Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

PHP Streams

gwoo
May 18, 2012

PHP Streams

From basic to intermediate with some advanced techniques on working with streams in php.

gwoo

May 18, 2012
Tweet

More Decks by gwoo

Other Decks in Technology

Transcript

  1. GWoo • PHP developer since 1999 • CakePHP 2005-2009 •

    Lithium 2009-present • Engineer on Orchestra.io @ EngineYard • On a boat Friday, May 18, 12
  2. Input / Output • include/require, and *_once variants • fopen,

    fread, fgets, fgetcsv, fputcsv, fwrite, fclose, feof, etc • file_get_contents, file_put_contents, readfile, file • mkdir, rename, unlink • EVERYTHING! Friday, May 18, 12
  3. Transports ~: php -r "print_r(stream_get_transports());" Array ( [0] => tcp

    [1] => udp [2] => unix [3] => udg [4] => ssl [5] => sslv3 [6] => sslv2 [7] => tls ) Friday, May 18, 12
  4. Example ~: php -r '$fp = stream_socket_client("tcp://php.net:80", $errno, $errstr); \

    > fwrite($fp, "HEAD / HTTP/1.0\r\nHost: php.net\r\nAccept: */*\r\n\r\n"); \ > print_r(stream_get_contents($fp));' HTTP/1.1 200 OK Date: Fri, 18 May 2012 07:12:38 GMT Server: Apache/1.3.41 (Unix) PHP/5.2.17 X-Powered-By: PHP/5.2.17 Content-language: en Set-Cookie: COUNTRY=ITA%2C85.42.99.82; expires=Fri, 25-May-2012 07:12:38 GMT; path=/; domain=.php.net Last-Modified: Fri, 18 May 2012 10:20:11 GMT Connection: close Content-Type: text/html;charset=utf-8 Friday, May 18, 12
  5. Wrappers ~: php -r "print_r(stream_get_wrappers());" Array ( [0] => https

    [1] => ftps [2] => compress.zlib [3] => compress.bzip2 [4] => php [5] => file [6] => glob [7] => data [8] => http [9] => ftp [10] => zip [11] => phar ) Friday, May 18, 12
  6. Example ~: php -r '$fp = fopen("php://temp", "w+"); \ >

    fwrite($fp, "hello world"); \ > rewind($fp); \ > print_r(stream_get_contents($fp));' hello world Friday, May 18, 12
  7. Example ~: php -r '$fp = fopen("php://stdout", "w"); \ >

    fwrite($fp, "hello world");' hello world Friday, May 18, 12
  8. Contexts • A context is a set of parameters and

    wrapper specific options that modify or enhance the behavior of streams. Friday, May 18, 12
  9. Contexts ~: php -r '$http = array("method" => "HEAD"); \

    > readfile("http://php.net", false, stream_context_create(compact("http"))); \ > print_r($http_response_header);' Array ( [0] => HTTP/1.1 200 OK [1] => Date: Fri, 18 May 2012 07:25:32 GMT [2] => Server: Apache/1.3.41 (Unix) PHP/5.2.17 [3] => X-Powered-By: PHP/5.2.17 [4] => Content-language: en [5] => Set-Cookie: COUNTRY=ITA%2C85.42.99.82; expires=Fri, 25- May-2012 07:25:34 GMT; path=/; domain=.php.net [6] => Last-Modified: Fri, 18 May 2012 10:20:11 GMT [7] => Connection: close [8] => Content-Type: text/html;charset=utf-8 ) Friday, May 18, 12
  10. Filters • modify data while reading and/or writing • appended

    and removed anytime • chain filters as needed Friday, May 18, 12
  11. Default Filters ~: php -r "print_r(stream_get_filters());" Array ( [0] =>

    zlib.* [1] => bzip2.* [2] => convert.iconv.* [3] => string.rot13 [4] => string.toupper [5] => string.tolower [6] => string.strip_tags [7] => convert.* [8] => consumed [9] => dechunk [10] => http.* ) Friday, May 18, 12
  12. streamWrapper { /* Properties */ public resource $context ; /*

    Methods */ __construct ( void ) __destruct ( void ) public bool dir_closedir ( void ) public bool dir_opendir ( string $path , int $options ) public string dir_readdir ( void ) public bool dir_rewinddir ( void ) public bool mkdir ( string $path , int $mode , int $options ) public bool rename ( string $path_from , string $path_to ) public bool rmdir ( string $path , int $options ) public resource stream_cast ( int $cast_as ) public void stream_close ( void ) public bool stream_eof ( void ) public bool stream_flush ( void ) public bool stream_lock ( mode $operation ) public bool stream_metadata ( int $path , int $option , int $var ) public bool stream_open ( string $path , string $mode , int $options , string &$opened_path ) public string stream_read ( int $count ) public bool stream_seek ( int $offset , int $whence = SEEK_SET ) public bool stream_set_option ( int $option , int $arg1 , int $arg2 ) public array stream_stat ( void ) public int stream_tell ( void ) public bool stream_truncate ( int $new_size ) public int stream_write ( string $data ) public bool unlink ( string $path ) public array url_stat ( string $path , int $flags ) } Friday, May 18, 12
  13. interface Stream_Interface { public function stream_open($path,$mode,$options,&$opened_path); public function stream_close(); public

    function stream_read($count); public function stream_write($data); public function stream_eof(); public function stream_tell(); public function stream_seek($offset, $whence); public function stream_stat(); public function url_stat($path, $flags); } Friday, May 18, 12
  14. class AutoEscapeStream implements Stream_Interface { protected $_position = 0; protected

    $_stats = array(); protected $_data = null; protected $_path = null; } Friday, May 18, 12
  15. class AutoEscapeStream implements Stream_Interface { ... public function stream_open($path, $mode,

    $options, &$opened_path) { $path = str_replace('escape://', '', $path); if (empty($path)) { return false; } $success = ($this->_data = file_get_contents($path)); $this->_stats = stat($path); if ($success === false) { return false; } $escEcho = '/\<\?=\s*\$this->(.+?)\s*;?\s*\?>/ms'; $this->_data = preg_replace($escEcho, '<?php echo $this->$1; ?>', $this->_data); $echo = '/\<\?=\s*(.+?)\s*;?\s*\?>/ms'; $this->_data = preg_replace($echo, '<?php echo $h($1); ?>', $this->_data); return true; } public function stream_read($count) { $result = substr($this->_data, $this->_position, $count); $this->_position += strlen($result); return $result; } public function stream_tell() { return $this->_position; } public function stream_eof() { return ($this->_position >= strlen($this->_data)); } Friday, May 18, 12
  16. class AutoEscapeStream implements Stream_Interface { ... public function stream_seek($offset, $whence)

    { switch ($whence) { case SEEK_SET: if ($offset < strlen($this->_data) && $offset >= 0) { $this->_position = $offset; return true; } return false; case SEEK_CUR: if ($offset >= 0) { $this->_position += $offset; return true; } return false; case SEEK_END: if (strlen($this->_data) + $offset >= 0) { $this->_position = strlen($this->_data) + $offset; return true; } return false; default: } return false; } public function stream_stat() { return $this->_stats; } public function url_stat() { return $this->_stats; } Friday, May 18, 12