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 script works
- your script waits (blocked)
- on the way over the socket
- the script runs in PHP-FPM
$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();
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 script works
- your script waits (blocked)
- on the way over the socket
- the script runs in PHP-FPM
$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();
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
WriteFailedExceptionis thrown. - The maximum number of tries must be at least 1, otherwise an
InvalidArgumentExceptionis 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 script works
- your script waits (blocked)
- on the way over the socket
- the script runs in PHP-FPM
- failure
$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();
}