Skip to content

Commit 1fe327b

Browse files
authored
Merge pull request #45 from clue-labs/examples
Restructure examples
2 parents 9fe6d4d + eb79a60 commit 1fe327b

File tree

6 files changed

+114
-8
lines changed

6 files changed

+114
-8
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,3 +564,8 @@ MIT
564564

565565
* If you want to learn more about processing streams of data, refer to the documentation of
566566
the underlying [react/stream](https://github.com/reactphp/stream) component.
567+
* If you build an interactive CLI tool that reads a command line from STDIN, you
568+
may want to use [clue/arguments](https://github.com/clue/php-arguments) in
569+
order to split this string up into its individual arguments and then use
570+
[clue/commander](https://github.com/clue/php-commander) to route to registered
571+
commands and their required arguments.

composer.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,9 @@
2222
},
2323
"autoload": {
2424
"psr-4": { "Clue\\React\\Stdio\\": "src/" }
25+
},
26+
"require-dev": {
27+
"clue/commander": "^1.2",
28+
"clue/arguments": "^2.0"
2529
}
2630
}

examples/01-periodic.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
use Clue\React\Stdio\Stdio;
4+
5+
require __DIR__ . '/../vendor/autoload.php';
6+
7+
$loop = React\EventLoop\Factory::create();
8+
9+
$stdio = new Stdio($loop);
10+
11+
$stdio->writeln('Will print periodic messages until you submit anything');
12+
13+
// add some periodic noise
14+
$timer = $loop->addPeriodicTimer(0.5, function () use ($stdio) {
15+
$stdio->writeln(date('Y-m-d H:i:s') . ' hello');
16+
});
17+
18+
// react to commands the user entered
19+
$stdio->on('line', function ($line) use ($stdio, $timer) {
20+
$stdio->writeln('you just said: ' . $line . ' (' . strlen($line) . ')');
21+
22+
$timer->cancel();
23+
$stdio->end();
24+
});
25+
26+
$loop->run();

examples/periodic.php renamed to examples/02-interactive.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,15 @@
3636
return $offset > 1 ? array() : array('exit', 'quit', 'help', 'echo', 'print', 'printf');
3737
});
3838

39-
$stdio->writeln('Will print periodic messages until you type "quit" or "exit"');
39+
$stdio->writeln('Welcome to this interactive demo');
4040

41-
$stdio->on('line', function ($line) use ($stdio, $loop, &$timer) {
41+
// react to commands the user entered
42+
$stdio->on('line', function ($line) use ($stdio) {
4243
$stdio->writeln('you just said: ' . $line . ' (' . strlen($line) . ')');
4344

4445
if (in_array(trim($line), array('quit', 'exit'))) {
45-
$timer->cancel();
4646
$stdio->end();
4747
}
4848
});
4949

50-
// add some periodic noise
51-
$timer = $loop->addPeriodicTimer(2.0, function () use ($stdio) {
52-
$stdio->writeln('hello');
53-
});
54-
5550
$loop->run();

examples/03-commander.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
use Clue\React\Stdio\Stdio;
4+
use Clue\Arguments;
5+
use Clue\Commander\Router;
6+
use Clue\Commander\NoRouteFoundException;
7+
8+
require __DIR__ . '/../vendor/autoload.php';
9+
10+
$loop = React\EventLoop\Factory::create();
11+
12+
$stdio = new Stdio($loop);
13+
$readline = $stdio->getReadline();
14+
$readline->setPrompt('> ');
15+
16+
// limit history to HISTSIZE env
17+
$limit = getenv('HISTSIZE');
18+
if ($limit === '' || $limit < 0) {
19+
// empty string or negative value means unlimited
20+
$readline->limitHistory(null);
21+
} elseif ($limit !== false) {
22+
// apply any other value if given
23+
$readline->limitHistory($limit);
24+
}
25+
26+
// register all available commands and their arguments
27+
$router = new Router();
28+
$router->add('exit | quit', function() use ($stdio) {
29+
$stdio->end();
30+
});
31+
$router->add('help', function () use ($stdio) {
32+
$stdio->writeln('Use TAB-completion or use "exit"');
33+
});
34+
$router->add('(echo | print) <words>...', function (array $args) use ($stdio) {
35+
$stdio->writeln(implode(' ', $args['words']));
36+
});
37+
$router->add('printf <format> <args>...', function (array $args) use ($stdio) {
38+
$stdio->writeln(vsprintf($args['format'],$args['args']));
39+
});
40+
41+
// autocomplete the following commands (at offset=0/1 only)
42+
$readline->setAutocomplete(function ($_, $offset) {
43+
return $offset > 1 ? array() : array('exit', 'quit', 'help', 'echo', 'print', 'printf');
44+
});
45+
46+
$stdio->writeln('Welcome to this interactive demo');
47+
48+
// react to commands the user entered
49+
$stdio->on('line', function ($line) use ($router, $stdio, $readline) {
50+
// add all lines from input to history
51+
// skip empty line and duplicate of previous line
52+
$all = $readline->listHistory();
53+
if (trim($line) !== '' && $line !== end($all)) {
54+
$readline->addHistory($line);
55+
}
56+
57+
try {
58+
$args = Arguments\split($line);
59+
} catch (Arguments\UnclosedQuotesException $e) {
60+
$stdio->writeln('Error: Invalid command syntax (unclosed quotes)');
61+
return;
62+
}
63+
64+
// skip empty lines
65+
if (!$args) {
66+
return;
67+
}
68+
69+
try {
70+
$router->handleArgs($args);
71+
} catch (NoRouteFoundException $e) {
72+
$stdio->writeln('Error: Invalid command usage');
73+
}
74+
});
75+
76+
$loop->run();
File renamed without changes.

0 commit comments

Comments
 (0)