-
Notifications
You must be signed in to change notification settings - Fork 3
bucefal91/php-async
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
PHP asynchronous execution framework
------------------------------------
This framework allows you to execute asynchronously arbitrary shell command from
PHP process. It features the following functionality:
* open file descriptors for communication between the PHP process and the child
one. Right now we support reading child's STDOUT and STDERR.
* ability to query whether the child process has finished its execution
* query PID of the child process, possibly for sending signals to it
* read exit code of the child process once it has finished its execution
* pre-inclined for easy caching of the child process results
------------------
Examples of usage:
------------------
Most simple asynchronous execution:
-----------------------------------
<?php
$command = 'my-command';
$args = array();
$args[] = array(
'key' => '--name-of-the-argument',
'glue' => ' ',
'value' => 'value of the argument',
);
$child = new ToolsAsyncResult($cmd, $args);
// Your 'my-command --name-of-the-argument "value of the argument"' is being
// executed right now. In the mean time you can do something useful in your main
// PHP process.
do_something_useful();
// When you decide you need the results of asynchronous child process, simply do
// the following. If the command has not finished yet, your main PHP process
// will sleep until the execution is finished.
$result = $child->result();
if ($result['exit'] != 0) {
// Whoups... The child process did not terminate with exit code 0.
// Let's see, maybe there is more hints about what went wrong in the STDERR.
$stderr = $result['stderr'];
}
// Now let's save the STDOUT from the child process somewhere.
$stdout = $result['stdout'];
?>
Run the asynchronous command and query whether it has finished:
---------------------------------------------------------------
<?php
$command = 'my-command';
$args = array();
$args[] = array(
'key' => '--name-of-the-argument',
'glue' => ' ',
'value' => 'value of the argument',
);
$child = new ToolsAsyncResult($cmd, $args);
// While the child process is running, and as we do not want to sleep in the
// main PHP process waiting for the results, let's keep doing something useful.
while ($child->isRunning()) {
do_something_useful();
}
// Now we fetched the child process results without actually sleeping a second
// in the main PHP process.
$result = $child->result();
?>
Additional file descriptors passed to your asynchronous command:
----------------------------------------------------------------
<?php
$command = 'my-awesome-command';
$args = array();
// Sometimes your command will communicate on more file descriptors than just
// STDOUT & STDERR. So you can provide additional file descriptors to your child
// command, be it a pipe or an actual file.
// See http://php.net/manual/en/function.proc-open.php for full list of
// available options.
$extra_descriptors = array(
4 => array('pipe', 'w'),
);
$result = new ToolsAsyncResult($cmd, $args, NULL, array(), $extra_descriptors)->result();
// Let's see what our child command has communicated on the 4th file descriptor.
$fd4 = $result['streams'][4];
?>
Example of synchronous caching:
-------------------------------
<?php
/**
* This function simply encapsulate starting a child process asynchronously.
*
* But let's put a bit on top of it. Before we take off to create a child
* process, let's check if the results of $cmd are not available in cache. If
* they are available, we return them right away without bothering with the
* whole thing of asynchronous command.
* Also, when the asynchronous command finishes execution, we take a note of its
* result and if it's positive (exit code equals 0) we store it in the cache
* bin. That way we guarantee asynchronous command will be only initiated for
* commands that have not been run before.
*/
function do_something_asynchronously($cmd) {
$cache = cache_bin_get($cmd);
if ($cache) {
// ToolsResult class has identical methods as the ToolsAsyncResult does,
// but this one does not execute any asynchronous command, but simply stores
// the $cache result until it is requested at some later point. That way we
// can freely swap between ToolsResult and ToolsAsyncResult classes without
// modifying the rest of our code.
return new ToolsResult($cache);
}
return new ToolsAsyncResult($cmd, array(), 'my_process_callback', array($cmd));
}
/**
* This function plays on par with do_something_asynchronously().
*
* When the child process has finished its execution, its results will be passed
* into this process function before being returned to whoever have requested
* them. We take the opportunity to store the results of asynchronous command
* execution into our cache bin so next time they can be fetched much faster
* from there.
*/
function my_process_callback($info, $cmd) {
if ($info['exit'] == 0) {
cache_bin_set($cmd, $info);
}
// We could also alter what gets returned to whoever requested the results of
// asynchronous command execution by just returning something else than $info.
// But let's keep this example simple.
return $info;
}
$result = do_something_asynchronously('my-command');
// This line takes to execute as long as the asynchronous command takes to
// execute.
$result->result();
// But if we repeat the same thing over again, our results are already cached
// and this time it happens instantaneously. All you have to do, is to implement
// some cache storage bin.
$result = do_something_asynchronously('my-command');
$result->result();
?>
-----------------
Issues/Questions?
-----------------
Do check the php-async.php file to see full options and features provided by the
framework.
About
Framework for asynchronous executing shell command in PHP.
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published