@@ -14,6 +14,7 @@ single [`run()`](#run) call that is controlled by the user.
1414* [ Quickstart example] ( #quickstart-example )
1515* [ Usage] ( #usage )
1616 * [ Loop] ( #loop )
17+ * [ Loop methods] ( #loop-methods )
1718 * [ get()] ( #get )
1819 * [ Factory] ( #factory )
1920 * [ create()] ( #create )
@@ -52,88 +53,215 @@ use React\EventLoop\Loop;
5253$server = stream_socket_server('tcp://127.0.0.1:8080');
5354stream_set_blocking($server, false);
5455
55- Loop::get()-> addReadStream($server, function ($server) {
56+ Loop::addReadStream($server, function ($server) {
5657 $conn = stream_socket_accept($server);
5758 $data = "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nHi\n";
58- Loop::get()-> addWriteStream($conn, function ($conn) use (& $data) {
59+ Loop::addWriteStream($conn, function ($conn) use (& $data) {
5960 $written = fwrite($conn, $data);
6061 if ($written === strlen($data)) {
6162 fclose($conn);
62- Loop::get()-> removeWriteStream($conn);
63+ Loop::removeWriteStream($conn);
6364 } else {
6465 $data = substr($data, $written);
6566 }
6667 });
6768});
6869
69- Loop::get()-> addPeriodicTimer(5, function () {
70+ Loop::addPeriodicTimer(5, function () {
7071 $memory = memory_get_usage() / 1024;
7172 $formatted = number_format($memory, 3).'K';
7273 echo "Current memory usage: {$formatted}\n";
7374});
7475
75- Loop::get()-> run();
76+ Loop::run();
7677```
7778
7879See also the [ examples] ( examples ) .
7980
8081## Usage
8182
82- Typical applications use a single event loop which is created at the beginning
83- and run at the end of the program.
83+ As of ` v1.2.0 ` , typical applications would use the [ ` Loop ` object ] ( #loop )
84+ to use the currently active event loop instance like this:
8485
8586``` php
86- // [1]
87- $loop = React\EventLoop\Factory::create();
87+ use React\EventLoop\Loop;
8888
89- // [2]
90- $loop->addPeriodicTimer(1, function () {
91- echo "Tick\n";
89+ $timer = Loop::addPeriodicTimer(0.1, function () {
90+ echo "Tick" . PHP_EOL;
91+ });
92+ Loop::addTimer(1.0, function () use ($timer) {
93+ Loop::cancelTimer($timer);
94+ echo 'Done' . PHP_EOL;
9295});
9396
94- $stream = new React\Stream\ReadableResourceStream(
95- fopen('file.txt', 'r'),
96- $loop
97- );
97+ Loop::run();
98+ ```
99+
100+ As an alternative, you can also explicitly create an event loop instance at the
101+ beginning, reuse it throughout your program and finally run it at the end of the
102+ program like this:
103+
104+ ``` php
105+ $loop = React\EventLoop\Loop::get(); // or deprecated React\EventLoop\Factory::create();
106+
107+ $timer = $loop->addPeriodicTimer(0.1, function () {
108+ echo "Tick" . PHP_EOL;
109+ });
110+ $loop->addTimer(1.0, function () use ($loop, $timer) {
111+ $loop->cancelTimer($timer);
112+ echo 'Done' . PHP_EOL;
113+ });
98114
99- // [3]
100115$loop->run();
101116```
102117
103- 1 . The loop instance is created at the beginning of the program. A convenience
104- factory [ ` React\EventLoop\Factory::create() ` ] ( #create ) is provided by this library which
105- picks the best available [ loop implementation] ( #loop-implementations ) .
106- 2 . The loop instance is used directly or passed to library and application code.
107- In this example, a periodic timer is registered with the event loop which
108- simply outputs ` Tick ` every second and a
109- [ readable stream] ( https://github.com/reactphp/stream#readableresourcestream )
110- is created by using ReactPHP's
111- [ stream component] ( https://github.com/reactphp/stream ) for demonstration
112- purposes.
113- 3 . The loop is run with a single [ ` $loop->run() ` ] ( #run ) call at the end of the program.
118+ While the former is more concise, the latter is more explicit.
119+ In both cases, the program would perform the exact same steps.
120+
121+ 1 . The event loop instance is created at the beginning of the program. This is
122+ implicitly done the first time you call the [ ` Loop ` class] ( #loop ) or
123+ explicitly when using the deprecated [ ` Factory::create() method ` ] ( #create )
124+ (or manually instantiating any of the [ loop implementation] ( #loop-implementations ) ).
125+ 2 . The event loop is used directly or passed as an instance to library and
126+ application code. In this example, a periodic timer is registered with the
127+ event loop which simply outputs ` Tick ` every fraction of a second until another
128+ timer stops the periodic timer after a second.
129+ 3 . The event loop is run at the end of the program with a single [ ` run() ` ] ( #run )
130+ call at the end of the program.
131+
132+ As of ` v1.2.0 ` , we highly recommend using the [ ` Loop ` class] ( #loop ) .
133+ The explicit loop instructions are still valid and may still be useful in some
134+ applications, especially for a transition period towards the more concise style.
114135
115136### Loop
116137
117138The ` Loop ` class exists as a convenient global accessor for the event loop.
118139
119- #### get()
140+ #### Loop methods
120141
121- The ` get(): LoopInterface ` method is the preferred way to get and use the event loop. With
122- it there is no need to always pass the loop around anymore.
142+ The ` Loop ` class provides all methods that exist on the [ ` LoopInterface ` ] ( #loopinterface )
143+ as static methods:
144+
145+ * [ run()] ( #run )
146+ * [ stop()] ( #stop )
147+ * [ addTimer()] ( #addtimer )
148+ * [ addPeriodicTimer()] ( #addperiodictimer )
149+ * [ cancelTimer()] ( #canceltimer )
150+ * [ futureTick()] ( #futuretick )
151+ * [ addSignal()] ( #addsignal )
152+ * [ removeSignal()] ( #removesignal )
153+ * [ addReadStream()] ( #addreadstream )
154+ * [ addWriteStream()] ( #addwritestream )
155+ * [ removeReadStream()] ( #removereadstream )
156+ * [ removeWriteStream()] ( #removewritestream )
157+
158+ If you're working with the event loop in your application code, it's often
159+ easiest to directly interface with the static methods defined on the ` Loop ` class
160+ like this:
123161
124162``` php
125163use React\EventLoop\Loop;
126164
127- Loop::get()->addTimer(0.02 , function () {
128- echo 'World!' ;
165+ $timer = Loop::addPeriodicTimer(0.1 , function () {
166+ echo 'tick!' . PHP_EOL ;
129167});
130- Loop::get()->addTimer(0.01, function () {
131- echo 'Hello ';
168+
169+ Loop::addTimer(1.0, function () use ($timer) {
170+ Loop::cancelTimer($timer);
171+ echo 'Done' . PHP_EOL;
132172});
133173
134- Loop::get()-> run();
174+ Loop::run();
135175```
136176
177+ On the other hand, if you're familiar with object-oriented programming (OOP) and
178+ dependency injection (DI), you may want to inject an event loop instance and
179+ invoke instance methods on the ` LoopInterface ` like this:
180+
181+ ``` php
182+ use React\EventLoop\Loop;
183+ use React\EventLoop\LoopInterface;
184+
185+ class Greeter
186+ {
187+ private $loop;
188+
189+ public function __construct(LoopInterface $loop)
190+ {
191+ $this->loop = $loop;
192+ }
193+
194+ public function greet(string $name)
195+ {
196+ $this->loop->addTimer(1.0, function () use ($name) {
197+ echo 'Hello ' . $name . '!' . PHP_EOL;
198+ });
199+ }
200+ }
201+
202+ $greeter = new Greeter(Loop::get());
203+ $greeter->greet('Alice');
204+ $greeter->greet('Bob');
205+
206+ Loop::run();
207+ ```
208+
209+ Each static method call will be forwarded as-is to the underlying event loop
210+ instance by using the [ ` Loop::get() ` ] ( #get ) call internally.
211+ See [ ` LoopInterface ` ] ( #loopinterface ) for more details about available methods.
212+
213+ #### get()
214+
215+ The ` get(): LoopInterface ` method can be used to
216+ get the currently active event loop instance.
217+
218+ This method will always return the same event loop instance throughout the
219+ lifetime of your application.
220+
221+ ``` php
222+ use React\EventLoop\Loop;
223+ use React\EventLoop\LoopInterface;
224+
225+ $loop = Loop::get();
226+
227+ assert($loop instanceof LoopInterface);
228+ assert($loop === Loop::get());
229+ ```
230+
231+ This is particularly useful if you're using object-oriented programming (OOP)
232+ and dependency injection (DI). In this case, you may want to inject an event
233+ loop instance and invoke instance methods on the ` LoopInterface ` like this:
234+
235+ ``` php
236+ use React\EventLoop\Loop;
237+ use React\EventLoop\LoopInterface;
238+
239+ class Greeter
240+ {
241+ private $loop;
242+
243+ public function __construct(LoopInterface $loop)
244+ {
245+ $this->loop = $loop;
246+ }
247+
248+ public function greet(string $name)
249+ {
250+ $this->loop->addTimer(1.0, function () use ($name) {
251+ echo 'Hello ' . $name . '!' . PHP_EOL;
252+ });
253+ }
254+ }
255+
256+ $greeter = new Greeter(Loop::get());
257+ $greeter->greet('Alice');
258+ $greeter->greet('Bob');
259+
260+ Loop::run();
261+ ```
262+
263+ See [ ` LoopInterface ` ] ( #loopinterface ) for more details about available methods.
264+
137265### Factory
138266
139267The ` Factory ` class exists as a convenient way to pick the best available
0 commit comments