Skip to main content
Version: 4.x

Single requests

The following examples assume that the content of /path/to/target/script.php looks like this:

<?php declare(strict_types=1);

sleep((int)($_REQUEST['sleep'] ?? 0));
echo $_REQUEST['key'] ?? '';

Send request synchronously​

<?php declare(strict_types=1);

namespace YourVendor\YourProject;

use hollodotme\FastCGI\Client;
use hollodotme\FastCGI\RequestContents\UrlEncodedFormData;
use hollodotme\FastCGI\Requests\PostRequest;
use hollodotme\FastCGI\SocketConnections\NetworkSocket;

$client = new Client();
$connection = new NetworkSocket('127.0.0.1', 9000);
$content = new UrlEncodedFormData(['key' => 'value']);
$request = new PostRequest('/path/to/target/script.php', $content);

$response = $client->sendRequest($connection, $request);

echo $response->getBody();
# prints
value

See it in action​

sendRequest() blocks your script until PHP-FPM has run the script and the response has arrived. Press play, step through, or change the runtime of the script:

1/6Create the client, a connection to PHP-FPM and a request for script.php.

Your PHP scriptusing the FastCGI Clientpreparing the requestPHP-FPMworker #1idlescript.php · sleep(2)
0.0 s
  • your script works
  • your script waits (blocked)
  • on the way over the socket
  • the script runs in PHP-FPM
Try it: change the example
sync.php
$client = new Client();
$connection = new NetworkSocket('127.0.0.1', 9000);
$request = new PostRequest(
'/path/to/target/script.php',
new UrlEncodedFormData(['key' => 'value', 'sleep' => 2])
);

$response = $client->sendRequest($connection, $request);

echo $response->getBody();
$ php sync.php

Send request asynchronously (Fire and forget)​

<?php declare(strict_types=1);

namespace YourVendor\YourProject;

use hollodotme\FastCGI\Client;
use hollodotme\FastCGI\RequestContents\UrlEncodedFormData;
use hollodotme\FastCGI\Requests\PostRequest;
use hollodotme\FastCGI\SocketConnections\NetworkSocket;

$client = new Client();
$connection = new NetworkSocket('127.0.0.1', 9000);
$content = new UrlEncodedFormData(['key' => 'value']);
$request = new PostRequest('/path/to/target/script.php', $content);

$socketId = $client->sendAsyncRequest($connection, $request);

echo "Request sent, got ID: {$socketId}";

Read the response, after sending the async request​

<?php declare(strict_types=1);

namespace YourVendor\YourProject;

use hollodotme\FastCGI\Client;
use hollodotme\FastCGI\RequestContents\UrlEncodedFormData;
use hollodotme\FastCGI\Requests\PostRequest;
use hollodotme\FastCGI\SocketConnections\NetworkSocket;

$client = new Client();
$connection = new NetworkSocket('127.0.0.1', 9000);
$content = new UrlEncodedFormData(['key' => 'value']);
$request = new PostRequest('/path/to/target/script.php', $content);

$socketId = $client->sendAsyncRequest($connection, $request);

echo "Request sent, got ID: {$socketId}";

# Do something else here in the meanwhile

# Blocking call until response is received or read timed out
$response = $client->readResponse(
$socketId, # The socket ID
3000 # Optional timeout to wait for response,
# defaults to read/write timeout in milliseconds set in connection
);

echo $response->getBody();
# prints
value

See it in action​

With sendAsyncRequest() your script can do other work while PHP-FPM runs the script. readResponse() only waits, if the response is not there yet. Change the runtimes to see both cases:

1/6Create the client, a connection to PHP-FPM and a request for script.php.

Your PHP scriptusing the FastCGI Clientpreparing the requestPHP-FPMworker #1idlescript.php · sleep(2)
0.0 s
  • your script works
  • your script waits (blocked)
  • on the way over the socket
  • the script runs in PHP-FPM
Try it: change the example
async.php
$client = new Client();
$connection = new NetworkSocket('127.0.0.1', 9000);
$request = new PostRequest(
'/path/to/target/script.php',
new UrlEncodedFormData(['key' => 'value', 'sleep' => 2])
);

$socketId = $client->sendAsyncRequest($connection, $request);
echo "Request sent, got ID: {$socketId}\n";

doSomethingElse(); # takes 1 s

$response = $client->readResponse($socketId);

echo $response->getBody();
$ php async.php

Notify a callback when async request responded​

