@@ -11,6 +11,7 @@ tightly integrated at the core level.
11
11
- [ Installation] ( #installation )
12
12
- [ Unix / macOS] ( #unix--macos )
13
13
- [ Windows] ( #windows )
14
+ - [ Adapted PHP Functions] ( #adapted-php-functions )
14
15
- [ Quick Start] ( #quick-start )
15
16
- [ Documentation] ( #documentation )
16
17
- [ Contributing] ( #contributing )
@@ -105,14 +106,191 @@ Please see the [LibUV installation guide](https://github.com/libuv/libuv)
105
106
nmake
106
107
```
107
108
109
+ ---
110
+
111
+ ## Adapted PHP Functions
112
+
113
+ **50+ PHP functions** have been adapted to work asynchronously when used within coroutines:
114
+
115
+ ### DNS Functions
116
+ - `gethostbyname()` - resolve hostname to IP address
117
+ - `gethostbyaddr()` - resolve IP address to hostname
118
+ - `gethostbynamel()` - get list of IP addresses for hostname
119
+
120
+ ### CURL Functions
121
+ - `curl_exec()` - execute cURL request
122
+ - `curl_multi_exec()` - execute multiple cURL handles
123
+ - `curl_multi_select()` - wait for activity on multiple cURL handles
124
+ - `curl_multi_getcontent()` - get content from multi handle
125
+ - `curl_setopt()`, `curl_getinfo()`, `curl_error()`, `curl_close()` - async-aware
126
+
127
+ ### Socket Functions
128
+ - `socket_connect()`, `socket_accept()` - connection operations
129
+ - `socket_read()`, `socket_write()` - data transfer
130
+ - `socket_send()`, `socket_recv()` - data exchange
131
+ - `socket_sendto()`, `socket_recvfrom()` - addressed data transfer
132
+ - `socket_bind()`, `socket_listen()` - server operations
133
+ - `socket_select()` - monitor socket activity
134
+
135
+ ### Stream Functions
136
+ - `file_get_contents()` - get file/URL contents
137
+ - `fread()`, `fwrite()` - file I/O operations
138
+ - `fopen()`, `fclose()` - file handle management
139
+ - `stream_socket_client()`, `stream_socket_server()` - socket streams
140
+ - `stream_socket_accept()` - accept stream connections
141
+ - `stream_select()` - monitor stream activity
142
+ - `stream_context_create()` - async-aware context creation
143
+
144
+ ### Process Execution Functions
145
+ - `proc_open()` - open process with pipes
146
+ - `exec()` - execute external command
147
+ - `shell_exec()` - execute shell command
148
+ - `system()` - execute system command
149
+ - `passthru()` - execute and pass output directly
150
+
151
+ ### Sleep/Timer Functions
152
+ - `sleep()` - delay execution (seconds)
153
+ - `usleep()` - delay execution (microseconds)
154
+ - `time_nanosleep()` - nanosecond precision delay
155
+ - `time_sleep_until()` - sleep until timestamp
156
+
157
+ ### Output Buffer Functions
158
+ - `ob_start()` - start output buffering with coroutine isolation
159
+ - `ob_flush()`, `ob_clean()` - buffer operations with isolation
160
+ - `ob_get_contents()`, `ob_end_clean()` - get/end buffer with isolation
161
+
162
+ All functions automatically become non-blocking when used in async context, allowing other coroutines to continue execution while waiting for I/O operations to complete.
163
+
164
+ ---
165
+
108
166
## Quick Start
109
167
168
+ ### Basic Coroutine Example
169
+
170
+ ```php
171
+ <?php
172
+
173
+ // Spawn multiple concurrent coroutines
174
+ Async\spawn(function() {
175
+ echo "Starting coroutine 1\n";
176
+ sleep(2); // Non-blocking in async context
177
+ echo "Coroutine 1 completed\n";
178
+ });
179
+
180
+ Async\spawn(function() {
181
+ echo "Starting coroutine 2\n";
182
+ sleep(1); // Non-blocking in async context
183
+ echo "Coroutine 2 completed\n";
184
+ });
185
+
186
+ echo "All coroutines started\n";
187
+ ```
188
+
189
+ ### Concurrent DNS Lookups
190
+
191
+ ``` php
192
+ <?php
193
+
194
+ $start = microtime(true);
195
+
196
+ // Start multiple DNS lookups concurrently
197
+ Async\spawn(function() {
198
+ $ip = gethostbyname('github.com'); // Non-blocking
199
+ $ips = gethostbynamel('github.com'); // Get all IPs
200
+ echo "GitHub: $ip (" . count($ips) . " total IPs)\n";
201
+ });
202
+
203
+ Async\spawn(function() {
204
+ $ip = gethostbyname('google.com'); // Non-blocking
205
+ $hostname = gethostbyaddr($ip); // Reverse lookup
206
+ echo "Google: $ip -> $hostname\n";
207
+ });
208
+
209
+ Async\spawn(function() {
210
+ $content = file_get_contents('http://httpbin.org/ip'); // Non-blocking
211
+ echo "External IP: " . json_decode($content)->origin . "\n";
212
+ });
213
+
214
+ $elapsed = microtime(true) - $start;
215
+ echo "All operations completed in: " . round($elapsed, 3) . "s\n";
216
+ ```
217
+
218
+ ### Concurrent HTTP Requests with CURL
219
+
110
220
``` php
111
221
<?php
112
222
223
+ $urls = [
224
+ 'https://httpbin.org/delay/1',
225
+ 'https://httpbin.org/delay/2',
226
+ 'https://httpbin.org/delay/1'
227
+ ];
228
+
229
+ $start = microtime(true);
230
+
231
+ foreach ($urls as $i => $url) {
232
+ Async\spawn(function() use ($url, $i) {
233
+ $ch = curl_init($url);
234
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
235
+ curl_setopt($ch, CURLOPT_TIMEOUT, 10);
236
+
237
+ $response = curl_exec($ch); // Non-blocking
238
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
239
+ curl_close($ch);
240
+
241
+ echo "Request $i: HTTP $httpCode\n";
242
+ });
243
+ }
244
+
245
+ $elapsed = microtime(true) - $start;
246
+ echo "All requests completed in: " . round($elapsed, 3) . "s\n";
247
+ ```
248
+
249
+ ### Process Execution
250
+
251
+ ``` php
252
+ <?php
253
+
254
+ // Execute multiple commands concurrently
113
255
Async\spawn(function() {
114
- // Your async code here
256
+ $output = shell_exec('sleep 2 && echo "Command 1 done"'); // Non-blocking
257
+ echo $output;
115
258
});
259
+
260
+ Async\spawn(function() {
261
+ $output = shell_exec('sleep 1 && echo "Command 2 done"'); // Non-blocking
262
+ echo $output;
263
+ });
264
+
265
+ echo "Commands started\n";
266
+ ```
267
+
268
+ ### Output Buffering with Coroutine Isolation
269
+
270
+ ``` php
271
+ <?php
272
+
273
+ // Each coroutine has isolated output buffer
274
+ Async\spawn(function() {
275
+ ob_start(); // Isolated buffer
276
+ echo "Output from coroutine 1\n";
277
+ echo "More output from coroutine 1\n";
278
+ $buffer1 = ob_get_contents();
279
+ ob_end_clean();
280
+
281
+ echo "Coroutine 1 captured: $buffer1";
282
+ });
283
+
284
+ Async\spawn(function() {
285
+ ob_start(); // Separate isolated buffer
286
+ echo "Output from coroutine 2\n";
287
+ $buffer2 = ob_get_contents();
288
+ ob_end_clean();
289
+
290
+ echo "Coroutine 2 captured: $buffer2";
291
+ });
292
+
293
+ echo "Buffers are isolated between coroutines\n";
116
294
```
117
295
118
296
---
0 commit comments