Stream_Var
[ class tree: Stream_Var ] [ index: Stream_Var ] [ all elements ]

Source for file Var.php

Documentation is available at Var.php

  1. <?PHP
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Stephan Schmidt <schst@php-tools.net>                       |
  17. // |          partly based on an exmple by Wez Furlong                    |
  18. // +----------------------------------------------------------------------+
  19. //
  20. //    $Id: Var.php 287139 2009-08-12 06:42:04Z cweiske $
  21.  
  22. /**
  23.  * stream is readable
  24.  * This depends on the mode, that is used for opening the stream
  25.  */
  26. define("STREAM_VAR_READABLE"1);
  27.  
  28. /**
  29.  * stream is writeable
  30.  * This depends on the mode, that is used for opening the stream
  31.  */
  32. define("STREAM_VAR_WRITEABLE"2);
  33.  
  34. /**
  35.  * Stream wrapper to access a variable
  36.  *
  37.  * Stream wrappers allow you to access any datasource using PHP's file manipulation functions
  38.  * like fopen(), fclose(), fseek(), ftell(),.. as well as directory functions like
  39.  * opendir() readdir() and closedir().
  40.  *
  41.  * This wrapper allows you to access any variable using these functions.
  42.  * You have to specify a scope (GLOBALS, _GET, _POST, etc.) as the host and
  43.  * the variable name as the path. If you want to access a string, that is
  44.  * stored in an array, you can use this array like you would use a directory.
  45.  *
  46.  * Usage:
  47.  * <code>
  48.  *  require_once '../Var.php';
  49.  *  stream_wrapper_register( "var", "Stream_Var" );
  50.  *
  51.  *  $fp = fopen('var://GLOBALS/myArray/index','r');
  52.  *  $data = fread($fp,100);
  53.  *  fclose($fp);
  54.  * </code>
  55.  *
  56.  * This wrapper also has support for dir functions, so it's possible to read any array, like
  57.  * you would read a directory. The following code will list all keys in an array.
  58.  * You could use fopen() to read the values for the keys.
  59.  *
  60.  * <code>
  61.  *  require_once '../Var.php';
  62.  *  stream_wrapper_register( "var", "Stream_Var" );
  63.  *
  64.  *  $dh = opendir('var://_SERVER');
  65.  *  while ($entry = readdir($dh)) {
  66.  *      echo $entry."<br />";
  67.  *  }
  68.  *  closedir($dh);
  69.  * </code>
  70.  *
  71.  * This wrapper allows you to replace files and directories with structures in
  72.  * memory in any application, that relies on filesystem functions. But keep in mind
  73.  * that variables are not persistent during several request, unless you write to
  74.  * var://SESSION.
  75.  * But this can be used to replace temporary files with variables.
  76.  *
  77.  * @category Stream
  78.  * @package  Stream_Var
  79.  * @version  0.2.1
  80.  * @author   Stephan Schmidt <schst@php-tools.net>
  81.  * @link     http://pear.php.net/package/Stream_Var
  82.  */
  83. class Stream_Var
  84. {
  85.  
  86.     /**
  87.     * pointer to the variable
  88.     *
  89.     * @var mixed $_pointer 
  90.     */
  91.     var $_pointer = null;
  92.  
  93.     /**
  94.     * flag to indicate whether stream is open
  95.     *
  96.     * @var boolean 
  97.     */
  98.     var $_open = false;
  99.  
  100.     /**
  101.     * position
  102.     *
  103.     * @var integer 
  104.     */
  105.     var $_pos = 0;
  106.  
  107.     /**
  108.     * mode of the opened file
  109.     *
  110.     * @var integer 
  111.     */
  112.     var $_mode = 0;
  113.  
  114.     /**
  115.     * Method used by fopen.
  116.     *
  117.     * @param string $path         Path to the variable
  118.     *                              (e.g. var://GLOBALS/myArray/anyIndex)
  119.     * @param string $mode         Mode to open the stream,
  120.     *                              like 'r', 'w,',... ({@see fopen()})
  121.     * @param array  $options      Options (not implemented yet)
  122.     * @param string &$opened_path This will be set to the actual opened path
  123.     *
  124.     * @return boolean $success
  125.     *
  126.     * @access public
  127.     */
  128.     function stream_open($path$mode$options&$opened_path)
  129.     {
  130.         $url parse_url($path);
  131.  
  132.         $scope   $url["host"];
  133.         $varpath substr($url["path"]1);
  134.         
  135.         $mode strtolower($mode);
  136.         switch ($mode{0}{
  137.         case    "r":
  138.             $status $this->_setPointer($scope$varpathfalse);
  139.             $this->_mode $this->_mode STREAM_VAR_READABLE;
  140.             break;
  141.         case    "w":
  142.         case    "a":
  143.             $status $this->_setPointer($scope$varpathtrue);
  144.             $this->_mode $this->_mode STREAM_VAR_WRITEABLE;
  145.             break;
  146.         case    "x":
  147.             $status $this->_setPointer($scope$varpathfalse);
  148.             if ($status{
  149.                 return false;
  150.             }
  151.             $status $this->_setPointer($scope$varpathtrue);
  152.             $this->_mode $this->_mode STREAM_VAR_WRITEABLE;
  153.             break;
  154.         }
  155.  
  156.         if (!$status{
  157.             return  false;
  158.         }
  159.         
  160.         if (!is_scalar($this->_pointer)) {
  161.             return false;
  162.         }
  163.  
  164.         // start at zero
  165.         $this->_pos = 0;
  166.         $this->_open = true;
  167.         $opened_path $path;
  168.  
  169.         if ($mode{0== 'a'{
  170.             $this->stream_seek(0SEEK_END);
  171.         }
  172.  
  173.         if (strlen($mode> 1 && $mode{1== '+'{
  174.             $this->_mode $this->_mode STREAM_VAR_READABLE | STREAM_VAR_WRITEABLE;
  175.         }
  176.  
  177.         return true;
  178.     }
  179.  
  180.     /**
  181.     * Check for end of stream.
  182.     *
  183.     * @return boolean True if at end of stream
  184.     *
  185.     * @access public
  186.     */
  187.     function stream_eof()
  188.     {
  189.         return ($this->_pos >= strlen($this->_pointer));
  190.     }
  191.  
  192.     /**
  193.     * Return the current position.
  194.     *
  195.     * @return integer Current position in stream
  196.     *
  197.     * @access public
  198.     */
  199.     function stream_tell()
  200.     {
  201.         return $this->_pos;
  202.     }
  203.  
  204.     /**
  205.     * Close the stream.
  206.     *
  207.     * @return void 
  208.     *
  209.     * @access public
  210.     */
  211.     function stream_close()
  212.     {
  213.         $this->_pos  = 0;
  214.         $this->_open = false;
  215.     }
  216.  
  217.     /**
  218.     * Read from the stream.
  219.     *
  220.     * @param integer $count Amount of bytes to read
  221.     *
  222.     * @return string $data Data that has been read
  223.     *
  224.     * @access public
  225.     */
  226.     function stream_read($count)
  227.     {
  228.         if (!$this->_open{
  229.             return false;
  230.         }
  231.  
  232.         if (!($this->_mode STREAM_VAR_READABLE)) {
  233.             return false;
  234.         }
  235.  
  236.         $data substr($this->_pointer$this->_pos$count);
  237.         $this->_pos $this->_pos strlen($data);
  238.         return $data;
  239.     }
  240.  
  241.     /**
  242.     * write to the stream.
  243.     *
  244.     * @param mixed $data Data to write
  245.     *
  246.     * @return integer Number of bytes that were written
  247.     *
  248.     * @access public
  249.     */
  250.     function stream_write($data)
  251.     {
  252.         if (!$this->_open{
  253.             return false;
  254.         }
  255.         
  256.         if (!($this->_mode STREAM_VAR_WRITEABLE)) {
  257.             return false;
  258.         }
  259.         
  260.         $datalen strlen($data);
  261.        
  262.         $this->_pointer substr($this->_pointer0$this->_pos)
  263.             . $data
  264.             . substr($this->_pointer$this->_pos+$datalen);
  265.  
  266.         $this->_pos $this->_pos $datalen;
  267.         return $datalen;
  268.     }
  269.  
  270.     /**
  271.     * Move the position in the stream.
  272.     *
  273.     * @param integer $offset Offset
  274.     * @param integer $whence Point from which the offset
  275.     *                         should be calculated
  276.     *
  277.     * @return boolean True if the position could be reached
  278.     *
  279.     * @access public
  280.     */
  281.     function stream_seek($offset$whence)
  282.     {
  283.         switch ($whence{
  284.         //  from start
  285.         case SEEK_SET:
  286.             if ($offset strlen($this->_pointer&& $offset >= 0{
  287.                 $this->_pos $offset;
  288.                 return true;
  289.             else {
  290.                 return false;
  291.             }
  292.             break;
  293.         // from current position
  294.         case SEEK_CUR:
  295.             if ($offset >= 0{
  296.                 $this->_pos += $offset;
  297.                 return true;
  298.             else {
  299.                 return false;
  300.             }
  301.             break;
  302.         // from the end
  303.         case SEEK_END:
  304.             if (strlen($this->_pointer$offset >= 0{
  305.                 $this->_pos strlen($this->_pointer$offset;
  306.                 return true;
  307.             else {
  308.                 return false;
  309.             }
  310.             break;
  311.         default:
  312.             return false;
  313.         }
  314.     }
  315.  
  316.     /**
  317.     * Write all data to storage.
  318.     *
  319.     * @return boolean Always true
  320.     *
  321.     * @access public
  322.     */
  323.     function stream_flush()
  324.     {
  325.         return true;
  326.     }
  327.  
  328.     /**
  329.     * Return information about the stream.
  330.     *
  331.     * @access public
  332.     * @return array $stat Information about the stream
  333.     *                      (currently only the length is included)
  334.     */
  335.     function stream_stat()
  336.     {
  337.         $stat = array(
  338.             'size' => strlen($this->_pointer)
  339.         );
  340.         return $stat;
  341.     }
  342.  
  343.     /**
  344.      * This method is called in response to stat() calls on the URL paths
  345.      * 
  346.      * As taken from the PHP Manual:
  347.      * 
  348.      * "This method is called in response to stat()  calls on the URL paths
  349.      * associated with the wrapper and should return as many elements in
  350.      * common with the system function as possible. Unknown or unavailable
  351.      * values should be set to a rational value (usually 0)."
  352.      * 
  353.      * With regards to the implementation that is Stream_Var we can actually fake
  354.      * some of the data. For instance, the uid and gid can be that of the corrent
  355.      * posix_getuid and posix_getgid()
  356.      * 
  357.      * The following outlines the information that we essentially fake:
  358.      * 
  359.      * - 'dev': is unknown and set to 0
  360.      * - 'ino': is unknown and set to 0
  361.      * - 'mode': set to 33216 (chmod 700 means user has read,
  362.      *    write and execute on the file)
  363.      * - 'nlink': is unknown and set to 0
  364.      * - 'uid': if the method posix_getuid exist, this is called,
  365.      *    otherwise 0 is returned
  366.      * - 'gid': if the method posix_getgid exist, this is called,
  367.      *    otherwise 0 is returned
  368.      * - 'rdev' unknown and set to 0
  369.      * - 'size': is set to the strlen of the pointer.
  370.      * - 'atime': set to current value returned by time()
  371.      * - 'mtime': set to current value returned by time()
  372.      * - 'ctime': set to current value returned by time()
  373.      * - 'blksize': is unknown and set to 0
  374.      * - 'blocks': is unknown and set to 0
  375.      * 
  376.      * @param string  $path  The path to stat.
  377.      * @param integer $flags Holds additional flags set by the streams API.
  378.      *                        It can hold one or more of the following values
  379.      *                        OR'd together.
  380.      *                        - STREAM_URL_STAT_LINK - currently this is
  381.      *                          ignored.
  382.      *                        - STREAM_URL_STAT_QUIET - makes call to
  383.      *                          strlen quiet
  384.      * 
  385.      * @return array 
  386.      * 
  387.      * @see http://au.php.net/stream_wrapper_register
  388.      * @author Alex Hayes <ahayes@wcg.net.au>
  389.      */
  390.     function url_stat($path$flags)
  391.     {
  392.         $time time();
  393.         $keys = array(
  394.             'dev'     => 0,
  395.             'ino'     => 0,
  396.             // chmod 700 means user has read, write and execute on the file
  397.             'mode'    => 33216,
  398.             'nlink'   => 0,
  399.             //this processes uid
  400.             'uid'     => function_exists('posix_getuid'posix_getuid(: 0,
  401.             //this processes gid
  402.             'gid'     => function_exists('posix_getgid'posix_getgid(: 0
  403.             'rdev'    => 0,
  404.             'size'    => $flags STREAM_URL_STAT_QUIET
  405.                 ? @strlen($this->_pointerstrlen($this->_pointer),
  406.             'atime'   => $time,
  407.             'mtime'   => $time,
  408.             'ctime'   => $time,
  409.             'blksize' => 0,
  410.             'blocks'  => 0
  411.         );
  412.  
  413.         return array_merge(array_values($keys)$keys);
  414.     }
  415.  
  416.     /**
  417.     * Open 'directory'
  418.     *
  419.     * @param string $path    Path to the array (i.e. the directory)
  420.     * @param array  $options Not implemented, yet.
  421.     *
  422.     * @return boolean $success
  423.     *
  424.     * @access public
  425.     */
  426.     function dir_opendir($path$options)
  427.     {
  428.         $url parse_url($path);
  429.  
  430.         $scope   $url['host'];
  431.         if (isset($url['path'])) {
  432.             $varpath substr($url['path']1);
  433.         else {
  434.             $varpath '';
  435.         }
  436.         
  437.         if (!$status $this->_setPointer($scope$varpath)) {
  438.             return false;
  439.         }
  440.  
  441.         if (!is_array($this->_pointer)) {
  442.             return false;
  443.         }
  444.         reset($this->_pointer);
  445.         $this->_open = true;
  446.         return true;
  447.     }
  448.  
  449.  
  450.     /**
  451.     * Close 'directory'
  452.     *
  453.     * @return boolean $success
  454.     *
  455.     * @access public
  456.     */
  457.     function dir_closedir()
  458.     {
  459.         $this->_open = false;
  460.         return true;
  461.     }
  462.  
  463.     /**
  464.     * Rewind 'directory'
  465.     *
  466.     * @return boolean $success
  467.     *
  468.     * @access public
  469.     */
  470.     function dir_rewinddir()
  471.     {
  472.         if (!$this->_open{
  473.             return false;
  474.         }
  475.         reset($this->_pointer);
  476.         return true;
  477.     }
  478.  
  479.     /**
  480.     * Read one entry from 'directory'
  481.     *
  482.     * @return mixed $entry Entry that has been read, or
  483.     *                       false if there are no entries left
  484.     *
  485.     * @access public
  486.     */
  487.     function dir_readdir()
  488.     {
  489.         if (!$this->_open{
  490.             return false;
  491.         }
  492.         if (current($this->_pointer== count($this->_pointer- 1{
  493.             return false;
  494.         }
  495.         list($keyeach($this->_pointer);
  496.         return $key;
  497.     }
  498.  
  499.     /**
  500.     * Set the internal pointer
  501.     *
  502.     * Basically this method only sets the object property _pointer
  503.     * as a reference to a variable
  504.     *
  505.     * @param string  $scope  Scope of the variable: GLOBAL, GET,
  506.     *                         POST, COOKIE, SESSION, SERVER, ENV
  507.     * @param string  $path   Path to the variable. Array indices
  508.     *                         are seperated by a slash
  509.     * @param boolean $create Create the variable, if it does not exist
  510.     *
  511.     * @return boolean true if the pointer was set, false if not found
  512.     *
  513.     * @access private
  514.     */
  515.     function _setPointer($scope$path$create = false)
  516.     {
  517.         $varpath explode('/'$path);
  518.  
  519.         switch (strtoupper($scope)) {
  520.         // GET variables
  521.         case 'GET':
  522.         case '_GET':
  523.             $this->_pointer &$_GET;
  524.             break;
  525.  
  526.         // POST variables
  527.         case 'POST':
  528.         case '_POST':
  529.             $this->_pointer &$_POST;
  530.             break;
  531.  
  532.         // SERVER variables
  533.         case 'SERVER':
  534.         case '_SERVER':
  535.             $this->_pointer &$_SERVER;
  536.             break;
  537.  
  538.         // SESSION variables
  539.         case 'SESSION':
  540.         case '_SESSION':
  541.             $this->_pointer &$_SESSION;
  542.             break;
  543.  
  544.         // COOKIE variables
  545.         case 'COOKIE':
  546.         case '_COOKIE':
  547.             $this->_pointer &$_COOKIE;
  548.             break;
  549.  
  550.         // ENV variables
  551.         case 'ENV':
  552.         case '_ENV':
  553.             $this->_pointer &$_ENV;
  554.             break;
  555.  
  556.         // global variables
  557.         case 'GLOBALS':
  558.         default:
  559.             $this->_pointer &$GLOBALS;
  560.             break;
  561.         }
  562.         if (empty($varpath)) {
  563.             return true;
  564.         }
  565.  
  566.         while ($part array_shift($varpath)) {
  567.             if (!isset($this->_pointer[$part])) {
  568.                 if (!$create{
  569.                     return false;
  570.                 }
  571.                 if (!empty($varpath)) {
  572.                     return false;
  573.                 }
  574.                 $this->_pointer[$part'';
  575.             }
  576.             $this->_pointer &$this->_pointer[$part];
  577.         }        
  578.         return true;
  579.     }
  580. }
  581. ?>

Documentation generated on Mon, 11 Mar 2019 15:32:46 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.