当前位置: 首页 > 工具软件 > Guzzle > 使用案例 >

guzzle-swoole_Guzzle-PHP HTTP客户端

孙嘉悦
2023-12-01

guzzle-swoole

As you probably know, website development can be broken up into 2 main areas:

您可能知道,网站开发可以分为两个主要领域:

  • Front end (what the end user sees)

    前端(最终用户看到的内容)
  • Back end (what the server has to do in order to provide the requested data)

    后端(服务器必须执行的操作才能提供请求的数据)

While front end development frequently uses several data sources to display a page, simple dynamic sites would only depend on data coming from a database hosted on the same server. As back end developers today, we are in need of retrieving data from a database server on a different host, or consuming an API from a third-party provider, while making it look like everything happened in our server.

尽管前端开发经常使用多个数据源来显示页面,但是简单的动态站点仅取决于来自同一服务器上托管的数据库的数据。 作为当今的后端开发人员,我们需要从不同主机上的数据库服务器中检索数据,或者使用第三方提供商的API,同时使数据看起来像发生在我们服务器中。

PHP comes with the native cURL client (if enabled), that can be frightening to the newcomer or hard to use to consume SOAP services. Other frameworks implement their versions of HTTP, REST, and SOAP clients to some degree. However, if you do not wish to use cURL, you do not have a framework or you are not a fan of your framework's solution, Guzzle to the rescue.

PHP带有本机cURL客户端(如果已启用),它可能会使新手感到恐惧或难以使用它来使用SOAP服务。 其他框架在某种程度上实现了HTTP,REST和SOAP客户端的版本。 但是,如果您不希望使用cURL,则说明您没有框架,或者您不喜欢框架的解决方案,请耐心等待

Guzzle is an independent HTTP client for PHP. Installing Guzzle is very easy: you'll need to get composer first (https://www.sitepoint.com/php-dependency-management-with-composer/). Once you got composer installed and ready, create your basic composer.json file, which would look like the following:

