Guzzle 3

repository·master·Indexed 41 days ago

https://github.com/guzzle/guzzle3

A PHP HTTP client and web service framework providing a simple interface for powerful HTTP operations. Guzzle 3 supports parallel requests, persistent connections, connection pooling, and includes a service description DSL and a Symfony2 event-based plugin system.

Tokens
61.6K
Snippets
188
Records
237
Agent score
98%

What's inside Guzzle

  1. Key features of Guzzle 3

    master

    Guzzle 3 provides a powerful interface for HTTP operations with the following capabilities:

    • cURL-like Power: A simple interface that provides the full power of cURL.
    • HTTP/1.1 Optimization: Supports persistent connections, connection pooling, and parallel requests.
    • Service Description DSL: A Domain Specific Language for building web service clients rapidly.
    • Plugin System: Uses a Symfony2 event-based system to allow complete modification of request behavior.
  2. How ServiceBuilder works to manage web service clients

    master

    A ServiceBuilder is a tool used to instantiate Guzzle web service clients based on centralized configuration. Instead of manually calling factory() methods on individual client classes, you use a ServiceBuilder to manage credentials, share configuration across multiple clients, and decouple your application from concrete client classes.

    Key benefits include:

    • Configuration Sharing: Use an "abstract" service to define common parameters (like API keys) and have other services extends it to inherit those parameters.
    • Environment Management: Easily switch between development and production clients by defining them in the builder configuration.
    • Dependency Injection: You can reference one service inside the parameters of another by enclosing the service name in curly braces (e.g., "{service_name}"). The builder will automatically instantiate the dependency first and inject it.
    • Singleton-like Behavior: The ServiceBuilder acts as a multiton; it instantiates a client only once and returns the same instance for subsequent requests for that same service name.
    use Guzzle\
    use Guzzle\Service\Builder\ServiceBuilder;
    
    // Define a hierarchy where 'foo' inherits from 'abstract_client'
    $builder = ServiceBuilder::factory(array(
        'services' => array(
            'abstract_client' => array(
                'params' => array(
                    'key'    => 'abc',
                    'secret' => '123'
                )
            ),
            'foo' => array(
                'extends' => 'abstract_client',
                'class'   => 'MyService\\FooClient',
                'params'  => array(
                    'custom' => 'and above all'
                )
            )
        )
    ));
    
    $foo = $builder->get('foo');
  3. How Guzzle plugins and events work

    master
    Guzzle uses a signal-slot event system powered by the Symfony2 Event Dispatcher component to allow plugins to add behavior to requests. When you attach an event listener or a subscriber to a Guzzle\Http\Client object, that listener or subscriber is automatically applied to every request created by that client.
  4. Handle request and response bodies with EntityBody

    master

    In Guzzle, HTTP message bodies are treated as PHP streams via the Guzzle\Http\EntityBody class. You can create an EntityBody from a string or a PHP stream using the EntityBody::factory() method.

    To protect against memory exhaustion, Guzzle uses temporary PHP streams. If the data exceeds 2MB, it is automatically stored on disk instead of in memory. This allows Guzzle to stream data during uploads and downloads without loading the entire body into a string.

    You can specify a request body in Client::put() or Client::post() methods, or by calling setBody() on any object implementing Guzzle\Http\Message\EntityEnclosingRequestInterface.

    use Guzzle\
    Http\
    EntityBody;
    
    // Create an EntityBody from a file stream
    $body = EntityBody::factory(fopen('/path/to/file.txt', 'r+'));
    
    // Send a request using the body
    $response = $client->put('http://localhost:8080/uploads', null, $body)->send();
  5. How Commands work in Guzzle

    master

    A Command is an abstraction that hides the underlying API implementation. It provides a parameter-driven object for specific API actions. A command is responsible for:

    1. Accepting an array of configuration parameters.
    2. Serializing those parameters into an HTTP request.
    3. Parsing the resulting HTTP response into a usable result.

    Commands follow the Command pattern, offering flexibility when implementing web service clients. You can create them via getCommand() to customize them before execution, or use magic methods on the client to create and execute them immediately.

    // Create a command without executing it immediately
    $command = $twitter->getCommand('getMentions', array('count' => 5));
    $command['trim_user'] = false;
    $result = $command->execute();
    
    // Or use magic methods for immediate execution
    $result = $twitter->getMentions(array('count' => 5));
  6. Define service operations

    master

    Operations represent the actions available on a service. Each operation has a unique name, an HTTP method, and a URI.

    Key attributes for an operation include:

    • httpMethod: The HTTP verb (e.g., GET, POST, PUT, DELETE, PATCH).
    • uri: The endpoint URI, which can use URI templates (e.g., /users/{id}). Variables in the template become parameters with location: "uri".
    • responseClass: Defines what getResult() returns. Can be primitive, a class name (must implement Guzzle\Service\Command\ResponseClassInterface), or a model name.
    • responseType: The type of response (primitive, class, model, or documentation). Defaults to primitive if not specified.
    • errorResponses: An array of objects defining potential errors. Each object can contain code (HTTP status), reason (description), and class (the exception class to raise).
    • additionalParameters: A catch-all rule for parameters not explicitly defined. This is useful for APIs with many similar parameters (e.g., Twitter's query string parameters).
    • parameters: An object defining specific input data for the request.
    {
        "operations": {
            "operationName": {
                "extends": "string",
                "httpMethod": "GET|POST|PUT|DELETE|PATCH|string",
                "uri": "string",
                "summary": "string",
                "class": "string",
                "responseClass": "string",
                "responseNotes": "string",
                "type": "string",
                "description": "string",
                "responseType": "primitive|class|(model by name)|documentation|(string)",
                "deprecated": false,
                "errorResponses": [
                    {
                        "code": 500,
                        "reason": "Unexpected Error",
                        "class": "string"
                    }
                ],
                "data": {
                    "foo": "bar",
                    "baz": "bam"
                },
                "parameters": {}
            }
        }
    }
  7. Working with Guzzle\Http\Message\Response objects

    master

    When you send a request in Guzzle, it returns a Guzzle\Http\Message\Response object.

    • Viewing raw response: You can cast the Response object to a string to see the raw HTTP response message. Note that this also casts the entity body to a string, which can be expensive for large files or network streams.
    • Viewing headers only: To see only the response headers without triggering a body download, use getRawHeaders().
    • Status Line: You can retrieve the protocol, version, status code, and reason phrase using specific methods.
    $response = $client->get('http://www.amazon.com')->send();
    
    echo $response->getStatusCode();      // e.g., 200
    echo $response->getReasonPhrase();    // e.g., OK
    echo $response->getProtocol();        // e.g., HTTP
    echo $response->getProtocolVersion(); // e.g., 1.1
  8. How the Guzzle HTTP client components work together

    master

    The Guzzle HTTP client is built on top of PHP libcurl bindings and consists of three primary components that work in a lifecycle:

    1. Clients (Guzzle\Http\Client): Responsible for creating and sending requests, and associating a response with a request.
    2. Requests (Guzzle\Http\Message\Request or Guzzle\Http\Message\EntityEnclosingRequest): Represents the HTTP request. Use Request for requests without a body and EntityEnclosingRequest for those with a body.
    3. Responses (Guzzle\Http\Message\Response): The object returned after a request is successfully sent.

    To perform an HTTP operation, you typically create a client, use a client method to generate a request, and then call send() on that request to receive a response.

    use Guzzle\Http\Client;
    
    $client = new Client('https://api.github.com');
    $request = $client->get('/user');
    $response = $request->send();
  9. Performance considerations for MD5 validation

    master
    Calculating MD5 hashes for large entity bodies or bodies transferred with Content-Encoding can be an expensive operation. In high-performance applications, you may want to configure the Guzzle\Plugin\Md5\Md5ValidatorPlugin to skip validation for bodies exceeding a specific size or for content-encoded bodies to avoid performance bottlenecks.
  10. How Guzzle batching works

    master

    The Guzzle\Batch\Batch object acts as a queue. You add items to the queue and then call flush() to transfer them.

    To manage the transfer, the batch object uses two components:

    1. Divisor (Guzzle\Batch\BatchDivisorInterface): Responsible for dividing the queue into manageable chunks.
    2. Transfer Strategy (Guzzle\Batch\BatchTransferInterface): Responsible for sending the chunks.

    In many cases, a single class (like Guzzle\Http\BatchRequestTransfer) can act as both the divisor and the transfer strategy.

    use Guzzle\Batch\Batch;
    use Guzzle\Http\BatchRequestTransfer;
    
    // BatchRequestTransfer acts as both the divisor and transfer strategy
    $transferStrategy = new BatchRequestTransfer(10);
    $divisorStrategy = $transferStrategy;
    
    $batch = new Batch($transferStrategy, $divisorStrategy);
    
    // Add items to the queue
    $batch->add($request1)
        ->add($request2)
        ->add($request3);
    
    // Flush the queue and retrieve the transferred items
    $arrayOfTransferredRequests = $batch->flush();
  11. How the Guzzle plugin system works

    master

    Guzzle's request and response workflow is driven by an event system powered by the Symfony2 Event Dispatcher component.

    Any object that emits events implements the Guzzle\Common\HasEventDispatcher interface. You can interact with the event system in two ways:

    1. Add Subscribers: Use the addSubscriber() method to attach an object that implements subscriber logic.
    2. Direct Dispatcher Access: Use getEventDispatcher() to retrieve the underlying Symfony\Component\EventDispatcher\EventDispatcher object, allowing you to add individual listeners or subscribers manually.

    Plugins are implemented as event subscribers, which allows for reusable logic that is easier to test than anonymous functions.

  12. Use request.options in Guzzle 3.7

    master

    Guzzle 3.7 introduces request.options as a parameter for client configuration and as an optional argument to all creational request methods. This allows you to specify default settings for various aspects of a request.

    When using AbstractCommand, replace deprecated keys like command.headers, command.response_body, and command.on_complete with the command.request_options key.

    // Old way (deprecated):
    $command = $client->getCommand('foo', array(
        'command.headers' => array('Test' => '123'),
        'command.response_body' => '/path/to/file'
    ));
    
    // New way:
    $command = $client->getCommand('foo', array(
        'command.request_options' => array(
            'headers' => array('Test' => '123'),
            'save_as' => '/path/to/file'
        )
    ));