scratch – Blame information for rev

Subversion Repositories:
Rev:
Rev Author Line No. Line
115 office 1 # Binary Driver
2  
3 Binary-Driver is a set of PHP tools to build binary drivers.
4  
5 [![Build Status](https://travis-ci.org/alchemy-fr/BinaryDriver.png?branch=master)](https://travis-ci.org/alchemy-fr/BinaryDriver)
6  
7 ## Why ?
8  
9 You may wonder *Why building a library while I can use `exec` or
10 [symfony/process](https://github.com/symfony/Process) ?*.
11  
12 Here is a simple answer :
13  
14 - If you use `exec`, `passthru`, `system`, `proc_open` or any low level process
15 handling in PHP, you should have a look to [symfony/process](https://github.com/symfony/Process)
16 component that will provide an OO portable, testable and secure interface to
17 deal with this. It seems easy at first approach, but if you look at this
18 component [unit tests](https://github.com/symfony/Process/tree/master/Tests),
19 you will see that handling process in a simple interface can easily become a
20 nightmare.
21  
22 - If you already use symfony/process, and want to build binary drivers, you
23 will always have the same common set of methods and objects to configure, log,
24 debug, and generate processes.
25 This library is a base to implement any binary driver with this common set of
26 needs.
27  
28 ## AbstractBinary
29  
30 `AbstractBinary` provides an abstract class to build a binary driver. It implements
31 `BinaryInterface`.
32  
33 Implementation example :
34  
35 ```php
36 use Alchemy\BinaryDriver\AbstractBinary;
37  
38 class LsDriver extends AbstractBinary
39 {
40 public function getName()
41 {
42 return 'ls driver';
43 }
44 }
45  
46 $parser = new LsParser();
47  
48 $driver = Driver::load('ls');
49 // will return the output of `ls -a -l`
50 $parser->parse($driver->command(array('-a', '-l')));
51 ```
52  
53 ### Binary detection troubleshooting
54  
55 If you are using Nginx with PHP-fpm, executable detection may not work because of an empty `$_ENV['path']`.
56 To avoid having an empty `PATH` environment variable, add the following line to your `fastcgi_params`
57 config file (replace `/your/current/path/` with the output of `printenv PATH`) :
58  
59 ```
60 fastcgi_param PATH /your/current/path
61 ```
62  
63 ## Logging
64  
65 You can log events with a `Psr\Log\LoggerInterface` by passing it in the load
66 method as second argument :
67  
68 ```php
69 $logger = new Monolog\Logger('driver');
70 $driver = Driver::load('ls', $logger);
71 ```
72  
73 ## Listeners
74  
75 You can add custom listeners on processes.
76 Listeners are built on top of [Evenement](https://github.com/igorw/evenement)
77 and must implement `Alchemy\BinaryDriver\ListenerInterface`.
78  
79 ```php
80 use Symfony\Component\Process\Process;
81  
82 class DebugListener extends EventEmitter implements ListenerInterface
83 {
84 public function handle($type, $data)
85 {
86 foreach (explode(PHP_EOL, $data) as $line) {
87 $this->emit($type === Process::ERR ? 'error' : 'out', array($line));
88 }
89 }
90  
91 public function forwardedEvents()
92 {
93 // forward 'error' events to the BinaryInterface
94 return array('error');
95 }
96 }
97  
98 $listener = new DebugListener();
99  
100 $driver = CustomImplementation::load('php');
101  
102 // adds listener
103 $driver->listen($listener);
104  
105 $driver->on('error', function ($line) {
106 echo '[ERROR] ' . $line . PHP_EOL;
107 });
108  
109 // removes listener
110 $driver->unlisten($listener);
111 ```
112  
113 ### Bundled listeners
114  
115 The debug listener is a simple listener to catch `stderr` and `stdout` outputs ;
116 read the implementation for customization.
117  
118 ```php
119 use Alchemy\BinaryDriver\Listeners\DebugListener;
120  
121 $driver = CustomImplementation::load('php');
122 $driver->listen(new DebugListener());
123  
124 $driver->on('debug', function ($line) {
125 echo $line;
126 });
127 ```
128  
129 ## ProcessBuilderFactory
130  
131 ProcessBuilderFactory ease spawning processes by generating Symfony [Process]
132 (http://symfony.com/doc/master/components/process.html) objects.
133  
134 ```php
135 use Alchemy\BinaryDriver\ProcessBuilderFactory;
136  
137 $factory = new ProcessBuilderFactory('/usr/bin/php');
138  
139 // return a Symfony\Component\Process\Process
140 $process = $factory->create('-v');
141  
142 // echoes '/usr/bin/php' '-v'
143 echo $process->getCommandLine();
144  
145 $process = $factory->create(array('-r', 'echo "Hello !";'));
146  
147 // echoes '/usr/bin/php' '-r' 'echo "Hello !";'
148 echo $process->getCommandLine();
149 ```
150  
151 ## Configuration
152  
153 A simple configuration object, providing an `ArrayAccess` and `IteratorAggregate`
154 interface.
155  
156 ```php
157 use Alchemy\BinaryDriver\Configuration;
158  
159 $conf = new Configuration(array('timeout' => 0));
160  
161 echo $conf->get('timeout');
162  
163 if ($conf->has('param')) {
164 $conf->remove('param');
165 }
166  
167 $conf->set('timeout', 20);
168  
169 $conf->all();
170 ```
171  
172 Same example using the `ArrayAccess` interface :
173  
174 ```php
175 use Alchemy\BinaryDriver\Configuration;
176  
177 $conf = new Configuration(array('timeout' => 0));
178  
179 echo $conf['timeout'];
180  
181 if (isset($conf['param'])) {
182 unset($conf['param']);
183 }
184  
185 $conf['timeout'] = 20;
186 ```
187  
188 ## License
189  
190 This project is released under the MIT license.