Guzzle是PHP的独立HTTP客户端。 安装Guzzle非常容易:您需要先获得作曲家( https://www.sitepoint.com/php-dependency-management-with-composer/ )。 安装并准备好composer之后,创建基本的composer.json文件,如下所示:

{
        "name": "jd/guzzle demo",
        "authors": [
            {
                "name": "John Doe",
                "email": "john@doe.tst"
            }
        ],
        "require": {

        }
    }

Now just add the guzzle library to the composer.json file in the require section as follows:

现在,将guzzle库添加到require部分中的composer.json文件中,如下所示:

{
        "name": "jd/guzzle demo",
        "authors": [
            {
                "name": "John Doe",
                "email": "john@doe.tst"
            }
        ],
        "require": {
            "guzzle/guzzle": "~3.7"
        }
    }

Having saved the file, you just need to run the composer install command and you should be good to go!

保存文件后,您只需要运行composer install命令,就可以了!

基本 (Basics)

As a cryptography enthusiast, searching for sources of entropy data for key generation is a hobby of mine. One good source is the ANU Quantum Random Numbers Server at https://qrng.anu.edu.au. Supposedly their RNG is based on quantum physics, so it is worth taking a look at when generating random data with a good entropy level.

作为密码学爱好者,搜索用于生成密钥的熵数据源是我的爱好。 一个很好的来源是位于https://qrng.anu.edu.au的ANU Quantum随机数服务器。 假设他们的RNG基于量子物理学,因此在生成具有良好熵级别的随机数据时值得一看。

Fortunately they have a public API we can consume, so here is where Guzzle will come in handy:

幸运的是,它们有一个可供我们使用的公共API,因此在这里Guzzle会派上用场:

<?php
    chdir(dirname(__DIR__));

    require_once 'vendor/autoload.php';

    use Guzzle\Http\Client;
    use Guzzle\Http\EntityBody;
    use Guzzle\Http\Message\Request;
    use Guzzle\Http\Message\Response;

    /** @var $client Client */
    $client = new Client("https://qrng.anu.edu.au");

The first two lines should be familiar to anyone using composer and its autoloading mechanisms. When we instantiate a Client object, we should pass as a constructor parameter the URL we want to connect to. Please notice that it does not use path and/or URL parameters – this will come in a minute.

使用composer及其自动加载机制的任何人都应该熟悉前两行。 实例化Client对象时,应将要连接的URL作为构造函数参数传递。 请注意,它不使用路径和/或URL参数-这将在一分钟内出现。

/** @var $request Request */
    $request = $client->get('/API/jsonI.php?length=10&type=uint8');

    /** @var $response Response */
    $response = $request->send();

    /** @var $body EntityBody */
    $body = $response->getBody(true);

We finally indicate the path (/API/jsonI.php) and the URL parameters (length=10&type=uint8) to the client, building an HTTP GET request via the $client->get() method. If we wanted to build a POST request, the client object has post() and many other HTTP request methods. For sending the request, the $request->send() method should be invoked, catching the response in the $response variable. Finally if we want to see what the response from the remote server was, we execute the $response->getBody() method. TRUE can be sent as a parameter to the getBody() method to get the result as a string.

最后,我们通过$client->get()方法建立一个HTTP GET请求,以指示指向客户端的路径( /API/jsonI.php )和URL参数( length=10&type=uint8 )。 如果我们要构建POST请求,则客户端对象具有post()和许多其他HTTP请求方法。 为了发送请求,应该调用$request->send()方法,并在$response变量中捕获$response 。 最后,如果我们想查看远程服务器的响应,则执行$response->getBody()方法。 可以将TRUE作为参数发送到getBody()方法,以获取字符串形式的结果。

路径和URL参数操作 (Path and URL Parameters Manipulation)

In the previous example, we used a string to indicate the path and URL parameters to build the request… This might not be the most elegant solution. We might decide to pass on certain URL parameters or use different paths according to certain conditions. We can easily accomplish proper handling of path and URL parameters by making some adjustments to the code.

在前面的示例中,我们使用了一个字符串来指示构建请求的路径和URL参数……这可能不是最优雅的解决方案。 我们可能决定根据某些条件传递某些URL参数或使用不同的路径。 通过对代码进行一些调整,我们可以轻松完成路径和URL参数的正确处理。

/** @var $request Request */
    $request = $client->createRequest();

    $request->setPath('/API/jsonI.php');

    $request->getQuery()
        ->set('length', 10)
        ->set('type', 'uint8');

First we create an empty request from the Guzzle client with the $client->getRequest() method. The request object has several methods; in this case we'll use the setPath() and getQuery() methods. setPath() should be pretty straightforward; as for getQuery, we use Guzzle's fluent interface to set the URL parameters one by one.

首先,我们使用$client->getRequest()方法从Guzzle客户端创建一个空请求。 请求对象有几种方法。 在这种情况下,我们将使用setPath()getQuery()方法。 setPath()应该非常简单; 至于getQuery ,我们使用Guzzle的流畅接口逐一设置URL参数。

记录中 (Logging)

When we develop applications that consume 3rd party services through a network, communication problems often arise, so it is very important to keep a log with all the requests and responses, at least during development stages so we can debug what is going on.

当我们开发通过网络使用第三方服务的应用程序时,经常会出现通信问题,因此保持所有请求和响应的日志非常重要,至少在开发阶段是如此,以便我们调试发生的事情。

Guzzle provides several plugins. In the case of logging plugins, we have several adapters available at our disposal. For this example we'll use monolog

Guzzle提供了几个插件。 对于日志记录插件,我们有几个可用的适配器。 在此示例中,我们将使用独白

To have monolog available in your project, you'll have to modify your composer.json file and run the composer update command. Your composer.json file should look like the following:

要在项目中使用独白,您必须修改composer.json文件并运行composer update命令。 您的composer.json文件应如下所示:

{
        "name": "jd/guzzle demo",
        "authors": [
            {
                "name": "John Doe",
                "email": "john@doe.tst"
            }
        ],
        "require": {
            "guzzle/guzzle": "~3.7",
            "monolog/monolog": "1.6.0"
        }
    }

To make Guzzle use monolog and write all requests and responses we send and receive, we need to make some adjustments to our code:

为了使Guzzle使用独白并编写我们发送和接收的所有请求和响应,我们需要对代码进行一些调整:

<?php

    chdir(dirname(__DIR__));

    require_once 'vendor/autoload.php';

    //...
    use Guzzle\Log\MessageFormatter;
    use Guzzle\Log\MonologLogAdapter;
    use Guzzle\Plugin\Log\LogPlugin;
    use Monolog\Handler\StreamHandler;
    use Monolog\Logger;

    $logger = new Logger('client');
    $logger->pushHandler(new StreamHandler('guzzle.log'));

    $logAdapter = new MonologLogAdapter($logger);

    $logPlugin = new LogPlugin($logAdapter, MessageFormatter::DEBUG_FORMAT);

    /** @var $client Client */
    $client = new Client("https://qrng.anu.edu.au");

    $client->addSubscriber($logPlugin);

First we create a monolog instance with $logger = new Logger('client');. Monolog posseses several handlers, in this case we will use the StreamHandler to write to a file named guzzle.log. Then we create guzzle's monolog adapter by instantiating a MonologLogAdapter object. Next we create a log plugin object using Guzzle's log plugin manager LogPlugin. Please notice the MessageFormatter::DEBUG_FORMAT constant which tells Guzzle to log full request and response messages. Please refer to Guzzle's docs to see which message formatters are available. Last, we add the log plugin to the guzzle client by calling $client->addSubscriber($logPlugin);

首先,我们使用$logger = new Logger('client');创建一个monolog实例$logger = new Logger('client'); 。 Monolog具有多个处理程序,在这种情况下,我们将使用StreamHandler写入名为guzzle.log的文件。 然后,我们通过实例化MonologLogAdapter对象来创建guzzle的monolog适配器。 接下来,我们使用Guzzle的日志插件管理器LogPlugin创建一个日志插件对象。 请注意MessageFormatter::DEBUG_FORMAT常量,该常量告诉Guzzle记录完整的请求和响应消息。 请参阅Guzzle的文档,以查看可用的消息格式器。 最后,我们通过调用$client->addSubscriber($logPlugin);将日志插件添加到$client->addSubscriber($logPlugin);

与Github的API交互 (Interacting with Github's API)

Let's have a look at this code and then I´ll explain it line by line

让我们看一下这段代码,然后我将逐行解释它

<?php
    chdir(dirname(__DIR__));

    require_once 'vendor/autoload.php';

    use Guzzle\http\Client;
    use Guzzle\Log\MonologLogAdapter;
    use Guzzle\Plugin\Log\LogPlugin;
    use Guzzle\Log\MessageFormatter;
    use Monolog\Logger;
    use Monolog\Handler\StreamHandler;

    $client = new Client('https://api.github.com');

    $log = new Logger('log');
    $log->pushHandler(new StreamHandler('requests.log'));

    $adapter = new MonologLogAdapter($log);

    $logPlugin = new LogPlugin($adapter, MessageFormatter::DEBUG_FORMAT);

    $client->addSubscriber($logPlugin);

    $request = $client->post('authorizations', array(), 
            json_encode(
                    array(
                            'scopes' => array(
                                    'public_repo',
                                    'user',
                                    'repo',
                                    'gist'
                            ),
                            'note' => 'auto client' . uniqid()
                    )));

    $request->setAuth('john@doe.tst', 'yourpasswordhere');

    $request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false);

    $response = $request->send();

    $body = json_decode($response->getBody(true));

    $oauthToken = $body->token;

    $request = $client->get('user/keys');

    $query = $request->getQuery();

    $query->add('access_token', $oauthToken);

    $request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false);

    try {

        $response = $request->send();

        $body = $response->getBody(true);

        echo $body;
    } catch (Exception $e) {
        echo $request->getResponse()->getRawHeaders();
    }

