Symfony2 Guzzle хранит cookie для запроса

Попытка заставить мой контроллер Symfony2 сделать запрос к поддерживаемому API. Необходимо сохранить файл cookie, полученный при первом запросе API, чтобы использовать его во втором запросе.

Вот мой код контроллера:

use Guzzle\Http\Client;

use Guzzle\Plugin\Cookie\CookiePlugin;
use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;


class DefaultController extends Controller
{

   public function verifyurlActionOK(Request $request)
   {


   $cookiePlugin = new CookiePlugin(new ArrayCookieJar());

   $client = new Client();

   $this->get('session')->set('client', $client);

   $client->addSubscriber($cookiePlugin);
   $request = $client->get('https://address/scanit?url='.$scantarget);
   $response = $request->send();
   }

   public function progressAction(Request $request)
   {
   $cli = $session->get('client');

   $crequest = $cli->get('https://address/progress');
   $response = $crequest->send();


   return $this->render('AppBundle:Default:progress.html.twig',
                        array(
                        'response'  => $cresponse->getBody()));
   }


}

Пытался установить Client как общедоступную переменную в классе DefaultController и, как указано выше, в сеансе (сериализованном). Оба не работают, здесь появляется ошибка get() в progressAction

[2016-11-29 16:22:46] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Debug\Exception\FatalErrorException: "Error: Call to a member function get() on a non-object"

Как получить доступ к $client из verifyurlActionOK в progressAction??

Спасибо,


person dev    schedule 29.11.2016    source источник
comment
переменная $session не инициализирована в методе progressAction   -  person Matteo    schedule 30.11.2016


Ответы (2)


в методе progressAction вы пропускаете сеанс из контейнера. Попробуйте добавить строку $session = $this->get('session')

Например:

public function progressAction(Request $request)
   {
   $session = $this->get('session')
   $cli = $session->get('client');

Я предлагаю вам сохранить в сеансе объект CookieJar (он реализует сериализуемость и может храниться в сеансе) вместо экземпляра объекта Client. Например:

public function verifyurlActionOK(Request $request)
{

    $cookieJar = $this->get('session')->get('cookie-jar', new ArrayCookieJar());
    $cookiePlugin = new CookiePlugin($cookieJar);

    $client = new Client();

    $client->addSubscriber($cookiePlugin);
    $request = $client->get('https://address/scanit?url='.$scantarget);
    $response = $request->send();
    $this->get('session')->set('cookie-jar', $cookieJar);

}

public function progressAction(Request $request)
{
    $cookieJar = $this->get('session')->get('cookie-jar');
    $cookiePlugin = new CookiePlugin($cookieJar);

    $cli = new Client();

    $cli->addSubscriber($cookiePlugin);

    $crequest = $cli->get('https://address/progress');
    $response = $crequest->send();


    return $this->render('AppBundle:Default:progress.html.twig',
        array(
            'response'  => $cresponse->getBody()));
}

Надеюсь, это поможет

person jack    schedule 30.11.2016
comment
Спасибо!!! Пришлось перейти на последнюю версию Guzzle, старая почему-то не обрабатывала файлы cookie должным образом. Вот также хороший пример использования последней версии Guzzle с файлами cookie: docs.guzzlephp.org /en/latest/quickstart.html#cookies - person dev; 30.11.2016

Для этого лучше всего создать общую службу, содержащую экземпляр Client, и использовать ее в обоих действиях. Вместо того, чтобы хранить клиента в сеансе, вы можете хранить файлы cookie.

У Symfony есть хорошая документация по созданию сервисов: http://symfony.com/doc/current/service_container.html

person lsouza    schedule 29.11.2016
comment
БОЛЬШОЕ СПАСИБО!!! После долгой возни обновил Guzzle до последней версии (docs.guzzlephp.org/en /latest/quickstart.html#cookies) и использовали подход Джека. Мне также нравится ваш подход, я буду использовать его в будущем .... Хотел бы я выбрать два ответа как правильные - person dev; 30.11.2016