添加网站文件

This commit is contained in:
2025-12-22 13:59:40 +08:00
commit 117aaf83d1
19468 changed files with 2111999 additions and 0 deletions

19
vendor/guzzlehttp/command/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2015 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

134
vendor/guzzlehttp/command/README.md vendored Normal file
View File

@@ -0,0 +1,134 @@
# Guzzle Commands
[![License](https://poser.pugx.org/guzzlehttp/command/license)](https://packagist.org/packages/guzzlehttp/command)
[![Build Status](https://travis-ci.org/guzzle/command.svg?branch=master)](https://travis-ci.org/guzzle/command)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/guzzle/command/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/guzzle/command/?branch=master)
[![Code Coverage](https://scrutinizer-ci.com/g/guzzle/command/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/guzzle/command/?branch=master)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/7a93338e-50cd-42f7-9299-17c44d92148f/mini.png)](https://insight.sensiolabs.com/projects/7a93338e-50cd-42f7-9299-17c44d92148f)
[![Latest Stable Version](https://poser.pugx.org/guzzlehttp/command/v/stable)](https://packagist.org/packages/guzzlehttp/command)
[![Latest Unstable Version](https://poser.pugx.org/guzzlehttp/command/v/unstable)](https://packagist.org/packages/guzzlehttp/command)
[![Total Downloads](https://poser.pugx.org/guzzlehttp/command/downloads)](https://packagist.org/packages/guzzlehttp/command)
This library uses Guzzle (``guzzlehttp/guzzle``, version 6.x) and provides the
foundations to create fully-featured web service clients by abstracting Guzzle
HTTP **requests** and **responses** into higher-level **commands** and
**results**. A **middleware** system, analogous to — but separate from — the one
in the HTTP layer may be used to customize client behavior when preparing
commands into requests and processing responses into results.
### Commands
Key-value pair objects representing an operation of a web service. Commands have a name and a set of parameters.
### Results
Key-value pair objects representing the processed result of executing an operation of a web service.
## Installing
This project can be installed using Composer:
``composer require guzzlehttp/command``
For **Guzzle 5**, use ``composer require guzzlehttp/command:0.8.*``. The source
code for the Guzzle 5 version is available on the
`0.8 branch <https://github.com/guzzle/command/tree/0.8>`_.
**Note:** If Composer is not
`installed globally <https://getcomposer.org/doc/00-intro.md#globally>`_,
then you may need to run the preceding Composer commands using
``php composer.phar`` (where ``composer.phar`` is the path to your copy of
Composer), instead of just ``composer``.
## Service Clients
Service Clients are web service clients that implement the
``GuzzleHttp\Command\ServiceClientInterface`` and use an underlying Guzzle HTTP
client (``GuzzleHttp\Client``) to communicate with the service. Service clients
create and execute **commands** (``GuzzleHttp\Command\CommandInterface``),
which encapsulate operations within the web service, including the operation
name and parameters. This library provides a generic implementation of a service
client: the ``GuzzleHttp\Command\ServiceClient`` class.
## Instantiating a Service Client
@TODO Add documentation
* ``ServiceClient``'s constructor
* Transformer functions (``$commandToRequestTransformer`` and ``$responseToResultTransformer``)
* The ``HandlerStack``
## Executing Commands
Service clients create command objects using the ``getCommand()`` method.
```php
$commandName = 'foo';
$arguments = ['baz' => 'bar'];
$command = $client->getCommand($commandName, $arguments);
```
After creating a command, you may execute the command using the ``execute()``
method of the client.
```php
$result = $client->execute($command);
```
The result of executing a command will be a ``GuzzleHttp\Command\ResultInterface``
object. Result objects are ``ArrayAccess``-ible and contain the data parsed from
HTTP response.
Service clients have magic methods that act as shortcuts to executing commands
by name without having to create the ``Command`` object in a separate step
before executing it.
```php
$result = $client->foo(['baz' => 'bar']);
```
## Asynchronous Commands
@TODO Add documentation
* ``-Async`` suffix for client methods
* Promises
```php
// Create and execute an asynchronous command.
$command = $command = $client->getCommand('foo', ['baz' => 'bar']);
$promise = $client->executeAsync($command);
// Use asynchronous commands with magic methods.
$promise = $client->fooAsync(['baz' => 'bar']);
```
@TODO Add documentation
* ``wait()``-ing on promises.
```php
$result = $promise->wait();
echo $result['fizz']; //> 'buzz'
```
## Concurrent Requests
@TODO Add documentation
* ``executeAll()``
* ``executeAllAsync()``.
* Options (``fulfilled``, ``rejected``, ``concurrency``)
## Middleware: Extending the Client
Middleware can be added to the service client or underlying HTTP client to
implement additional behavior and customize the ``Command``-to-``Result`` and
``Request``-to-``Response`` lifecycles, respectively.
## Todo
* Middleware system and command vs request layers
* The ``HandlerStack``

36
vendor/guzzlehttp/command/composer.json vendored Normal file
View File

@@ -0,0 +1,36 @@
{
"name": "guzzlehttp/command",
"description": "Provides the foundation for building command-based web service clients",
"license": "MIT",
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Jeremy Lindblom",
"email": "jeremeamia@gmail.com",
"homepage": "https://github.com/jeremeamia"
}
],
"require": {
"php": ">=5.5.0",
"guzzlehttp/guzzle": "^6.2",
"guzzlehttp/promises": "~1.3",
"guzzlehttp/psr7": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0|~5.0"
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Command\\": "src/"
}
},
"extra": {
"branch-alias": {
"dev-master": "0.9-dev"
}
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace GuzzleHttp\Command;
use GuzzleHttp\HandlerStack;
/**
* Default command implementation.
*/
class Command implements CommandInterface
{
use HasDataTrait;
/** @var string */
private $name;
/** @var HandlerStack */
private $handlerStack;
/**
* @param string $name Name of the command
* @param array $args Arguments to pass to the command
* @param HandlerStack $handlerStack Stack of middleware for the command
*/
public function __construct(
$name,
array $args = [],
HandlerStack $handlerStack = null
) {
$this->name = $name;
$this->data = $args;
$this->handlerStack = $handlerStack;
}
public function getHandlerStack()
{
return $this->handlerStack;
}
public function getName()
{
return $this->name;
}
public function hasParam($name)
{
return array_key_exists($name, $this->data);
}
public function __clone()
{
if ($this->handlerStack) {
$this->handlerStack = clone $this->handlerStack;
}
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace GuzzleHttp\Command;
use GuzzleHttp\HandlerStack;
/**
* A command object encapsulates the input parameters used to control the
* creation of a HTTP request and processing of a HTTP response.
*
* Using the getParams() method will return the input parameters of the command
* as an associative array.
*/
interface CommandInterface extends \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInterface
{
/**
* Retrieves the handler stack specific to this command's execution.
*
* This can be used to add middleware that is specific to the command instance.
*
* @return HandlerStack
*/
public function getHandlerStack();
/**
* Get the name of the command.
*
* @return string
*/
public function getName();
/**
* Check if the command has a parameter by name.
*
* @param string $name Name of the parameter to check.
*
* @return bool
*/
public function hasParam($name);
}

View File

@@ -0,0 +1,7 @@
<?php
namespace GuzzleHttp\Command\Exception;
/**
* Exception encountered when a 4xx level response is received for a request
*/
class CommandClientException extends CommandException {}

View File

@@ -0,0 +1,109 @@
<?php
namespace GuzzleHttp\Command\Exception;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Command\CommandInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
/**
* Exception encountered while executing a command.
*/
class CommandException extends \RuntimeException implements GuzzleException
{
/** @var CommandInterface */
private $command;
/** @var RequestInterface */
private $request;
/** @var ResponseInterface */
private $response;
/**
* @param CommandInterface $command
* @param \Exception $prev
* @return CommandException
*/
public static function fromPrevious(CommandInterface $command, \Exception $prev)
{
// If the exception is already a command exception, return it.
if ($prev instanceof self && $command === $prev->getCommand()) {
return $prev;
}
// If the exception is a RequestException, get the Request and Response.
$request = $response = null;
if ($prev instanceof RequestException) {
$request = $prev->getRequest();
$response = $prev->getResponse();
}
// Throw a more specific exception for 4XX or 5XX responses.
$class = self::class;
$statusCode = $response ? $response->getStatusCode() : 0;
if ($statusCode >= 400 && $statusCode < 500) {
$class = CommandClientException::class;
} elseif ($statusCode >= 500 && $statusCode < 600) {
$class = CommandServerException::class;
}
// Prepare the message.
$message = 'There was an error executing the ' . $command->getName()
. ' command: ' . $prev->getMessage();
// Create the exception.
return new $class($message, $command, $prev, $request, $response);
}
/**
* @param string $message Exception message
* @param CommandInterface $command
* @param \Exception $previous Previous exception (if any)
* @param RequestInterface $request
* @param ResponseInterface $response
*/
public function __construct(
$message,
CommandInterface $command,
\Exception $previous = null,
RequestInterface $request = null,
ResponseInterface $response = null
) {
$this->command = $command;
$this->request = $request;
$this->response = $response;
parent::__construct($message, 0, $previous);
}
/**
* Gets the command that failed.
*
* @return CommandInterface
*/
public function getCommand()
{
return $this->command;
}
/**
* Gets the request that caused the exception
*
* @return RequestInterface|null
*/
public function getRequest()
{
return $this->request;
}
/**
* Gets the associated response
*
* @return ResponseInterface|null
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -0,0 +1,7 @@
<?php
namespace GuzzleHttp\Command\Exception;
/**
* Exception encountered when a 5xx level response is received for a request
*/
class CommandServerException extends CommandException {}

View File

@@ -0,0 +1,60 @@
<?php
namespace GuzzleHttp\Command;
/**
* Basic collection behavior for Command and Result objects.
*
* The methods in the class are primarily for implementing the ArrayAccess,
* Countable, and IteratorAggregate interfaces.
*/
trait HasDataTrait
{
/** @var array Data stored in the collection. */
protected $data;
public function __toString()
{
return print_r($this, true);
}
public function __debugInfo()
{
return $this->data;
}
public function offsetExists($offset)
{
return array_key_exists($offset, $this->data);
}
public function offsetGet($offset)
{
return isset($this->data[$offset]) ? $this->data[$offset] : null;
}
public function offsetSet($offset, $value)
{
$this->data[$offset] = $value;
}
public function offsetUnset($offset)
{
unset($this->data[$offset]);
}
public function count()
{
return count($this->data);
}
public function getIterator()
{
return new \ArrayIterator($this->data);
}
public function toArray()
{
return $this->data;
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace GuzzleHttp\Command;
/**
* Default command implementation.
*/
class Result implements ResultInterface
{
use HasDataTrait;
/**
* @param array $data
*/
public function __construct(array $data = [])
{
$this->data = $data;
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace GuzzleHttp\Command;
/**
* An array-like object that represents the result of executing a command.
*/
interface ResultInterface extends \ArrayAccess, \IteratorAggregate, \Countable, ToArrayInterface
{
}

View File

@@ -0,0 +1,217 @@
<?php
namespace GuzzleHttp\Command;
use GuzzleHttp\ClientInterface as HttpClient;
use GuzzleHttp\Command\Exception\CommandException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Promise;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
/**
* The Guzzle ServiceClient serves as the foundation for creating web service
* clients that interact with RPC-style APIs.
*/
class ServiceClient implements ServiceClientInterface
{
/** @var HttpClient HTTP client used to send requests */
private $httpClient;
/** @var HandlerStack */
private $handlerStack;
/** @var callable */
private $commandToRequestTransformer;
/** @var callable */
private $responseToResultTransformer;
/**
* Instantiates a Guzzle ServiceClient for making requests to a web service.
*
* @param HttpClient $httpClient A fully-configured Guzzle HTTP client that
* will be used to perform the underlying HTTP requests.
* @param callable $commandToRequestTransformer A callable that transforms
* a Command into a Request. The function should accept a
* `GuzzleHttp\Command\CommandInterface` object and return a
* `Psr\Http\Message\RequestInterface` object.
* @param callable $responseToResultTransformer A callable that transforms a
* Response into a Result. The function should accept a
* `Psr\Http\Message\ResponseInterface` object (and optionally a
* `Psr\Http\Message\RequestInterface` object) and return a
* `GuzzleHttp\Command\ResultInterface` object.
* @param HandlerStack $commandHandlerStack A Guzzle HandlerStack, which can
* be used to add command-level middleware to the service client.
*/
public function __construct(
HttpClient $httpClient,
callable $commandToRequestTransformer,
callable $responseToResultTransformer,
HandlerStack $commandHandlerStack = null
) {
$this->httpClient = $httpClient;
$this->commandToRequestTransformer = $commandToRequestTransformer;
$this->responseToResultTransformer = $responseToResultTransformer;
$this->handlerStack = $commandHandlerStack ?: new HandlerStack();
$this->handlerStack->setHandler($this->createCommandHandler());
}
public function getHttpClient()
{
return $this->httpClient;
}
public function getHandlerStack()
{
return $this->handlerStack;
}
public function getCommand($name, array $params = [])
{
return new Command($name, $params, clone $this->handlerStack);
}
public function execute(CommandInterface $command)
{
return $this->executeAsync($command)->wait();
}
public function executeAsync(CommandInterface $command)
{
$stack = $command->getHandlerStack() ?: $this->handlerStack;
$handler = $stack->resolve();
return $handler($command);
}
public function executeAll($commands, array $options = [])
{
// Modify provided callbacks to track results.
$results = [];
$options['fulfilled'] = function ($v, $k) use (&$results, $options) {
if (isset($options['fulfilled'])) {
$options['fulfilled']($v, $k);
}
$results[$k] = $v;
};
$options['rejected'] = function ($v, $k) use (&$results, $options) {
if (isset($options['rejected'])) {
$options['rejected']($v, $k);
}
$results[$k] = $v;
};
// Execute multiple commands synchronously, then sort and return the results.
return $this->executeAllAsync($commands, $options)
->then(function () use (&$results) {
ksort($results);
return $results;
})
->wait();
}
public function executeAllAsync($commands, array $options = [])
{
// Apply default concurrency.
if (!isset($options['concurrency'])) {
$options['concurrency'] = 25;
}
// Convert the iterator of commands to a generator of promises.
$commands = Promise\iter_for($commands);
$promises = function () use ($commands) {
foreach ($commands as $key => $command) {
if (!$command instanceof CommandInterface) {
throw new \InvalidArgumentException('The iterator must '
. 'yield instances of ' . CommandInterface::class);
}
yield $key => $this->executeAsync($command);
}
};
// Execute the commands using a pool.
return (new Promise\EachPromise($promises(), $options))->promise();
}
/**
* Creates and executes a command for an operation by name.
*
* @param string $name Name of the command to execute.
* @param array $args Arguments to pass to the getCommand method.
*
* @return ResultInterface|PromiseInterface
* @see \GuzzleHttp\Command\ServiceClientInterface::getCommand
*/
public function __call($name, array $args)
{
$args = isset($args[0]) ? $args[0] : [];
if (substr($name, -5) === 'Async') {
$command = $this->getCommand(substr($name, 0, -5), $args);
return $this->executeAsync($command);
} else {
return $this->execute($this->getCommand($name, $args));
}
}
/**
* Defines the main handler for commands that uses the HTTP client.
*
* @return callable
*/
private function createCommandHandler()
{
return function (CommandInterface $command) {
return Promise\coroutine(function () use ($command) {
// Prepare the HTTP options.
$opts = $command['@http'] ?: [];
unset($command['@http']);
try {
// Prepare the request from the command and send it.
$request = $this->transformCommandToRequest($command);
$promise = $this->httpClient->sendAsync($request, $opts);
// Create a result from the response.
$response = (yield $promise);
yield $this->transformResponseToResult($response, $request, $command);
} catch (\Exception $e) {
throw CommandException::fromPrevious($command, $e);
}
});
};
}
/**
* Transforms a Command object into a Request object.
*
* @param CommandInterface $command
* @return RequestInterface
*/
private function transformCommandToRequest(CommandInterface $command)
{
$transform = $this->commandToRequestTransformer;
return $transform($command);
}
/**
* Transforms a Response object, also using data from the Request object,
* into a Result object.
*
* @param ResponseInterface $response
* @param RequestInterface $request
* @param CommandInterface $command
* @return ResultInterface
*/
private function transformResponseToResult(
ResponseInterface $response,
RequestInterface $request,
CommandInterface $command
) {
$transform = $this->responseToResultTransformer;
return $transform($response, $request, $command);
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace GuzzleHttp\Command;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Command\Exception\CommandException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Promise\PromiseInterface;
/**
* Web service client interface.
*/
interface ServiceClientInterface
{
/**
* Create a command for an operation name.
*
* Special keys may be set on the command to control how it behaves.
* Implementations SHOULD be able to utilize the following keys or throw
* an exception if unable.
*
* @param string $name Name of the operation to use in the command
* @param array $args Arguments to pass to the command
*
* @return CommandInterface
* @throws \InvalidArgumentException if no command can be found by name
*/
public function getCommand($name, array $args = []);
/**
* Execute a single command.
*
* @param CommandInterface $command Command to execute
*
* @return ResultInterface The result of the executed command
* @throws CommandException
*/
public function execute(CommandInterface $command);
/**
* Execute a single command asynchronously
*
* @param CommandInterface $command Command to execute
*
* @return PromiseInterface A Promise that resolves to a Result.
*/
public function executeAsync(CommandInterface $command);
/**
* Executes multiple commands concurrently using a fixed pool size.
*
* @param array|\Iterator $commands Array or iterator that contains
* CommandInterface objects to execute with the client.
* @param array $options Associative array of options to apply.
* - concurrency: (int) Max number of commands to execute concurrently.
* - fulfilled: (callable) Function to invoke when a command completes.
* - rejected: (callable) Function to invoke when a command fails.
*
* @return array
* @see GuzzleHttp\Command\ServiceClientInterface::createPool for options.
*/
public function executeAll($commands, array $options = []);
/**
* Executes multiple commands concurrently and asynchronously using a
* fixed pool size.
*
* @param array|\Iterator $commands Array or iterator that contains
* CommandInterface objects to execute with the client.
* @param array $options Associative array of options to apply.
* - concurrency: (int) Max number of commands to execute concurrently.
* - fulfilled: (callable) Function to invoke when a command completes.
* - rejected: (callable) Function to invoke when a command fails.
*
* @return PromiseInterface
* @see GuzzleHttp\Command\ServiceClientInterface::createPool for options.
*/
public function executeAllAsync($commands, array $options = []);
/**
* Get the HTTP client used to send requests for the web service client
*
* @return ClientInterface
*/
public function getHttpClient();
/**
* Get the HandlerStack which can be used to add middleware to the client.
*
* @return HandlerStack
*/
public function getHandlerStack();
}

View File

@@ -0,0 +1,16 @@
<?php
namespace GuzzleHttp\Command;
/**
* An object that can be represented as an array
*/
interface ToArrayInterface
{
/**
* Get the array representation of an object
*
* @return array
*/
public function toArray();
}