You can register response and failure callbacks for each request. In order to notify the callbacks when a response was received instead of returning it, you need to use the waitForResponse(int $socketId, ?int $timeoutMs = null) method.

<?php declare(strict_types=1);

namespace YourVendor\YourProject;

use hollodotme\FastCGI\Client;
use hollodotme\FastCGI\RequestContents\UrlEncodedFormData;
use hollodotme\FastCGI\Requests\PostRequest;
use hollodotme\FastCGI\Interfaces\ProvidesResponseData;
use hollodotme\FastCGI\SocketConnections\NetworkSocket;
use Throwable;

$client = new Client();
$connection = new NetworkSocket('127.0.0.1', 9000);
$content = new UrlEncodedFormData(['key' => 'value']);
$request = new PostRequest('/path/to/target/script.php', $content);

# Register a response callback, expects a `ProvidesResponseData` instance as the only parameter
$request->addResponseCallbacks(
static function( ProvidesResponseData $response )
{
echo $response->getBody();
}
);

# Register a failure callback, expects a `\Throwable` instance as the only parameter
$request->addFailureCallbacks(
static function ( Throwable $throwable )
{
echo $throwable->getMessage();
}
);

$socketId = $client->sendAsyncRequest($connection, $request);

echo "Request sent, got ID: {$socketId}";

# Do something else here in the meanwhile

# Blocking call until response is received or read timed out
# If response was received all registered response callbacks will be notified
# If no response was received within the timeout, all registered failure callbacks
# will be notified with a TimedoutException
$client->waitForResponse(
$socketId, # The socket ID
3000 # Optional timeout to wait for response,
# defaults to read/write timeout in milliseconds set in connection
);

# ... is the same as, apart from the timeout while waiting for the response

while(true)
{
if ($client->hasResponse($socketId))
{
$client->handleResponse($socketId, 3000);
break;
}
}
# prints
value

Retry sending a request​

The client keeps its sockets open and reuses them for subsequent requests to the same connection. Sockets that were closed in the meantime, e.g. because their php-fpm child process was terminated, are detected and replaced by new ones before a request is sent.

If writing a request to a socket still fails, sendRequest() and sendAsyncRequest() throw a WriteFailedException. If you want the client to send the request again on another socket instead, use the following methods:

<?php declare(strict_types=1);

namespace YourVendor\YourProject;

use hollodotme\FastCGI\Client;
use hollodotme\FastCGI\Requests\PostRequest;
use hollodotme\FastCGI\RequestContents\UrlEncodedFormData;
use hollodotme\FastCGI\SocketConnections\NetworkSocket;

$client = new Client();
$connection = new NetworkSocket('127.0.0.1', 9000);
$content = new UrlEncodedFormData(['key' => 'value']);
$request = new PostRequest('/path/to/target/script.php', $content);

# Same as sendRequest(), but tries to send the request up to 5 times (default)
$response = $client->tryRequest($connection, $request);

# Same as sendAsyncRequest(), but tries to send the request up to 3 times
$socketId = $client->tryAsyncRequest($connection, $request, 3);

Please note:

  • Each try uses another socket, because a socket is discarded when writing to it failed.
  • If the last try fails too, its WriteFailedException is thrown.
  • The maximum number of tries must be at least 1, otherwise an InvalidArgumentException is thrown.
  • Only sending the request is retried. If reading the response fails, the request is not sent again, because it may already have been processed by the target script.

See it in action​

The client reuses idle sockets and replaces sockets that PHP-FPM closed. Compare what happens when writing a request fails with sendRequest() and with tryRequest():

1/7There is no socket yet, so tryRequest() opens a new one for the first request.

Your PHP scriptusing the FastCGI Clientpreparing the requestPHP-FPMworker #1idlescript.php · sleep(0.5)worker #2idlescript.php · sleep(0.5)worker #3idlescript.php · sleep(0.5)
0.0 s
  • your script works
  • your script waits (blocked)
  • on the way over the socket
  • the script runs in PHP-FPM
  • failure
Try it: change the example
Send with
reuse.php
$client = new Client();
$connection = new NetworkSocket('127.0.0.1', 9000);

foreach ([1, 2, 3, 4] as $key)
{
$request = new PostRequest(
'/path/to/target/script.php',
new UrlEncodedFormData(['key' => $key])
);
$response = $client->tryRequest($connection, $request);

echo $response->getBody() . "\n";

doSomethingElse();
}
$ php reuse.php