Detailed explanation follows.

详细说明如下。

$client = new Client('https://api.github.com');

We create a client which will use Github's API base URL.

我们创建一个客户端,该客户端将使用Github的API基本URL。

$log = new Logger('log');
    $log->pushHandler(new StreamHandler('requests.log'));

    $adapter = new MonologLogAdapter($log);    

    $logPlugin = new LogPlugin($adapter, MessageFormatter::DEBUG_FORMAT);

    $client->addSubscriber($logPlugin);

As we previously saw, we set up logging capabilities, so we are able to debug communication issues.

如我们先前所见,我们设置了日志记录功能,因此我们能够调试通信问题。

$request = $client->post('authorizations', array(), 
            json_encode(
                    array(
                            'scopes' => array(
                                    'public_repo',
                                    'user',
                                    'repo',
                                    'gist'
                            ),
                            'note' => 'auto client' . uniqid()
                    )));

First we want to request authorization to use Github's API (http://developer.github.com/v3/oauth/) without having to use our username and password every time, so we need to perform an HTTP POST verb to https://api.github.com/authorizations. Remember that we set up the base URL when we created our client, so we only need to set the path. To see a list of possible parameters that can be sent to Github's API, please refer to their documentation.

首先,我们要请求授权使用Github的API( http://developer.github.com/v3/oauth/ ),而不必每次都使用用户名和密码,因此我们需要对https://api.github.com/authorizations执行HTTP POST动词https://api.github.com/authorizations 。 请记住,我们在创建客户端时就设置了基本URL,因此我们只需要设置路径即可。 要查看可以发送到Github API的可能参数列表,请参阅其文档。

$request->setAuth('john@doe.tst', 'yourpasswordhere');

    $request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false);

