1 Отредактировано Vdomah (2013-04-13 03:27:03)

Тема: [РЕШЕНО]Распарсить JSON в экшене

Здравствуйте,
Задача состоит в том, чтобы получить запрос с удаленного сервера в формате JSON распарсить его, провести манипуляции с данными и отдать свой JSON с результатом обратно.

Как в симфони 1.2 отдать JSON вроде нашел:

public function executeIndex(sfWebRequest $request)
{
 $this->getResponse()->setContentType('application/json');
 $data_array=array("name" => "harry", "mobile" => "9876543210");
 $data_json=json_encode($data_array);
 return $this->renderText($data_json); 
}

А как правильно получить не могу найти. Читая док-цию: http://www.symfony-project.org/api/1_2/sfWebRequest попробовал getPostParameter() , который вроде должен вернуть массив ПОСТ, но результата я не получил. Но это пальцем в небо, более подходящего варианта не нашел.

public function executeIndex(sfWebRequest $request)
  {
    if ($request->isMethod('post'))
    {
        $err_id = 0; $msg = 'Success';
        $this->params = $request->getPostParameter();
//        $this->decoded = json_decode($this->params);

        $obj = json_decode($this->params[0]);
        $this->name = $obj->name;

Здесь вроде бы то что нужно, но для Сифони2: (http://stackoverflow.com/questions/9522 … -symfony-2)

public function yourAction()
{
    $params = array();
    $content = $this->get("request")->getContent();
    if (!empty($content))
    {
        $params = json_decode($content, true); // 2nd param to get as array
    }
}

2

Re: [РЕШЕНО]Распарсить JSON в экшене

Vdomah пишет:

попробовал getPostParameter() , который вроде должен вернуть массив ПОСТ, но результата я не получил.

Я без понятия, как вы читаете документацию, но по вашей ссылке (да и вообще по логике, название метода недвусмысленно указывает на то, что он возвращает значение конкретного параметра в POST запросе) читаем английским по белому:

string getPostParameter($name, $default = null)
Returns the value of a POST parameter.

Вообще, вызов этого метода без указания названия параметра должен был бы вызывать ошибку, которая также должна была натолкнуть на мысль, что что-то тут не так.

При этом сразу под этим методом есть метод getPostParameters(), который, очевидно, как раз возвращает массив POST.

3 Отредактировано Vdomah (2013-04-13 00:44:07)

Re: [РЕШЕНО]Распарсить JSON в экшене

Да getPostParameter() приносит NULL, но getPostParameters() пустой массив.
Может проблема в самом запросе:

  public function executeQuery(sfWebRequest $request)
  {
    $json_string = '{"name":"admin", "pass":"admpass"}';
    $socket = fsockopen($_SERVER['HTTP_HOST'], 80, $errno, $errstr, 30);
        
        if(!$socket)die("$errstr($errno)");

        fwrite($socket, "POST /token/index HTTP/1.1\r\n");

        fwrite($socket, "Host: " . $_SERVER['HTTP_HOST'] . "\r\n");
        fwrite($socket,"Content-type: applicaion/json; charset=utf-8\r\n");
        fwrite($socket,"Content-length:".strlen($json_string)."\r\n");

        fwrite($socket,"Connection:Close\r\n");
        fwrite($socket,"\r\n");
        
        fwrite($socket,"$json_string\r\n");
        fwrite($socket,"\r\n");
        
        fclose($socket);
        
  }

Хотя с другого сервера тоже не получается словить запрос.

И если подставить в $this-params из executeIndex (переменная, которую декодирую json_decode) строку '{"name":"admin", "pass":"admpass"}'; то метод возвращает успех, т.е. сама логика нормальная. Или запрос плохой, или распарсивается неправильно.

$this-params = '{"name":"admin", "pass":"admpass"}';
        $obj = json_decode($this->params);

4 Отредактировано Vdomah (2013-04-13 01:23:56)

Re: [РЕШЕНО]Распарсить JSON в экшене

Дошло до меня, что в этом случае не нужно делать decode, а так:

$params = $request->getPostParameters();
$name = $params['name']

Но проблема не решилась, т.к. $params пока еще пуст.

5

Re: [РЕШЕНО]Распарсить JSON в экшене

Vdomah пишет:

Но проблема не решилась, т.к. $params пока еще пуст.

Ну, вы же не думаете, что отправленный постом json сам собой чудом должен преобразоваться в массив? Причем не просто в массив, а почему-то в массив пост-параметров.
Метод getPostParameters() делает именно то, что отражает его название - отдает все пришедшие постом параметры.
Но у вас в запросе никаких параметров нет, у вас просто тело json.
Лезть в версию 1.2 чтобы посмотреть там, как и чего происходит, у меня ни времени, ни малейшего желания.
Можете попробовать запросить что-то вроде $request->getParameter('content');, вполне возможно Симфони уже тогда была достаточно умной и умела получать контент запроса.

Ну и это... простенькой отладкой и чтением исходного кода sfRequest вы бы наверняка ответили на свой вопрос минут за 10.

6

Re: [РЕШЕНО]Распарсить JSON в экшене

Спасибо за наводку!! У Симфони 1.2 в классе sfRequest отсутствует свойство $content. Получается тело запроса никак не вытянуть.

Решил, скопировав sfRequest.class.php из версии 1.3, где свойство $content уже есть. На удивление getContent() сработал!