1 | <?php |
||
35 | class BufferStream implements Streamable |
||
36 | { |
||
37 | use IsReadable, IsWritable; |
||
38 | |||
39 | /** |
||
40 | * Buffer contents |
||
41 | * @var string A string containing the buffer contents |
||
42 | */ |
||
43 | protected $buffer = ''; |
||
44 | |||
45 | /** |
||
46 | * Is stream readable? |
||
47 | * |
||
48 | * @var boolean Whether stream is readable |
||
49 | */ |
||
50 | protected $readable = true; |
||
51 | |||
52 | /** |
||
53 | * Is stream writable? |
||
54 | * |
||
55 | * @var boolean Whether stream is writable |
||
56 | */ |
||
57 | protected $writable = true; |
||
58 | |||
59 | /** |
||
60 | * Is stream seekable? |
||
61 | * |
||
62 | * @var boolean Whether stream is seekable |
||
63 | */ |
||
64 | protected $seekable = false; |
||
65 | |||
66 | /** |
||
67 | * @var array Stream meta data |
||
68 | * hwm: "high water mark" - once buffer reaches this number (in bytes) |
||
69 | * write() operations will begin returning false defaults to 16384 bytes (16KB) |
||
70 | */ |
||
71 | protected $meta = [ |
||
72 | 'hwm' => 16384 |
||
73 | ]; |
||
74 | |||
75 | /** |
||
76 | * Instantiate a buffer stream. |
||
77 | * |
||
78 | * Instantiate a new buffer stream, optionally changing the high water mark |
||
79 | * from its default of 16384 bytes (16KB). Once buffer reaches high water |
||
80 | * mark, write operations will begin returning false. It's possible for buffer |
||
81 | * size to exceed this level since it is only AFTER it is reached that writes |
||
82 | * begin returning false. |
||
83 | * |
||
84 | * @param int Number (in bytes) representing buffer "high water mark" |
||
85 | */ |
||
86 | 21 | public function __construct($hwm = null) |
|
92 | |||
93 | 11 | public function isEmpty() |
|
97 | |||
98 | 11 | public function isFull() |
|
102 | |||
103 | /** |
||
104 | * Readability accessor. |
||
105 | * |
||
106 | * Despite the fact that any class that implements this interface must also |
||
107 | * define methods such as read and readLine, that is no guarantee that an |
||
108 | * object will necessarily be readable. This method should tell the user |
||
109 | * whether a stream is, in fact, readable. |
||
110 | * |
||
111 | * @return boolean True if readable, false otherwise |
||
112 | */ |
||
113 | 1 | public function isReadable() |
|
117 | |||
118 | /** |
||
119 | * Read in the specified amount of characters from the input source |
||
120 | * |
||
121 | * @param integer Amount of characters to read from input source |
||
122 | * @return string|boolean The specified amount of characters read from input source |
||
123 | */ |
||
124 | 18 | public function read($chars) |
|
133 | |||
134 | /** |
||
135 | * Read the entire stream, beginning to end. |
||
136 | * |
||
137 | * In most stream implementations, __toString() differs from getContents() |
||
138 | * in that it returns the entire stream rather than just the remainder, but |
||
139 | * due to the way this stream works (sort of like a conveyor belt), this |
||
140 | * method is an alias to getContents() |
||
141 | * |
||
142 | * @return string The entire stream, beginning to end |
||
143 | */ |
||
144 | 1 | public function __toString() |
|
148 | |||
149 | /** |
||
150 | * Read the remainder of the stream |
||
151 | * |
||
152 | * @return string The remainder of the stream |
||
153 | */ |
||
154 | 3 | public function getContents() |
|
160 | |||
161 | /** |
||
162 | * Return the size (in bytes) of this readable (if known). |
||
163 | * |
||
164 | * @return int|null Size (in bytes) of this readable |
||
165 | */ |
||
166 | 20 | public function getSize() |
|
170 | |||
171 | /** |
||
172 | * Return the current position within the stream/readable |
||
173 | * |
||
174 | * @return int The current position within readable |
||
175 | */ |
||
176 | 2 | public function tell() |
|
180 | |||
181 | /** |
||
182 | * Determine whether the end of the readable resource has been reached |
||
183 | * |
||
184 | * @return boolean Whether we're at the end of the readable |
||
185 | */ |
||
186 | 18 | public function eof() |
|
190 | |||
191 | /** |
||
192 | * File must be able to be rewound when the end is reached |
||
193 | */ |
||
194 | 3 | public function rewind() |
|
198 | |||
199 | /** |
||
200 | * Get stream metadata as an associative array or retrieve a specific key. |
||
201 | * |
||
202 | * The keys returned are identical to the keys returned from PHP's |
||
203 | * stream_get_meta_data() function. |
||
204 | * |
||
205 | * @param string $key Specific metadata to retrieve. |
||
206 | * @return array|mixed|null Returns an associative array if no key is |
||
207 | * provided. Returns a specific key value if a key is provided and the |
||
208 | * value is found, or null if the key is not found. |
||
209 | * @see http://php.net/manual/en/function.stream-get-meta-data.php |
||
210 | */ |
||
211 | 21 | public function getMetadata($key = null) |
|
218 | |||
219 | /** |
||
220 | * Closes the stream and any underlying resources. |
||
221 | * |
||
222 | * @return void |
||
223 | */ |
||
224 | 1 | public function close() |
|
228 | |||
229 | /** |
||
230 | * Separates any underlying resources from the stream. |
||
231 | * |
||
232 | * After the stream has been detached, the stream is in an unusable state. |
||
233 | * |
||
234 | * @return string|null Underlying PHP stream, if any |
||
235 | */ |
||
236 | 1 | public function detach() |
|
242 | |||
243 | /** |
||
244 | * Writability accessor. |
||
245 | * |
||
246 | * Despite the fact that any class that implements this interface must also |
||
247 | * define methods such as write and writeLine, that is no guarantee that an |
||
248 | * object will necessarily be writable. This method should tell the user |
||
249 | * whether a stream is, in fact, writable. |
||
250 | * |
||
251 | * @return boolean True if writable, false otherwise |
||
252 | */ |
||
253 | 1 | public function isWritable() |
|
257 | |||
258 | /** |
||
259 | * Write data to the output. |
||
260 | * |
||
261 | * @param string The data to write |
||
262 | * @return int The number of bytes written |
||
263 | */ |
||
264 | 20 | public function write($data) |
|
272 | |||
273 | /** |
||
274 | * Seekability accessor. |
||
275 | * |
||
276 | * Despite the fact that any class that implements this interface must also |
||
277 | * define methods such as seek, that is no guarantee that an |
||
278 | * object will necessarily be seekable. This method should tell the user |
||
279 | * whether a stream is, in fact, seekable. |
||
280 | * |
||
281 | * @return boolean True if seekable, false otherwise |
||
282 | */ |
||
283 | 1 | public function isSeekable() |
|
287 | |||
288 | /** |
||
289 | * Seek to specified offset. |
||
290 | * |
||
291 | * @param integer Offset to seek to |
||
292 | * @param integer Position from whence the offset should be applied |
||
293 | * @return boolean True if seek was successful |
||
294 | */ |
||
295 | 1 | public function seek($offset, $whence = SEEK_SET) |
|
299 | |||
300 | } |
||
301 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.