src/functions.php source

1 <?php
2
3 namespace phasync;
4
5 /**
6 * This file provides an interface with functions having the same name as their native PHP
7 * equivalents. By importing these functions into your file, you can easily replace the native
8 * function with a coroutine aware version. Simply do:
9 *
10 * use function phasync\{
11 * fread,
12 * fwrite,
13 * file_get_contents
14 * };
15 *
16 * and you can use `fread`, `fwrite` and `file_get_contents` in your files, and your code will
17 * be coroutine aware.
18 */
19
20 /**
21 * Run a coroutine synchronously, and await the result. You can
22 * nest calls to run() within other coroutines.
23 *
24 * @param array $args
25 *
26 * @deprecated Use {@see \phasync::run()} instead
27 *
28 * @throws \FiberError
29 * @throws \Throwable
30 */
31 function run(\Closure $coroutine, mixed ...$args): mixed
32 {
33 return \phasync::run($coroutine, $args);
34 }
35
36 /**
37 * Run a coroutine asynchronously. The return value is a {@see Fiber}
38 * instance. You can use {@see await()} to resolve the return value.
39 *
40 * @param array $args
41 *
42 * @deprecated Use {@see \phasync::go()} instead
43 *
44 * @throws \FiberError
45 * @throws \Throwable
46 */
47 function go(\Closure $coroutine, mixed ...$args): \Fiber
48 {
49 return \phasync::go($coroutine, ...$args);
50 }
51
52 /**
53 * Wait for a coroutine to complete and return the result. If exceptions
54 * are thrown in the coroutine, they will be thrown here.
55 *
56 * @deprecated Use {@see \phasync::await()} instead
57 *
58 * @throws \Throwable
59 */
60 function await(\Fiber $fiber): mixed
61 {
62 return \phasync::await($fiber);
63 }
64
65 /**
66 * Pause execution from within a coroutine, allowing other coroutines
67 * to act.
68 *
69 * @throws \FiberError
70 * @throws \Throwable
71 */
72 function sleep(float $seconds=0): void
73 {
74 \phasync::sleep($seconds);
75 }
76
77 /**
78 * Pause the coroutine until there are no coroutines that will run immediately,
79 * effectively waiting until the entire application is waiting for IO operations
80 * or timers to complete.
81 */
82 function idle(?float $timeout=null): void
83 {
84 \phasync::idle($timeout);
85 }
86
87 /**
88 * Coroutine aware read of file contents, similar to {@see \file_get_contents()}.
89 * Whenever IO blocks, other coroutines will be allowed to continue processing.
90 *
91 * @throws \Exception
92 * @throws \FiberError
93 * @throws \Throwable
94 *
95 * @return string
96 */
97 function file_get_contents(string $filename): string|false
98 {
99 return io::file_get_contents($filename);
100 }
101
102 /**
103 * Coroutine aware write of data to a file.
104 *
105 * This function is modeled after file_put_contents(), but it performs
106 * the write operation in a non-blocking manner using the event loop.
107 *
108 * @param string $filename path to the file where to write the data
109 * @param mixed $data The data to write. Can be a string, an array or a stream resource.
110 * @param int $flags Flags to modify the behavior of the write operation (e.g., FILE_APPEND).
111 *
112 * @throws \Exception if unable to open the file or write fails
113 *
114 * @return void
115 */
116 function file_put_contents(string $filename, mixed $data, int $flags = 0): int|false
117 {
118 return io::file_put_contents($filename, $data, $flags);
119 }
120
121 /**
122 * Coroutine aware read until EOF from a given stream resource, similar to {@see \stream_get_contents()}.
123 * This function allows the event loop to continue processing other tasks whenever IO would block.
124 *
125 * @param resource $stream the stream resource from which to read
126 * @param int|null $maxLength Maximum bytes to read. Null for no limit, until EOF.
127 * @param int $offset seek to the specified offset before reading (if the stream supports seeking)
128 *
129 * @throws \Exception if unable to seek in the stream or other reading errors occur
130 * @throws \FiberError if called outside a coroutine context where necessary
131 * @throws \Throwable for any unexpected errors during operation
132 *
133 * @return string|false the read data on success, or false on failure
134 */
135 function stream_get_contents($stream, ?int $maxLength = null, int $offset = -1): string|false
136 {
137 return io::stream_get_contents($stream, $maxLength, $offset);
138 }
139
140 /**
141 * Coroutine aware binary-safe file read
142 *
143 * @param resource $stream the stream resource to read from
144 * @param int $length maximum number of bytes to read
145 *
146 * @return string|false the read data on success, or false on failure
147 */
148 function fread($stream, int $length): string|false
149 {
150 return io::fread($stream, $length);
151 }
152
153 /**
154 * Coroutine aware get line from file pointer
155 *
156 * @param resource $stream the stream resource to read from
157 * @param int $length maximum number of bytes to read
158 *
159 * @return string|false the read data on success, or false on failure
160 */
161 function fgets($stream, ?int $length = null): string|false
162 {
163 return io::fgets($stream, $length);
164 }
165
166 /**
167 * Coroutine aware get character from file pointer.
168 *
169 * @param resource $stream the stream resource to read from
170 *
171 * @return string|false the read data on success, or false on failure
172 */
173 function fgetc($stream): string|false
174 {
175 return io::fgetc($stream);
176 }
177
178 /**
179 * Coroutine aware get line from file pointer and parse for CSV fields
180 *
181 * @param resource $stream the stream resource to read from
182 * @param int $length maximum number of bytes to read
183 *
184 * @throws \Exception if the read operation fails
185 *
186 * @return string|false the read data on success, or false on failure
187 */
188 function fgetcsv($stream, ?int $length = null, string $separator = ',', string $enclosure = '"', string $escape = '\\'): array|false
189 {
190 return io::fgetcsv($stream, $length, $separator, $enclosure, $escape);
191 }
192
193 /**
194 * Coroutine aware format line as CSV and write to file pointer
195 *
196 * @param resource $stream
197 *
198 * @throws \TypeError
199 */
200 function fputcsv($stream, array $fields, string $separator = ',', string $enclosure = '"', string $escape = '\\', string $eol = "\n"): int|false
201 {
202 return io::fputcsv($stream, $fields, $separator, $enclosure, $escape, $eol);
203 }
204
205 /**
206 * Coroutine aware version of {@see \fwrite()}
207 *
208 * @param resource $stream the stream resource to write to
209 * @param string $data the data to write
210 *
211 * @throws \Exception if the write operation fails
212 *
213 * @return int|false the number of bytes written, or false on failure
214 */
215 function fwrite($stream, string $data): int|false
216 {
217 return io::fwrite($stream, $data);
218 }
219
220 /**
221 * Coroutine aware version of {@see \ftruncate()}
222 *
223 * @param resource $stream the stream resource to write to
224 * @param int $size the size to truncate to
225 *
226 * @return int|false returns true on success or false on failure
227 */
228 function ftruncate($stream, int $size): int|false
229 {
230 return io::ftruncate($stream, $size);
231 }
232
233 /**
234 * Coroutine aware version of {@see \flock()}
235 *
236 * @throws \Exception
237 * @throws \Throwable
238 */
239 function flock($stream, int $operation, ?int &$would_block = null): bool
240 {
241 return io::flock($stream, $operation, $would_block);
242 }
243