8.5 Filtering Streams

 <  Day Day Up  >  

Use filters to modify the contents of a stream. They allow you to pre- and postprocess data without altering the original. Stream filters are like output buffer handlers only better, because they're more flexible and efficient.

Unlike the output buffer handler, which is best suited for information that's either being printed out or stored in a variable, you can use a filter wherever you can use a stream. This makes it possible to filter, for example, data going to a file. With an output buffer you'd need to store the entire dataset in a buffer, capture it to a variable, and then send it to the file.

You can filter input data as well as output data. PHP's output buffering only works on output data. A filter lets you automatically encode all HTML entities from a user 's input, for example.

PHP comes with a few built-in filters, but you can also create your own. The built-in filters are:


string.rot13

Performs rot13 encoding


string.toupper

Turns all characters to uppercase


string. tolower

Turns all characters to lowercase


string.strip_tags

Eliminates HTML tags


convert.iconv.*

Alters the character set using iconv

Use stream_get_filters( ) to determine which filters are available. It works just like stream_get_wrappers( ) .

Filters observe an unofficial namespace convention. For instance, string filters begin with string . and conversion filters begin with convert ..

To use a filter with a stream, you must associate the two using stream_filter_prepend( ) or stream_filter_append( ) . Since you can place multiple filters upon a single stream, the first function adds the new filter to the front of the list, whereas the second function adds it to the end. If your stream uses only a single filter, there's no difference between the two functions.

8.5.1 Stripping HTML Tags

One of the built-in filters is string.strip_tags . This filter removes HTML tags from the data. For example:

 $html = 'I am <b>bold</b>. I am <i>italic</i>.'; $fp = fopen("php://output", "r"); stream_filter_prepend($fp, "string.strip_tags"); fwrite($fp, $html); fclose($fp); 

prints:

  I am bold. I am italic.  

This code opens a stream and then prepends the string.strip_tags filter to the filter chain. When the string $html is sent to the stream using fwrite( ) , the filter intercepts the stream and removes the HTML tags.

8.5.2 Converting Character Sets

Another useful filter is convert.iconv.* . This allows you to convert text from one character set to another.

As of PHP 5, the iconv library is enabled by default, but it's not required to run PHP, so it's possible (but unlikely ) that your copy of PHP won't have this filter.


For example, you have text stored in UTF-8 and want to convert it to ISO-8859-1 (aka Latin 1):

 $fp = fopen("data.UTF-8.xml", "r"); stream_filter_prepend($fp, "convert.iconv.UTF-8/ISO-8859-1"); $converted = ''; while (!feof($fp)) {     $converted .= fread($fp, 1000); } fclose($fp); 

This opens data.UTF-8.xml , a UTF-8-encoded XML file. The filter convert.iconv.UTF-8/ISO-8859-1 takes this UTF-8 data and converts it to ISO-8859-1.

convert.iconv.* is a special "wildcard" filter that matches any filter name that begins with convert.iconv .. Specify the source and destination encodings after the period and separate them with a slash ( / ). As long as iconv supports those encodings, the filter will work and there's no need to explicitly write filters for every single combination of encoding translations.

You cannot get PHP to provide you with complete list of available encodings. Instead, use the command-line iconv tool with the -l flag:

 % iconv -l 

This prints a long list of encodings, probably beginning with:

  ANSI_X3.4-1968 ANSI_X3.4-1986 ASCII   UTF-8   ISO-10646-UCS-2 UCS-2 CSUNICODE  

To determine if a system supports a particular encoding, check the return value of iconv( ) :

 if (!iconv('ASCII', 'UTF-8', '')) {     // Oops! iconv doesn't support this encoding } 

The function will return false when it cannot convert from one character set to another.

iconv supports two special modifiers for the destination encoding: //TRANSLIT and //IGNORE . The first option tells iconv that whenever it cannot exactly duplicate a character in the destination encoding, it should try to approximate it using a series of other characters. The other option makes iconv silently ignore any unconvertible characters.

For example, the file geb-UTF-8.txt holds the text G del, Escher, Bach . A straight conversion to ASCII produces an error:

 $fp = fopen("geb.UTF-8.txt", "r"); stream_filter_prepend($fp, "convert.iconv.UTF-8/ASCII"); $converted = ''; while (!feof($fp)) {     $converted .= fread($fp, 1000); } fclose($fp);  PHP Warning:  fread( ): iconv stream filter ("UTF-8"=>"ASCII"): unknown error  

Enabling the //IGNORE feature allows the conversion to occur:

 $fp = fopen("geb.UTF-8.txt", "r"); stream_filter_prepend($fp, "convert.iconv.UTF-8/ASCII//IGNORE"); $converted = ''; while (!feof($fp)) {     $converted .= fread($fp, 1000); } fclose($fp); 

However, the output isn't nice, because the is missing:

  Gdel, Escher, Bach  

The best solution is to use //TRANSLIT :

 $fp = fopen("geb.UTF-8.txt", "r"); stream_filter_prepend($fp, "convert.iconv.UTF-8/ASCII//TRANSLIT"); $converted = ''; while (!feof($fp)) {     $converted .= fread($fp, 1000); } fclose($fp); 

This produces a better-looking string:

  G"odel, Escher, Bach  

However, be careful when you use //TRANSLIT , as it can increase the number of characters. For example, the single character becomes two characters: " o .

8.5.3 Using php://filter

Since it doesn't expose a file pointer such as fopen( ) , the file_put_contents( ) function doesn't give you the opportunity to attach a filter using stream_filter_append( ) . The solution is to use the php://filter target.

This weird target exists solely for the purpose of allowing you to integrate filters with functions such as file_put_contents( ) . It lets you specify both filters and another target, like so:

 $html = 'I am <b>bold</b>. I am <i>italic</i>.'; // Stripping HTML tags on data sent to php://output file_put_contents(     'php://filter/write=string.strip_tags/resource=php://output', $html);  I am bold. I am italic.  

This code does the same thing as the longer version here:

 // The long version $fp = fopen("php://output", "r"); stream_filter_prepend($fp, "string.strip_tags"); fwrite($fp, $html); fclose($fp); 

Because filter isn't an actual target, you have to pass the true destination using the string /resource= . For example, use /resource=php://output to send information to the current output buffer.

You can also insert multiple filters into the stream. Filters can process data being read, written, or both. (Some streams are unidirectional, but others are bidirectional.) To designate a filter for reading, add /read= ; for writing, add /write= ; and, for both directions, add /= . For example, /write=string.strip_tags strips HTML tags from any data being written.

Chain multiple filters with the pipe character ( ). Filters are applied in the order present. So, /write=string.strip_tagsstring.string.toupper first strips tags and then uppercases letters .

 <  Day Day Up  >  


Upgrading to PHP 5
Upgrading to PHP 5
ISBN: 0596006365
EAN: 2147483647
Year: 2004
Pages: 144

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net