PHP Streams
-
Upload
g-woo -
Category
Technology
-
view
1.106 -
download
1
description
Transcript of PHP Streams
It’s all streams these days
Friday, May 18, 12
GWoo
• PHP developer since 1999
• CakePHP 2005-2009
• Lithium 2009-present
• Engineer on Orchestra.io @ EngineYard
• On a boat
Friday, May 18, 12
Basicshttp://php.net/manual/en/book.stream.php
Friday, May 18, 12
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
• Transports
• Wrappers
• Contexts
• Filters
Layers
Friday, May 18, 12
ALL
Input/Ouput
PHP Streams Layer
Stream Filters
Stream Wrapper
Stream Transport
Stream Context
Friday, May 18, 12
Transportshttp://php.net/manual/en/transports.php
Friday, May 18, 12
Transports
• socket clients
• “stream_set_blocking” non-blocking io
Friday, May 18, 12
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
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 OKDate: Fri, 18 May 2012 07:12:38 GMTServer: Apache/1.3.41 (Unix) PHP/5.2.17X-Powered-By: PHP/5.2.17Content-language: enSet-Cookie: COUNTRY=ITA%2C85.42.99.82; expires=Fri, 25-May-2012 07:12:38 GMT; path=/; domain=.php.netLast-Modified: Fri, 18 May 2012 10:20:11 GMTConnection: closeContent-Type: text/html;charset=utf-8
Friday, May 18, 12
Wrappershttp://php.net/manual/en/wrappers.php
Friday, May 18, 12
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
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
Example
~: php -r '$fp = fopen("php://stdout", "w"); \> fwrite($fp, "hello world");'hello world
Friday, May 18, 12
Contextshttp://php.net/manual/en/context.php
Friday, May 18, 12
Contexts
• A context is a set of parameters and wrapper specific options that modify or enhance the behavior of streams.
Friday, May 18, 12
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
Filtershttp://php.net/manual/en/filters.php
Friday, May 18, 12
Filters
• modify data while reading and/or writing
• appended and removed anytime
• chain filters as needed
Friday, May 18, 12
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
Example
$stream = fopen('data://text/plain,' . $body, 'r');stream_filter_append($stream, 'dechunk');return trim(stream_get_contents($stream));
Friday, May 18, 12
Custom Wrappershttp://php.net/manual/en/class.streamwrapper.php
Friday, May 18, 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
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
class AutoEscapeStream implements Stream_Interface {
}
Friday, May 18, 12
class AutoEscapeStream implements Stream_Interface {
protected $_position = 0;
protected $_stats = array();
protected $_data = null;
protected $_path = null;
}
Friday, May 18, 12
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
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
stream_wrapper_register("escape", "AutoEscapeStream");include("escape://template.php");
Using the Wrapper
Friday, May 18, 12
Demo
• Using phar streams
• https://github.com/gwoo/sinatrium
Friday, May 18, 12
Questions?
Friday, May 18, 12
@gwoo
https://github.com/gwoo
THANKS!
Friday, May 18, 12