Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify usage by supporting new default loop #87

Merged
merged 2 commits into from
Jul 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 27 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ as [Streams](https://github.com/reactphp/stream).
## Quickstart example

```php
$loop = React\EventLoop\Factory::create();

$process = new React\ChildProcess\Process('echo foo');
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -41,8 +39,6 @@ $process->stdout->on('data', function ($chunk) {
$process->on('exit', function($exitCode, $termSignal) {
echo 'Process exited with code ' . $exitCode . PHP_EOL;
});

$loop->run();
```

See also the [examples](examples).
Expand Down Expand Up @@ -80,7 +76,7 @@ you can use any of their events and methods as usual:

```php
$process = new Process($command);
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo $chunk;
Expand Down Expand Up @@ -113,7 +109,7 @@ The `Process` class allows you to pass any kind of command line string:

```php
$process = new Process('echo test');
$process->start($loop);
$process->start();
```

The command line string usually consists of a whitespace-separated list with
Expand All @@ -129,7 +125,7 @@ $bin = 'C:\\Program files (x86)\\PHP\\php.exe';
$file = 'C:\\Users\\me\\Desktop\\Application\\main.php';

$process = new Process(escapeshellarg($bin) . ' ' . escapeshellarg($file));
$process->start($loop);
$process->start();
```

By default, PHP will launch processes by wrapping the given command line string
Expand All @@ -146,7 +142,7 @@ streams from the wrapping shell command like this:

```php
$process = new Process('echo run && demo || echo failed');
$process->start($loop);
$process->start();
```

> Note that [Windows support](#windows-compatibility) is limited in that it
Expand All @@ -168,7 +164,7 @@ boundary between each sub-command like this:

```php
$process = new Process('cat first && echo --- && cat second');
$process->start($loop);
$process->start();
```

As an alternative, considering launching one process at a time and listening on
Expand All @@ -177,11 +173,11 @@ This will give you an opportunity to configure the subsequent process I/O stream

```php
$first = new Process('cat first');
$first->start($loop);
$first->start();

$first->on('exit', function () use ($loop) {
$first->on('exit', function () {
$second = new Process('cat second');
$second->start($loop);
$second->start();
});
```

Expand All @@ -191,7 +187,7 @@ also applies to running the most simple single command:

```php
$process = new Process('yes');
$process->start($loop);
$process->start();
```

This will actually spawn a command hierarchy similar to this on Unix:
Expand All @@ -212,7 +208,7 @@ wrapping shell process to be replaced by our process:

```php
$process = new Process('exec yes');
$process->start($loop);
$process->start();
```

This will show a resulting command hierarchy similar to this:
Expand Down Expand Up @@ -244,7 +240,7 @@ arguments:

```php
$process = new Process('sleep 10');
$process->start($loop);
$process->start();

$process->on('exit', function ($code, $term) {
if ($term === null) {
Expand Down Expand Up @@ -292,9 +288,9 @@ accordingly when terminating a process:

```php
$process = new Process('sleep 10');
$process->start($loop);
$process->start();

$loop->addTimer(2.0, function () use ($process) {
Loop::addTimer(2.0, function () use ($process) {
foreach ($process->pipes as $pipe) {
$pipe->close();
}
Expand All @@ -308,9 +304,9 @@ inherited process pipes as [mentioned above](#command).

```php
$process = new Process('exec sleep 10');
$process->start($loop);
$process->start();

$loop->addTimer(2.0, function () use ($process) {
Loop::addTimer(2.0, function () use ($process) {
$process->terminate();
});
```
Expand All @@ -321,9 +317,9 @@ For example, the following can be used to "soft-close" a `cat` process:

```php
$process = new Process('cat');
$process->start($loop);
$process->start();

$loop->addTimer(2.0, function () use ($process) {
Loop::addTimer(2.0, function () use ($process) {
$process->stdin->end();
});
```
Expand Down Expand Up @@ -366,7 +362,7 @@ $fds = array(
);

$process = new Process($cmd, null, null, $fds);
$process->start($loop);
$process->start();
```

Unless your use case has special requirements that demand otherwise, you're
Expand Down Expand Up @@ -429,7 +425,7 @@ instead throw a `LogicException` on Windows by default:
```php
// throws LogicException on Windows
$process = new Process('ping example.com');
$process->start($loop);
$process->start();
```

There are a number of alternatives and workarounds as detailed below if you want
Expand All @@ -449,7 +445,7 @@ to run a child process on Windows, each with its own set of pros and cons:
['socket']
]
);
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -471,7 +467,7 @@ to run a child process on Windows, each with its own set of pros and cons:

```php
$process = new Process('ping example.com', null, null, array());
$process->start($loop);
$process->start();

$process->on('exit', function ($exitcode) {
echo 'exit with ' . $exitcode . PHP_EOL;
Expand All @@ -494,7 +490,7 @@ to run a child process on Windows, each with its own set of pros and cons:
$stdout = tmpfile(),
array('file', 'nul', 'w')
));
$process->start($loop);
$process->start();

$process->on('exit', function ($exitcode) use ($stdout) {
echo 'exit with ' . $exitcode . PHP_EOL;
Expand All @@ -520,7 +516,7 @@ to run a child process on Windows, each with its own set of pros and cons:
omit any actual standard I/O pipes like this:

```php
$server = new React\Socket\Server('127.0.0.1:0', $loop);
$server = new React\Socket\Server('127.0.0.1:0');
$server->on('connection', function (React\Socket\ConnectionInterface $connection) {
$connection->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -529,7 +525,7 @@ to run a child process on Windows, each with its own set of pros and cons:

$command = 'ping example.com | foobar ' . escapeshellarg($server->getAddress());
$process = new Process($command, null, null, array());
$process->start($loop);
$process->start();

$process->on('exit', function ($exitcode) use ($server) {
$server->close();
Expand Down Expand Up @@ -560,7 +556,7 @@ to run a child process on Windows, each with its own set of pros and cons:
$code = '$s=stream_socket_client($argv[1]);do{fwrite($s,$d=fread(STDIN, 8192));}while(isset($d[0]));';
$command = 'ping example.com | php -r ' . escapeshellarg($code) . ' ' . escapeshellarg($server->getAddress());
$process = new Process($command, null, null, array());
$process->start($loop);
$process->start();
```

See also [example #23](examples/23-forward-socket.php).
Expand All @@ -580,7 +576,7 @@ particular, this means that shell built-in functions such as `echo hello` or

```php
$process = new Process('cmd /c echo hello', null, null, $pipes);
$process->start($loop);
$process->start();
```

## Install
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
"require": {
"php": ">=5.3.0",
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
"react/stream": "^1.0 || ^0.7.6"
"react/event-loop": "^1.2",
"react/stream": "^1.2"
},
"require-dev": {
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35",
"react/socket": "^1.0",
"react/socket": "^1.8",
"sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0"
},
"autoload": {
Expand Down
14 changes: 5 additions & 9 deletions examples/01-stdio.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;
use React\EventLoop\Loop;

require __DIR__ . '/../vendor/autoload.php';

if (DIRECTORY_SEPARATOR === '\\') {
exit('Process pipes not supported on Windows' . PHP_EOL);
}

$loop = Factory::create();

$process = new Process('cat');
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -23,14 +21,12 @@
});

// periodically send something to stream
$periodic = $loop->addPeriodicTimer(0.2, function () use ($process) {
$periodic = Loop::addPeriodicTimer(0.2, function () use ($process) {
$process->stdin->write('hello');
});

// stop sending after a few seconds
$loop->addTimer(2.0, function () use ($periodic, $loop, $process) {
$loop->cancelTimer($periodic);
Loop::addTimer(2.0, function () use ($periodic, $process) {
Loop::cancelTimer($periodic);
$process->stdin->end();
});

$loop->run();
9 changes: 2 additions & 7 deletions examples/02-race.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;

require __DIR__ . '/../vendor/autoload.php';
Expand All @@ -9,13 +8,11 @@
exit('Process pipes not supported on Windows' . PHP_EOL);
}

$loop = Factory::create();

$first = new Process('sleep 2; echo welt');
$first->start($loop);
$first->start();

$second = new Process('sleep 1; echo hallo');
$second->start($loop);
$second->start();

$first->stdout->on('data', function ($chunk) {
echo $chunk;
Expand All @@ -24,5 +21,3 @@
$second->stdout->on('data', function ($chunk) {
echo $chunk;
});

$loop->run();
7 changes: 1 addition & 6 deletions examples/03-stdout-stderr.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;

require __DIR__ . '/../vendor/autoload.php';
Expand All @@ -9,10 +8,8 @@
exit('Process pipes not supported on Windows' . PHP_EOL);
}

$loop = Factory::create();

$process = new Process('echo hallo;sleep 1;echo welt >&2;sleep 1;echo error;sleep 1;nope');
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo '(' . $chunk . ')';
Expand All @@ -25,5 +22,3 @@
$process->on('exit', function ($code) {
echo 'EXIT with code ' . $code . PHP_EOL;
});

$loop->run();
10 changes: 3 additions & 7 deletions examples/04-terminate.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;
use React\EventLoop\Loop;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

// start a process that takes 10s to terminate
$process = new Process('php -r "sleep(10);"', null, null, array());
$process->start($loop);
$process->start();

// report when process exits
$process->on('exit', function ($exit, $term) {
var_dump($exit, $term);
});

// forcefully terminate process after 2s
$loop->addTimer(2.0, function () use ($process) {
Loop::addTimer(2.0, function () use ($process) {
foreach ($process->pipes as $pipe) {
$pipe->close();
}
$process->terminate();
});

$loop->run();
7 changes: 1 addition & 6 deletions examples/05-stdio-sockets.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php

use React\EventLoop\Factory;
use React\ChildProcess\Process;

require __DIR__ . '/../vendor/autoload.php';
Expand All @@ -9,8 +8,6 @@
exit('Socket descriptors require PHP 8+' . PHP_EOL);
}

$loop = Factory::create();

$process = new Process(
'php -r ' . escapeshellarg('echo 1;sleep(1);fwrite(STDERR,2);exit(3);'),
null,
Expand All @@ -21,7 +18,7 @@
['socket']
]
);
$process->start($loop);
$process->start();

$process->stdout->on('data', function ($chunk) {
echo '(' . $chunk . ')';
Expand All @@ -34,5 +31,3 @@
$process->on('exit', function ($code) {
echo 'EXIT with code ' . $code . PHP_EOL;
});

$loop->run();
Loading