1. Go to this page and download the library: Download jerome/matrix library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
try {
$result = await(timeout(
async(function () {
sleep(5); // Long operation
return 'Done';
}),
2.0, // 2 second timeout
'The operation took too long'
));
} catch (\Matrix\Exceptions\TimeoutException $e) {
echo $e->getMessage(); // "The operation took too long"
echo "Duration: " . $e->getDuration() . " seconds"; // "Duration: 2 seconds"
}
use React\Http\Browser;
$browser = new Browser();
try {
$result = await(retry(
function () use ($browser) {
// Non-blocking HTTP request with potential for failure
return $browser->get('https://unreliable-api.com/data')
->then(function ($response) {
if ($response->getStatusCode() !== 200) {
throw new \RuntimeException('API returned ' . $response->getStatusCode());
}
return $response->getBody()->getContents();
});
},
5, // Try up to 5 times
function ($attempt, $error) {
// Exponential backoff with jitter
$delay = min(pow(2, $attempt - 1) * 0.1, 5.0) * (0.8 + 0.4 * mt_rand() / mt_getrandmax());
echo "Attempt $attempt failed: {$error->getMessage()}, retrying in {$delay}s...\n";
return $delay; // Return null to stop retrying
}
));
echo "Finally succeeded: $result\n";
} catch (\Matrix\Exceptions\RetryException $e) {
echo "All {$e->getAttempts()} attempts failed\n";
foreach ($e->getFailures() as $index => $failure) {
echo "Failure " . ($index + 1) . ": " . $failure->getMessage() . "\n";
}
}
// Start a long operation
$operation = async(function () {
// Simulate long computation
for ($i = 0; $i < 10; $i++) {
// Check for cancellation at safe points
if (/* cancelled check */) {
throw new \RuntimeException('Operation cancelled');
}
sleep(1);
}
return 'Completed';
});
// Create a clean-up function for when the operation is cancelled
$cleanup = function () {
echo "Cleaning up resources...\n";
// Release any held resources
};
// Create a cancellable promise
$cancellable = cancellable($operation, $cleanup);
// Later, when you need to cancel the operation
$cancellable->cancel();
// Check if it was cancelled
if ($cancellable->isCancelled()) {
echo "Operation was cancelled.\n";
}
try {
await(withErrorContext(
async(function () {
throw new \RuntimeException('Database connection failed');
}),
'While initializing user service'
));
} catch (\Matrix\Exceptions\AsyncException $e) {
// Outputs: "While initializing user service: Database connection failed"
echo $e->getMessage() . "\n";
// Original exception is preserved as the previous exception
echo "Original error: " . $e->getPrevious()->getMessage() . "\n";
}
$result = await(delay(2.0, 'Delayed result'));
echo $result; // Outputs: Delayed result (after 2 seconds)
// Can be used in promise chains
async(fn () => 'Step 1')
->then(function ($result) {
echo "$result\n";
return delay(1.0, $result . ' -> Step 2');
})
->then(function ($result) {
echo "$result\n";
});
use React\Http\Browser;
$browser = new Browser();
// Create a function that's limited to 2 calls per second
$limitedFetch = rateLimit(
function ($url) use ($browser) {
// Non-blocking HTTP request
return $browser->get($url);
},
2, // Maximum 2 calls
1.0 // Per 1 second
);
// Make multiple calls
$urls = [
'https://example.com/api/1',
'https://example.com/api/2',
'https://example.com/api/3',
'https://example.com/api/4',
'https://example.com/api/5',
];
// These will automatically be rate-limited
foreach ($urls as $url) {
$limitedFetch($url)->then(function ($response) use ($url) {
echo "Fetched $url: HTTP " . $response->getStatusCode() . "\n";
});
}
// Wait for all to complete
await(delay(10)); // Give time for requests to complete
public function test_error_context_enhancement(): void
{
try {
await(withErrorContext(
async(fn () => throw new \RuntimeException('Original error')),
'Error context'
));
$this->fail('Should have thrown an exception');
} catch (AsyncException $e) {
$this->assertStringContainsString('Error context', $e->getMessage());
$this->assertInstanceOf(\RuntimeException::class, $e->getPrevious());
}
}
public function test_rate_limiting(): void
{
$startTime = microtime(true);
$results = [];
$limitedFn = rateLimit(
function ($i) use (&$results) {
return async(function () use ($i, &$results) {
$results[] = $i;
return $i;
});
},
2, // Max 2 calls
0.5 // Per 0.5 seconds
);
$promises = [];
for ($i = 1; $i <= 5; $i++) {
$promises[] = $limitedFn($i);
}
await(all($promises));
$duration = microtime(true) - $startTime;
$this->assertGreaterThanOrEqual(1.0, $duration);
$this->assertEquals([1, 2, 3, 4, 5], $results);
}
// DON'T - This blocks the entire event loop
$result = await(async(function () {
return file_get_contents('https://api.example.com'); // Blocking!
}));
// DO - Use ReactPHP's non-blocking HTTP client
use React\Http\Browser;
$browser = new Browser();
$result = await($browser->get('https://api.example.com'));
// DO - Break into smaller chunks or use separate processes
$result = await(async(function () {
// Process in smaller batches with yields to event loop
$sum = 0;
for ($i = 1; $i <= 10000000; $i += 1000) {
$sum += array_sum(range($i, min($i + 999, 10000000)));
if ($i % 10000 === 0) {
// Yield control back to event loop periodically
await(delay(0.001));
}
}
return $sum;
}));
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.