Symfony HttpClient教程展示了如何使用HttpClient组件在 Symfony 中创建 HTTP 请求。 该组件提供使用 API 的工具,并支持同步和异步操作。
有关更多信息,请阅读官方 HttpComponent 文档。
Symfony
Symfony 是一组可重用的 PHP 组件和一个用于 Web 项目的 PHP 框架。 Symfony 于 2005 年发布为免费软件。Symfony 的原始作者是 Fabien Potencier。 Symfony 受到 Spring 框架的极大启发。
在示例中,我们将使用httpbin.org和http://jsonplaceholder.typicode.com/在线服务。
$ composer require symfony/http-client$ composer require symfony/var-dumper
我们安装了HttpClient和var-dumper组件。
HttpClient GET 请求
HTTP 定义了一组请求方法,以指示要对给定资源执行的所需操作。 GET 请求用于从指定资源请求数据。 使用 GET 的请求应仅检索数据,而对数据没有其他影响。
注意:建议使用 HTTP 方法的目的和影响; 这些不是严格的规则。 这就是我们前面说过 GET 方法不应对数据产生影响的原因。 实际上,这并不总是遵循的。
get_request.php
<?phprequire('vendor/autoload.php');use Symfony\Component\HttpClient\HttpClient;$httpClient = HttpClient::create();$response = $httpClient->request('GET', 'http://webcode.me');$statusCode = $response->getStatusCode();echo $statusCode . "\n";$contentType = $response->getHeaders()['content-type'][0];echo $contentType . "\n";$content = $response->getContent();echo $content . "\n";
该示例创建HttpClient,并向指定的网页发出 GET 请求。
注意:响应始终是异步的,因此对方法的调用将立即返回,而不是等待接收响应。 有诸如
getStatusCode()和getContent()之类的阻塞方法,它们会等到接收到完整的响应内容为止。
$httpClient = HttpClient::create();$response = $httpClient->request('GET', 'http://webcode.me');
我们用HttpClient::create()创建一个HttpClient。 使用request()方法生成 GET 请求。
$statusCode = $response->getStatusCode();echo $statusCode . "\n";
我们使用getStatusCode()方法获取状态代码。
$contentType = $response->getHeaders()['content-type'][0];echo $contentType . "\n";
从响应的标题中,我们获得内容类型。
$content = $response->getContent();echo $content . "\n";
最后,我们使用getContent()方法获得页面的内容。
$ php get_request.php200text/html<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>My html page</title></head><body><p>Today is a beautiful day. We go swimming and fishing.</p><p>Hello there. How are you?</p></body></html>
这是输出。
HttpClient用户代理
创建HttpClient时,我们可以传递一些选项,例如标头值。
user_agent.php
<?phprequire('vendor/autoload.php');use Symfony\Component\HttpClient\HttpClient;$httpClient = HttpClient::create(['headers' => ['User-Agent' => 'PHP console app',]]);$response = $httpClient->request('GET', 'https://httpbin.org/user-agent');echo $response->getContent() . "\n";
我们连接到httpbin.org网站,该网站是用于测试 HTTP 请求&响应的在线工具。
$httpClient = HttpClient::create(['headers' => ['User-Agent' => 'PHP console app',]]);
在标题数组中,我们添加User-Agent选项。
$response = $httpClient->request('GET', 'https://httpbin.org/user-agent');
我们将 GET 请求发送到https://httpbin.org/user-agent URL,该 URL 返回请求的用户代理选项。
HttpClient toArray()
toArray()方法通常将响应主体解码为数组,并从 JSON 有效负载解码为数组。
content_array.php
<?phprequire('vendor/autoload.php');use Symfony\Component\HttpClient\HttpClient;$httpClient = HttpClient::create();$response = $httpClient->request('GET','https://jsonplaceholder.typicode.com/posts/2/');dump($response->toArray());
该示例向jsonplaceholder.typicode.com在线服务网站发出 GET 请求,该网站以 JSON 格式返回 ID 为 2 的帖子。
dump($response->toArray());
我们转储toArray()方法的输出。
$ php content_array.phparray:4 ["userId" => 1"id" => 2"title" => "qui est esse""body" => """est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"""]
这是输出。
HttpClient POST 数据
发布请求用于将数据发送到服务器。 数据位于 HTTP 请求的请求正文中。
发布请求永远不会被缓存,它们不会保留在浏览器历史记录中,也无法被添加书签,并且数据长度没有限制。
post_data.php
<?phprequire('vendor/autoload.php');use Symfony\Component\HttpClient\HttpClient;$httpClient = HttpClient::create();$response = $httpClient->request('POST', 'https://httpbin.org/post', ['body' => ['msg' => 'Hello there']]);echo $response->getContent();
在示例中,我们在 POST 请求中将消息变量发送到指定的 URL。 在响应对象中,我们找到了 POST 请求中发送的数据。
$ php post_data.php{"args": {},"data": "","files": {},"form": {"msg": "Hello there"},...}
这是输出。
HttpClient重定向
URL 重定向是将请求从一页转发到另一页的过程。 当 Web 浏览器尝试打开已重定向的 URL 时,将打开一个具有其他 URL 的页面。 一个 URL 可能有多个重定向。
使用重定向的原因:
- URL 缩短
- 防止在移动网页时断开链接
- 允许属于同一所有者的多个域名引用一个网站
- 隐私保护
- HTTP 到 HTTP 的过渡
- 恶意目的,例如网络钓鱼攻击或恶意软件分发
发出请求时,HttpClient遵循重定向,最多 20 个。 max_redirects属性用于配置此行为。 值 0 表示不遵循任何重定向。
redirect.php
<?phprequire 'vendor/autoload.php';use Symfony\Component\HttpClient\HttpClient;$httpClient = HttpClient::create();$response = $httpClient->request('GET', 'https://httpbin.org/redirect/4', ['max_redirects' => 3,]);echo $response->getStatusCode();
我们将 GET 请求发送到重定向四次的 URL,同时将max_redirects属性设置为三。 这意味着我们获得 302 重定向状态代码。 如果我们增加max_redirects值,我们应该得到 200。
HttpClient查询参数
查询参数是统一资源定位器(URL)的一部分,该 URL 将值分配给指定的参数。 这是将数据发送到目标服务器的一种方法。
http://example.com/api/users?name=John%20Doe&occupation=gardener
查询参数在?字符之后指定。&分隔了多个字段。 特殊字符(例如空格)被编码。 在上面的字符串中,空格用%20值编码。
Symfony HttpClient在将值包含在 URL 中之前会自动对其进行编码。
query_params.php
<?phprequire('vendor/autoload.php');use Symfony\Component\HttpClient\HttpClient;$httpClient = HttpClient::create();$response = $httpClient->request('GET', 'https://httpbin.org/get', ['query' => ['name' => 'John Doe',],]);echo $response->getContent();
我们将name字段发送到https://httpbin.org/get URL。 在响应中,我们返回了 URL 参数。
$ php query_params.php{"args": {"name": "John Doe"},"headers": {"Accept-Encoding": "deflate, gzip","Host": "httpbin.org","User-Agent": "Symfony HttpClient/Curl"},...}
这是输出。
使用 httpbin 的 Docker 容器
httpbin.org还提供了一个用于测试的 Docker 容器。
$ docker run -p 80:80 kennethreitz/httpbin
我们运行容器。
docker_ex.php
<?phprequire 'vendor/autoload.php';use Symfony\Component\HttpClient\HttpClient;$httpClient = HttpClient::create();$response = $httpClient->request('GET', 'http://localhost:80/anything',['json' => ['message' => 'Hello there'],]);dump($response->toArray());
在示例中,我们使用 httpbin 的服务连接到容器。 localhost:80/anything返回传递给请求的任何内容。
HTTP 基本认证
HTTP 基本认证是一种简单的质询和响应机制,其中服务器从客户端请求凭据。 客户端在授权标头中将凭据传递给服务器。 认证信息不以任何方式加密或哈希。 它使用 Base64 算法编码。 因此,仅将 HTTP 基本认证与HTTPS一起使用才被认为是安全的。
HTTP 基本认证使用 HTTP 标头中的标准字段,从而无需握手。
authenticate.php
<?phprequire('vendor/autoload.php');use Symfony\Component\HttpClient\HttpClient;$httpClient = HttpClient::create(['auth_basic' => ['user7', 'passwd']]);$response = $httpClient->request('GET','https://httpbin.org/basic-auth/user7/passwd');echo $response->getStatusCode();dump($response);
在示例中,我们使用 HTTP 基本认证。
$httpClient = HttpClient::create(['auth_basic' => ['user7', 'passwd']]);
HTTP 基本认证通过auth_basic选项指定。 所有请求将使用相同的凭据。
$response = $httpClient->request('GET','https://httpbin.org/basic-auth/user7/passwd');
不要与 URL 中的用户名和密码混淆; 这仅用于在 httpbin 的服务中进行测试。
HttpClient流数据
自 HTTP 1.1 以来,块传输编码是一种流数据传输机制。 在分块传输编码中,数据流被分为一系列不重叠的块。
块彼此独立地发送和接收。 每个块之前都有其大小(以字节为单位)。
在 Symfony HttpClient中,流传输是通过stream()完成的。
streaming.php
<?phprequire 'vendor/autoload.php';use Symfony\Component\HttpClient\HttpClient;$httpClient = HttpClient::create();$url = 'https://download.freebsd.org/ftp/releases/amd64/amd64/ISO-IMAGES/12.0/FreeBSD-12.0-RELEASE-amd64-mini-memstick.img';$response = $httpClient->request('GET', $url, ['buffer' => false,]);if (200 !== $response->getStatusCode()) {throw new \Exception('Failed to create a request');}$fileHandler = fopen('freebsd-12.0-amd64-mini-memstick.iso', 'w');foreach ($httpClient->stream($response) as $chunk) {fwrite($fileHandler, $chunk->getContent());}
在示例中,我们下载了 FreeBSD ISO 映像。
$response = $httpClient->request('GET', $url, ['buffer' => false,]);
我们创建一个对指定 URL 的 GET 请求; (可选)我们可以关闭内存缓冲。
$fileHandler = fopen('freebsd-12.0-amd64-mini-memstick.iso', 'w');foreach ($httpClient->stream($response) as $chunk) {fwrite($fileHandler, $chunk->getContent());}
我们以块的形式获取响应内容,并将其保存在文件中。
Symfony HttClient Webapp 示例
在下面的示例中,我们创建一个 Symfony Web 应用,该应用使用HttpClient生成请求。 我们使用HttpClientInterface注入HttpClient。
该应用向https://jsonplaceholder.typicode.com/users发出 GET 请求,该请求返回十个用户。
$ composer create-project symfony/skeleton symfapp$ cd symfapp$ composer require annotations$ composer require maker server --dev$ composer require symfony/http-client
我们创建一个新的 Symfony 框架应用并安装一些依赖项。
config/packages/framework.yaml
framework:...http_client:max_host_connections: 5default_options:max_redirects: 3
在framework.yaml文件中,我们可以配置HttpClient。
$ php bin/console make:controller DataController
我们创建一个新的控制器。
src/Controller/DataController.php
<?phpnamespace App\Controller;use App\Service\UserService;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Routing\Annotation\Route;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;class DataController extends AbstractController{/*** @Route("/data", name="data")*/public function index(UserService $userService): Response{$data = $userService->getUsers();return $this->json($data);}}
DataController注入UserService,调用其getUsers()方法以检索数据。 数据作为 JSON 返回给调用方。
src/Service/UserService.php
<?phpnamespace App\Service;use Symfony\Contracts\HttpClient\HttpClientInterface;class UserService{private $httpClient;public function __construct(HttpClientInterface $httpClient){$this->httpClient = $httpClient;}public function getUsers(): Array{$response = $this->httpClient->request('GET','https://jsonplaceholder.typicode.com/users');$data = $response->getContent();$decoded = json_decode($data);return $decoded;}}
这是UserService.
public function __construct(HttpClientInterface $httpClient){$this->httpClient = $httpClient;}
我们用HttpClientInterface注入 HttpClient。
public function getUsers(): Array{$response = $this->httpClient->request('GET','https://jsonplaceholder.typicode.com/users');$data = $response->getContent();$decoded = json_decode($data);return $decoded;}
我们生成一个 GET 请求,解码数据并返回它。
$ php bin/console server:run
我们运行该应用并导航到localhost:8000/data。
在本教程中,我们使用了 Symfony HttpClient组件。
您可能也对以下相关教程感兴趣: Symfony 简介, Symfony 验证教程, Symfony 服务教程, Symfony 表单教程 , PHP 教程或列出所有 Symfony 教程。
