cvs: phpdoc /en/reference/filesystem/functions file-register-wrapper.xml
| From: | Wez Furlong | Date: | Mon, 23 Sep 2002 22:40:20 +0000 |
| Subject: | cvs: phpdoc /en/reference/filesystem/functions file-register-wrapper.xml | ||
| Groups: | php.doc | ||
| Request: | Send a blank email to phpdoc+get-969348791@lists.php.net to get a copy of this message | ||
wez Mon Sep 23 18:40:20 2002 EDT
Modified files:
/phpdoc/en/reference/filesystem/functions file-register-wrapper.xml
Log:
Flesh out the docs for user streams.
Index: phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml diff -u phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml:1.3 phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml:1.4 --- phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml:1.3 Thu Sep 19 21:02:59 2002 +++ phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml Mon Sep 23 18:40:20 2002 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="iso-8859-1"?> -<!-- $Revision: 1.3 $ --> +<!-- $Revision: 1.4 $ --> <!-- splitted from ./en/functions/filesystem.xml, last change in rev 1.141 --> <refentry id="function.file-register-wrapper"> <refnamediv> @@ -14,75 +14,289 @@ <methodparam><type>string</type><parameter>classname</parameter></methodparam> </methodsynopsis> <para> - This function is currently only documented by the example below: + <function>file_register_wrapper</function> allows you to implement + your own protocol handlers and streams for use with all the other + filesystem functions (such as <function>fopen</function>, + <function>fread</function> etc.). + </para> + <para> + To implement a wrapper, you need to define a class with a number of + member functions, as defined below. When someone fopens your stream, + PHP will create an instance of <parameter>classname</parameter> and + then call methods on that instance. You must implement the methods + exactly as described below - doing otherwise will lead to undefined + behaviour. + </para> + <para> + <function>file_register_wrapper</function> will return &false; if the + <parameter>protocol</parameter> already has a handler. + </para> + + <methodsynopsis> + <type>boolean</type><methodname>stream_open</methodname> + <methodparam><type>string</type><parameter>path</parameter></methodparam> + <methodparam><type>string</type><parameter>mode</parameter></methodparam> + <methodparam><type>int</type><parameter>options</parameter></methodparam> + <methodparam><type>string</type><parameter>opened_path</parameter></methodparam> + </methodsynopsis> + <para> + This method is called immediately after your stream object is + created. <parameter>path</parameter> specifies the URL that was + passed to <function>fopen</function> and that this object is + expected to retrieve. You can use <function>parse_url</function> + to break it apart. + </para> + <para> + <parameter>mode</parameter> is the mode used to open the file, + as detailed for <function>fopen</function>. You are responsible + for checking that <parameter>mode</parameter> is valid for the + <parameter>path</parameter> requested. + </para> + <para> + <parameter>options</parameter> holds additional flags set + by the streams API. It can hold one or more of the following + values OR'd together. + <informaltable> + <tgroup cols="2"> + <thead> + <row> + <entry>Flag</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>STREAM_USE_PATH</entry> + <entry>If <parameter>path</parameter> is relative, search + for the resource using the include_path. + </entry> + </row> + <row> + <entry>STREAM_REPORT_ERRORS</entry> + <entry>If this flag is set, you are responsible for raising + errors using <function>trigger_error</function> during + opening of the stream. If this flag is not set, you + should not raise any errors. + </entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + If the <parameter>path</parameter> is opened successfully, + and STREAM_USE_PATH is set in <parameter>options</parameter>, + you should set <parameter>opened_path</parameter> to the full + path of the file/resource that was actually opened. + </para> + <para> + If the requested resource was opened successfully, you should + return &true;, otherwise you should return &false; + </para> + + <methodsynopsis> + <type>void</type><methodname>stream_close</methodname> + <methodparam><type>void</type><parameter></parameter></methodparam> + </methodsynopsis> + <para> + This method is called when the stream is closed, using + <function>fclose</function>. You must release any resources + that were locked or allocated by the stream. + </para> + + <methodsynopsis> + <type>string</type><methodname>stream_read</methodname> + <methodparam><type>int</type><parameter>count</parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>fread</function> + and <function>fgets</function> calls on the stream. You + must return up-to <parameter>count</parameter> bytes of data + from the current read/write position as a string. + If there are less than <parameter>count</parameter> + bytes available, return as many as are available. If no + more data is available, return either &false; or an + empty string. + You must also update the read/write position of the stream + by the number of bytes that were successfully read. + </para> + + <methodsynopsis> + <type>int</type><methodname>stream_write</methodname> + <methodparam><type>string</type><parameter>data</parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>fwrite</function> + calls on the stream. You should store <parameter>data</parameter> + into the underlying storage used by your stream. If there is not + enough room, try to store as many bytes as possible. + You should return the number of bytes that were successfully + stored in the stream, or 0 if none could be stored. + You must also update the read/write position of the stream + by the number of bytes that were successfully written. + </para> + + <methodsynopsis> + <type>boolean</type><methodname>stream_eof</methodname> + <methodparam><type>void</type><parameter></parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>feof</function> + calls on the stream. You should return &true; if the read/write + position is at the end of the stream and if no more data is available + to be read, or &false; otherwise. + </para> + + <methodsynopsis> + <type>int</type><methodname>stream_tell</methodname> + <methodparam><type>void</type><parameter></parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>ftell</function> + calls on the stream. You should return the current read/write + position of the stream. + </para> + + <methodsynopsis> + <type>boolean</type><methodname>stream_seek</methodname> + <methodparam><type>int</type><parameter>offset</parameter></methodparam> + <methodparam><type>int</type><parameter>whence</parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>fseek</function> + calls on the stream. You should update the read/write position + of the stream according to <parameter>offset</parameter> and + <parameter>whence</parameter>. See <function>fseek</function> + for more information about these parameters. + Return &true; if the position was updated, &false; otherwise. + </para> + + <methodsynopsis> + <type>boolean</type><methodname>stream_flush</methodname> + <methodparam><type>void</type><parameter></parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>fflush</function> + calls on the stream. If you have cached data in your stream + but not yet stored it into the underlying storage, you should + do so now. + Return &true; if the cached data was successfully stored (or + if there was no data to store), or &false; if the data could + not be stored. + </para> + + <para> + The example below implements a var:// protocol handler that + allows read/write access to a named global variable using + standard filesystem stream functions such as <function>fread</function>. + The var:// protocol implemented below, given the url + "var://foo" will read/write data to/from $GLOBALS["foo"]. + <example> - <title>Implementing a base64 encoding protocol</title> + <title>A Stream for reading/writing global variables</title> <programlisting role="php"> <![CDATA[ -class Base64EncodingStream { - var $fp = null; - +class VariableStream { + var $position; + var $varname; + function stream_open($path, $mode, $options, &$opened_path) { - $this->fp = fopen($path, $mode); - return is_resource($this->fp); - } - function stream_close() - { - fclose($this->fp); + $url = parse_url($path); + $this->varname = $split["host"]; + $this->position = 0; + + return true; } + function stream_read($count) { - return false; // We only allow writing + $ret = substr($GLOBALS[$this->varname], $this->position, $count); + $this->position += strlen($ret); + return $ret; } + function stream_write($data) { - return fwrite($this->fp, base64_encode($data)); - } - function stream_flush() - { - fflush($this->fp); - return true; - } - function stream_seek($offset, $whence) - { - return false; - } - function stream_gets() - { - return false; + $left = substr($GLOBALS[$this->varname], 0, $this->position); + $right = substr($GLOBALS[$this->varname], $this->position + strlen($data)); + $GLOBALS[$this->varname] = $left . $data . $right; + $this->position += strlen($data); + return strlen($data); } + function stream_tell() { - return false; + return $this->position; } + function stream_eof() { - return false; + return $this->position >= strlen($GLOBALS[$this->varname]); + } + + function stream_seek($offset, $whence) + { + switch($whence) { + case SEEK_SET: + if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) { + $this->position = $offset; + return true; + } else { + return false; + } + break; + + case SEEK_CUR: + if ($offset >= 0) { + $this->position += $offset; + return true; + } else { + return false; + } + break; + + case SEEK_END: + if (strlen($GLOBALS[$this->varname]) + $offset >= 0) { + $this->position = strlen($GLOBALS[$this->varname]) + $offset; + return true; + } else { + return false; + } + break; + + default: + return false; + } } } -file_register_wrapper("base64", "Base64EncodingStream") + +file_register_wrapper("var", "VariableStream") or die("Failed to register protocol"); -copy("/tmp/inputfile.txt", "base64:///tmp/outputfile.txt"); -readfile("/tmp/outputfile"); +$myvar = ""; + +$fp = fopen("var://myvar", "r+"); + +fwrite($fp, "line1\n"); +fwrite($fp, "line2\n"); +fwrite($fp, "line3\n"); + +rewind($fp); +while(!feof($fp)) { + echo fgets($fp) +} +fclose($fp); +var_dump($myvar); + ]]> </programlisting> </example> - </para> - <para> - <function>file_register_wrapper</function> will return &false; if the - <parameter>protocol</parameter> already has a handler, or if "fopen - wrappers" are disabled. - </para> - <note> - <para> - This function was introduced in PHP 4.3.0. - </para> - </note> + </refsect1> </refentry> + <!-- Keep this comment at the end of the file Local variables:
Index: phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml diff -u phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml:1.3 phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml:1.4 --- phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml:1.3 Thu Sep 19 21:02:59 2002 +++ phpdoc/en/reference/filesystem/functions/file-register-wrapper.xml Mon Sep 23 18:40:20 2002 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="iso-8859-1"?> -<!-- $Revision: 1.3 $ --> +<!-- $Revision: 1.4 $ --> <!-- splitted from ./en/functions/filesystem.xml, last change in rev 1.141 --> <refentry id="function.file-register-wrapper"> <refnamediv> @@ -14,75 +14,289 @@ <methodparam><type>string</type><parameter>classname</parameter></methodparam> </methodsynopsis> <para> - This function is currently only documented by the example below: + <function>file_register_wrapper</function> allows you to implement + your own protocol handlers and streams for use with all the other + filesystem functions (such as <function>fopen</function>, + <function>fread</function> etc.). + </para> + <para> + To implement a wrapper, you need to define a class with a number of + member functions, as defined below. When someone fopens your stream, + PHP will create an instance of <parameter>classname</parameter> and + then call methods on that instance. You must implement the methods + exactly as described below - doing otherwise will lead to undefined + behaviour. + </para> + <para> + <function>file_register_wrapper</function> will return &false; if the + <parameter>protocol</parameter> already has a handler. + </para> + + <methodsynopsis> + <type>boolean</type><methodname>stream_open</methodname> + <methodparam><type>string</type><parameter>path</parameter></methodparam> + <methodparam><type>string</type><parameter>mode</parameter></methodparam> + <methodparam><type>int</type><parameter>options</parameter></methodparam> + <methodparam><type>string</type><parameter>opened_path</parameter></methodparam> + </methodsynopsis> + <para> + This method is called immediately after your stream object is + created. <parameter>path</parameter> specifies the URL that was + passed to <function>fopen</function> and that this object is + expected to retrieve. You can use <function>parse_url</function> + to break it apart. + </para> + <para> + <parameter>mode</parameter> is the mode used to open the file, + as detailed for <function>fopen</function>. You are responsible + for checking that <parameter>mode</parameter> is valid for the + <parameter>path</parameter> requested. + </para> + <para> + <parameter>options</parameter> holds additional flags set + by the streams API. It can hold one or more of the following + values OR'd together. + <informaltable> + <tgroup cols="2"> + <thead> + <row> + <entry>Flag</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>STREAM_USE_PATH</entry> + <entry>If <parameter>path</parameter> is relative, search + for the resource using the include_path. + </entry> + </row> + <row> + <entry>STREAM_REPORT_ERRORS</entry> + <entry>If this flag is set, you are responsible for raising + errors using <function>trigger_error</function> during + opening of the stream. If this flag is not set, you + should not raise any errors. + </entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + If the <parameter>path</parameter> is opened successfully, + and STREAM_USE_PATH is set in <parameter>options</parameter>, + you should set <parameter>opened_path</parameter> to the full + path of the file/resource that was actually opened. + </para> + <para> + If the requested resource was opened successfully, you should + return &true;, otherwise you should return &false; + </para> + + <methodsynopsis> + <type>void</type><methodname>stream_close</methodname> + <methodparam><type>void</type><parameter></parameter></methodparam> + </methodsynopsis> + <para> + This method is called when the stream is closed, using + <function>fclose</function>. You must release any resources + that were locked or allocated by the stream. + </para> + + <methodsynopsis> + <type>string</type><methodname>stream_read</methodname> + <methodparam><type>int</type><parameter>count</parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>fread</function> + and <function>fgets</function> calls on the stream. You + must return up-to <parameter>count</parameter> bytes of data + from the current read/write position as a string. + If there are less than <parameter>count</parameter> + bytes available, return as many as are available. If no + more data is available, return either &false; or an + empty string. + You must also update the read/write position of the stream + by the number of bytes that were successfully read. + </para> + + <methodsynopsis> + <type>int</type><methodname>stream_write</methodname> + <methodparam><type>string</type><parameter>data</parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>fwrite</function> + calls on the stream. You should store <parameter>data</parameter> + into the underlying storage used by your stream. If there is not + enough room, try to store as many bytes as possible. + You should return the number of bytes that were successfully + stored in the stream, or 0 if none could be stored. + You must also update the read/write position of the stream + by the number of bytes that were successfully written. + </para> + + <methodsynopsis> + <type>boolean</type><methodname>stream_eof</methodname> + <methodparam><type>void</type><parameter></parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>feof</function> + calls on the stream. You should return &true; if the read/write + position is at the end of the stream and if no more data is available + to be read, or &false; otherwise. + </para> + + <methodsynopsis> + <type>int</type><methodname>stream_tell</methodname> + <methodparam><type>void</type><parameter></parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>ftell</function> + calls on the stream. You should return the current read/write + position of the stream. + </para> + + <methodsynopsis> + <type>boolean</type><methodname>stream_seek</methodname> + <methodparam><type>int</type><parameter>offset</parameter></methodparam> + <methodparam><type>int</type><parameter>whence</parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>fseek</function> + calls on the stream. You should update the read/write position + of the stream according to <parameter>offset</parameter> and + <parameter>whence</parameter>. See <function>fseek</function> + for more information about these parameters. + Return &true; if the position was updated, &false; otherwise. + </para> + + <methodsynopsis> + <type>boolean</type><methodname>stream_flush</methodname> + <methodparam><type>void</type><parameter></parameter></methodparam> + </methodsynopsis> + <para> + This method is called in response to <function>fflush</function> + calls on the stream. If you have cached data in your stream + but not yet stored it into the underlying storage, you should + do so now. + Return &true; if the cached data was successfully stored (or + if there was no data to store), or &false; if the data could + not be stored. + </para> + + <para> + The example below implements a var:// protocol handler that + allows read/write access to a named global variable using + standard filesystem stream functions such as <function>fread</function>. + The var:// protocol implemented below, given the url + "var://foo" will read/write data to/from $GLOBALS["foo"]. + <example> - <title>Implementing a base64 encoding protocol</title> + <title>A Stream for reading/writing global variables</title> <programlisting role="php"> <![CDATA[ -class Base64EncodingStream { - var $fp = null; - +class VariableStream { + var $position; + var $varname; + function stream_open($path, $mode, $options, &$opened_path) { - $this->fp = fopen($path, $mode); - return is_resource($this->fp); - } - function stream_close() - { - fclose($this->fp); + $url = parse_url($path); + $this->varname = $split["host"]; + $this->position = 0; + + return true; } + function stream_read($count) { - return false; // We only allow writing + $ret = substr($GLOBALS[$this->varname], $this->position, $count); + $this->position += strlen($ret); + return $ret; } + function stream_write($data) { - return fwrite($this->fp, base64_encode($data)); - } - function stream_flush() - { - fflush($this->fp); - return true; - } - function stream_seek($offset, $whence) - { - return false; - } - function stream_gets() - { - return false; + $left = substr($GLOBALS[$this->varname], 0, $this->position); + $right = substr($GLOBALS[$this->varname], $this->position + strlen($data)); + $GLOBALS[$this->varname] = $left . $data . $right; + $this->position += strlen($data); + return strlen($data); } + function stream_tell() { - return false; + return $this->position; } + function stream_eof() { - return false; + return $this->position >= strlen($GLOBALS[$this->varname]); + } + + function stream_seek($offset, $whence) + { + switch($whence) { + case SEEK_SET: + if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) { + $this->position = $offset; + return true; + } else { + return false; + } + break; + + case SEEK_CUR: + if ($offset >= 0) { + $this->position += $offset; + return true; + } else { + return false; + } + break; + + case SEEK_END: + if (strlen($GLOBALS[$this->varname]) + $offset >= 0) { + $this->position = strlen($GLOBALS[$this->varname]) + $offset; + return true; + } else { + return false; + } + break; + + default: + return false; + } } } -file_register_wrapper("base64", "Base64EncodingStream") + +file_register_wrapper("var", "VariableStream") or die("Failed to register protocol"); -copy("/tmp/inputfile.txt", "base64:///tmp/outputfile.txt"); -readfile("/tmp/outputfile"); +$myvar = ""; + +$fp = fopen("var://myvar", "r+"); + +fwrite($fp, "line1\n"); +fwrite($fp, "line2\n"); +fwrite($fp, "line3\n"); + +rewind($fp); +while(!feof($fp)) { + echo fgets($fp) +} +fclose($fp); +var_dump($myvar); + ]]> </programlisting> </example> - </para> - <para> - <function>file_register_wrapper</function> will return &false; if the - <parameter>protocol</parameter> already has a handler, or if "fopen - wrappers" are disabled. - </para> - <note> - <para> - This function was introduced in PHP 4.3.0. - </para> - </note> + </refsect1> </refentry> + <!-- Keep this comment at the end of the file Local variables: