W celu wysłania żądania HTTP konieczne jest zainicjowanie obiektu yii\httpclient\Client i użycie jego metody createRequest()
.
Następnie należy skonfigurować wszystkie parametry tego żądania według własnych potrzeb i tak przygotowane wysłać.
W rezultacie otrzymujemy obiekt yii\httpclient\Response, który przechowuje wszystkie informacje odpowiedzi.
Przykładowo:
use yii\httpclient\Client;
$client = new Client();
$response = $client->createRequest()
->setMethod('POST')
->setUrl('http://example.com/api/1.0/users')
->setData(['name' => 'John Doe', 'email' => 'johndoe@example.com'])
->send();
if ($response->isOk) {
$newUserId = $response->data['id'];
}
Aby uprościć przygotowywanie żądania, można użyć skrótowych metod get()
, post()
, put()
, itd.
W przypadku korzystania z pojedynczej instancji yii\httpclient\Client dla wielu żądań skierowanych do tej samej domeny
(np. łącząc się z REST API), można ustawić tę domenę jako wartość właściwości baseUrl
. Pozwala to na określanie jedynie
relatywnych adresów URL podczas tworzenia żądania.
Dzięki temu kilka następujących po sobie żądań skierowanych do jakiegoś REST API może wyglądać jak poniżej:
use yii\httpclient\Client;
$client = new Client(['baseUrl' => 'http://example.com/api/1.0']);
$newUserResponse = $client->post('users', ['name' => 'John Doe', 'email' => 'johndoe@example.com'])->send();
$articleResponse = $client->get('articles', ['name' => 'Yii 2.0'])->send();
$client->post('subscriptions', ['user_id' => $newUserResponse->data['id'], 'article_id' => $articleResponse->data['id']])->send();
Dane żądania HTTP są domyślnie przesyłane w formacie 'form-urlencoded', np. param1=value1¶m2=value2
.
Jest on powszechnie wykorzystywany w formularzach web, ale już nie dla REST API, które zwykle wymaga treści w formacie
JSON lub XML. Format żądania można ustawić za pomocą właściwości format
lub metody setFormat()
.
Wspierane są następujące formaty:
Przykładowo:
use yii\httpclient\Client;
$client = new Client(['baseUrl' => 'http://example.com/api/1.0']);
$response = $client->createRequest()
->setFormat(Client::FORMAT_JSON)
->setUrl('articles/search')
->setData([
'query_string' => 'Yii',
'filter' => [
'date' => ['>' => '2015-08-01']
],
])
->send();
Obiekt odpowiedzi automatycznie rozpoznaje jej format, opierając się na nagłówku 'Content-Type' i samej treści, zatem
w większości przypadków nie jest wymagane określanie tego formatu, wystarczy przetworzyć ją używając metody getData()
lub właściwości data
. Rozwijając powyższy przykład, można otrzymać dane odpowiedzi następująco:
$responseData = $response->getData(); // pobierz wszystkie artykuły
count($response->data) // policz artykuły
$article = $response->data[0] // pobierz pierwszy artykuł
Korzystanie z wbudowanych formaterów nie jest obowiązkowe. Można skonfigurować żądanie HTTP, aby przekazywało niesformatowaną treść i jednocześnie można przetwarzać niesformatowaną treść uzyskaną w odpowiedzi. Dla przykładu:
use yii\httpclient\Client;
$client = new Client(['baseUrl' => 'http://example.com/api/1.0']);
$response = $client->createRequest()
->setUrl('articles/search')
->addHeaders(['content-type' => 'application/json'])
->setContent('{query_string: "Yii"}')
->send();
echo 'Search results:<br>';
echo $response->content;
yii\httpclient\Request formatuje przekazywane data
, tylko jeśli content
nie jest ustawiony.
yii\httpclient\Response przetwarza content
, tylko jeśli data
jest wywołane.
Używając pojedynczej instancji yii\httpclient\Client dla kilku podobnych żądań, przykładowo pracując z REST API,
można uprościć i przyspieszyć pisanie kodu, dodając własną konfigurację dla obiektów żądania i odpowiedzi. Można to
zrobić korzystając z pól requestConfig
i responseConfig
w yii\httpclient\Client.
Przykładowo, aby ustawić format JSON dla wszystkich żądań klienta:
use yii\httpclient\Client;
$client = new Client([
'baseUrl' => 'http://example.com/api/1.0',
'requestConfig' => [
'format' => Client::FORMAT_JSON
],
'responseConfig' => [
'format' => Client::FORMAT_JSON
],
]);
$request = $client->createRequest();
echo $request->format; // zwraca: 'json'
Tip: można nawet określić własne klasy dla obiektów żądania i odpowiedzi, aby uzyskać dodatkowe funkcjonalności - w tym celu należy użyć klucza 'class' w tablicy konfiguracyjnej.
Można zdefiniować nagłówki żądania za pomocą metod setHeaders()
i addHeaders()
.
Metoda getHeaders()
lub właściwość headers
służy do pobrania już zdefiniowanych nagłówków w postaci instancji klasy
\yii\web\HeaderCollection. Przykładowo:
use yii\httpclient\Client;
$client = new Client(['baseUrl' => 'http://example.com/api/1.0']);
$request = $client->createRequest()
->setHeaders(['content-type' => 'application/json'])
->addHeaders(['user-agent' => 'My User Agent']);
$request->getHeaders()->add('accept-language', 'en-US;en');
$request->headers->set('user-agent', 'User agent override');
Kiedy obiekt odpowiedzi jest już gotowy, można pobrać wszystkie nagłówki odpowiedzi za pomocą metody getHeaders()
lub
właściwości headers
:
$response = $request->send();
echo $response->getHeaders()->get('content-type');
echo $response->headers->get('content-encoding');
Pomimo tego, że ciasteczka są przesyłane wyłącznie w nagłówkach, yii\httpclient\Request i yii\httpclient\Request dostarczają oddzielny interfejs dla pracy z nimi, używając \yii\web\Cookie i \yii\web\CookieCollection.
Można zdefiniować ciasteczka żądania używając metod setCookies()
lub addCookies()
.
Metoda getCookies()
lub właściwość cookies
służy do pobrania już zdefiniowanych ciasteczek w postaci instancji klasy
\yii\web\CookieCollection. Przykładowo:
use yii\httpclient\Client;
use yii\web\Cookie;
$client = new Client(['baseUrl' => 'http://example.com/api/1.0']);
$request = $client->createRequest()
->setCookies([
['name' => 'country', 'value' => 'USA'],
new Cookie(['name' => 'language', 'value' => 'en-US']),
])
->addCookies([
['name' => 'view_mode', 'value' => 'full']
]);
$request->cookies->add(['name' => 'display-notification', 'value' => '0']);
Kiedy obiekt odpowiedzi jest już gotowy, można pobrać wszystkie ciasteczka odpowiedzi za pomocą metody getCookies()
lub
właściwości cookies
:
$response = $request->send();
echo $response->getCookies()->get('country');
echo $response->headers->get('PHPSESSID');
Można przekazać ciasteczka pomiędzy obiektem odpowiedzi i żądania po prostu je kopiując. Przykładowo, musimy edytować profil użytkownika w aplikacji web, dostępnej jedynie po zalogowaniu - konieczne jest zatem zalogowanie się i następnie użycie nowoutworzonej sesji dla uwierzytelnienia dalszej aktywności:
use yii\httpclient\Client;
$client = new Client(['baseUrl' => 'http://example.com']);
$loginResponse = $client->post('login', [
'username' => 'johndoe',
'password' => 'somepassword',
])->send();
// $loginResponse->cookies->get('PHPSESSID') - przechowuje ID nowej sesji
$client->post('account/profile', ['birthDate' => '10/11/1982'])
->setCookies($loginResponse->cookies) // przekazuje ciasteczka odpowiedzi do żądania
->send();