添加网站文件

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

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();
}