Всем привет! Иногда в проекте на Symfony удобно задать один единственный заголовок по-умолчанию чтобы везде где требуется вызвать HttpClient не нужно было бы каждый раз прописывать заголовок.
Делается это достаточно просто. Например часто нужно прикинутся браузером в своем скрипте, для этого достаточно задать верный заголовок User-Agent и никто не догадается, что запрос пришел не от браузера, а от вашего скрипта на PHP
Я представлю несколько вариантов.
Статичный вариант представляет из себя возможность добавить заголовок в настройки Symfony для
Добавляем в config/packages/framework.yaml следующий код:
User-Agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
framework:
http_client:
default_options:
headers:
User-Agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
framework:
http_client:
default_options:
headers:
User-Agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
Таким образом где бы вы не вызвали в коде http client в Symfony в запросе будет передаваться заголовок User-Agent c данными из настройки
Можно сделать вариант поинтереснее, можно создать прослойку для http клиента проекта и внутри устанавливать заголовки запроса динамически выбирая из списка заголовки разных браузеров. Вот как это сделать:
use Symfony\Contracts\HttpClient\ResponseInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
class RandomUserAgentMiddleware implements HttpClientInterface
private HttpClientInterface $httpClient;
private array $userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7; rv:118.0) Gecko/20100101 Firefox/118.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.67',
'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 OPR/97.0.0.0'
public function __construct(HttpClientInterface $httpClient)
$this->httpClient = $httpClient;
public function request(string $method, string $url, array $options = []): ResponseInterface
$options['headers']['User-Agent'] = $this->userAgents[array_rand($this->userAgents)];
return $this->httpClient->request($method, $url, $options);
// Прокси для всех остальных методов
public function stream($responses, float $timeout = null): ResponseStreamInterface
return $this->httpClient->stream($responses, $timeout);
public function withOptions(array $options): static
$new->httpClient = $this->httpClient->withOptions($options);
<?php
namespace App\Service;
use Symfony\Contracts\HttpClient\ResponseInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
class RandomUserAgentMiddleware implements HttpClientInterface
{
private HttpClientInterface $httpClient;
private array $userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7; rv:118.0) Gecko/20100101 Firefox/118.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.67',
'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 OPR/97.0.0.0'
];
public function __construct(HttpClientInterface $httpClient)
{
$this->httpClient = $httpClient;
}
public function request(string $method, string $url, array $options = []): ResponseInterface
{
$options['headers']['User-Agent'] = $this->userAgents[array_rand($this->userAgents)];
return $this->httpClient->request($method, $url, $options);
}
// Прокси для всех остальных методов
public function stream($responses, float $timeout = null): ResponseStreamInterface
{
return $this->httpClient->stream($responses, $timeout);
}
public function withOptions(array $options): static
{
$new = clone $this;
$new->httpClient = $this->httpClient->withOptions($options);
return $new;
}
}
<?php
namespace App\Service;
use Symfony\Contracts\HttpClient\ResponseInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
class RandomUserAgentMiddleware implements HttpClientInterface
{
private HttpClientInterface $httpClient;
private array $userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7; rv:118.0) Gecko/20100101 Firefox/118.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.67',
'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 OPR/97.0.0.0'
];
public function __construct(HttpClientInterface $httpClient)
{
$this->httpClient = $httpClient;
}
public function request(string $method, string $url, array $options = []): ResponseInterface
{
$options['headers']['User-Agent'] = $this->userAgents[array_rand($this->userAgents)];
return $this->httpClient->request($method, $url, $options);
}
// Прокси для всех остальных методов
public function stream($responses, float $timeout = null): ResponseStreamInterface
{
return $this->httpClient->stream($responses, $timeout);
}
public function withOptions(array $options): static
{
$new = clone $this;
$new->httpClient = $this->httpClient->withOptions($options);
return $new;
}
}
И прописываем для прослойки декоратор http_client в services.yaml
App\Service\RandomUserAgentMiddleware:
services:
App\Service\RandomUserAgentMiddleware:
decorates: 'http_client'
services:
App\Service\RandomUserAgentMiddleware:
decorates: 'http_client'
Вызываем в коде проекта как обычно
public function __construct(
protected HttpClientInterface $client,
private readonly string $url
public function getData(): void
// Вот тут уже будет запрос с заголовком User-Agent реального браузера
$response = $this->client->request('GET', $this->url);
$data = $response->getContent();
class MySuperClass
{
public function __construct(
protected HttpClientInterface $client,
private readonly string $url
)
{
}
public function getData(): void
{
// Вот тут уже будет запрос с заголовком User-Agent реального браузера
$response = $this->client->request('GET', $this->url);
$data = $response->getContent();
// ...
}
}
class MySuperClass
{
public function __construct(
protected HttpClientInterface $client,
private readonly string $url
)
{
}
public function getData(): void
{
// Вот тут уже будет запрос с заголовком User-Agent реального браузера
$response = $this->client->request('GET', $this->url);
$data = $response->getContent();
// ...
}
}