Input stream are useful as they encapsulate concrete implementation of a data source. You can change the data source without changing the application code. For example, you application reads data from a file. One day your boss decides that you need to retrieve information from a server located 1000 miles away. You just implement another class that implements the same input stream interface. The new class retrieves data from network instead of a local file. That’s it. No more changes are required to your code.
Solution:
The following class implements simple Input Stream functionality in PHP. It provides a handy function for retrieving complete UTF-8 chars. At this time it supports only 1, 2 or 3 – octet (byte) characters.
<?php class FileInputStream { private $fh = FALSE; private $fn = null; public function __construct($file_name) { $this->fn = $file_name; } public function open() { $this->fh = fopen($this->fn, 'r'); } public function close() { fclose($this->fh); } public function fetchByte() { return fread($this->fh, 1); } public function fetchUtf8Char() { $ch = $this->fetchByte(); $code1 = ord($ch); if ($code1 < 0x80) { // Single byte } elseif ($code1 < 0xE0) { // Two byte $ch .= $this->fetchByte(); } elseif ($code1 < 0xF0) { // Tree byte $ch .= $this->fetchByte() . $this->fetchByte(); } return $ch; } public function hasMore() { return ($this->fh !== FALSE) && (feof($this->fh) === FALSE); } } ?>
I kept the functionality of the Input File Stream class to the bare minimum. I haven’t implemented any features that were not necessary for the solving the particular problem the Input Stream was designed for. You can implement methods that solve your problems. For example, you can implement a readLine method.
Useful concrete Input Stream could be a StringInputStream that implements same stream operations as File Input Stream, but for sequential read from string.
Programming patterns require that you create a interface class, for example InputStream. Concrete classes should implement the InputStream interface. PHP allows for replacing types without checking inheritance. Because of performance considerations I decided not to create an abstract interface.
See Also: utf8_decode: Decode UTF-8 Encoded String in PHP
Back to: PHP Tips and Recipes

Add A Comment
You must be logged in to post a comment.