For this one time, we will use HTTP Basic Authentication. Remember that the only mechanism preventing the sending of your credentials in plain text is HTTPS (as shown in the API url) – performing the request through something as insecure as HTTP could lead to someone intercepting your data. In the second line, we are configuring cURL not to verify the SSL certificate, as this can solve several communication issues.

这次,我们将使用HTTP基本身份验证。 请记住,阻止以纯文本形式发送凭据的唯一机制是HTTPS(如API URL中所示)–通过与HTTP一样不安全的方式执行请求可能会导致某人拦截您的数据。 在第二行中,我们将cURL配置为不验证SSL证书,因为这可以解决一些通信问题。

$response = $request->send();
    $body = json_decode($response->getBody(true));

Finally we send the request. The response is gotten through the getBody() method, the TRUE flag is used to configure Guzzle to return a plain string. Remember that Github's API is RESTful, so everything will be JSON encoded, and thus we will decode it to an object using json_decode().

最后,我们发送请求。 响应是通过getBody()方法获得的,TRUE标志用于将Guzzle配置为返回纯字符串。 请记住,Github的API是RESTful的,因此所有内容都将进行JSON编码,因此我们将使用json_decode()将其解码为一个对象。

$oauthToken = $body->token;

The Oauth token will be contained inside the 'token' attribute. Please refer to Github's API documentation for a detailed explanation of the response format.

Oauth令牌将包含在“令牌”属性内。 请参阅Github的API文档以获取有关响应格式的详细说明。

$request = $client->get('user/keys');
    $query = $request->getQuery();
    $query->add('access_token', $oauthToken);

We will be performing a new request. This time we want to list our authorized keys that are configured in our account, mostly for accessing our repositories through SSH. This time an HTTP GET request has to be sent, but instead of using our credentials in plain text, we will use the Oauth token we were given; this token has to be added as a query parameter to the URL we are requesting.

我们将执行一个新的请求。 这次,我们要列出在帐户中配置的授权密钥,主要用于通过SSH访问我们的存储库。 这次必须发送HTTP GET请求,但是我们将使用给定的Oauth令牌,而不是使用纯文本的凭据; 该令牌必须作为查询参数添加到我们请求的URL中。

$response = $request->send();    
    $body = $response->getBody(true);
    echo $body;

Finally we send the request and get the response body, ready to be parsed and used for whichever purpose you like.

最后,我们发送请求并获取响应主体,以准备进行解析并用于您喜欢的任何目的。

结论 (Conclusion)

This little demonstration is just the tip of the iceberg of what Guzzle is capable of. With a nicely structured plugin system, request and response handling mechanism, you can finally tame the wide quantity of API's the internet has to offer.

这个小小的演示只是Guzzle所能提供的冰山一角。 借助结构良好的插件系统,请求和响应处理机制,您最终可以驯服互联网必须提供的大量API。

If you have a specific use case of Guzzle you'd like to demonstrate or just some general feedback, let us know!

如果您想展示Guzzle的特定用例,或者只是一些一般性的反馈,请告诉我们!

翻译自: https://www.sitepoint.com/guzzle-php-http-client/

guzzle-swoole

 类似资料: