home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / File.php < prev    next >
Encoding:
PHP Script  |  2005-09-26  |  16.1 KB  |  535 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * File
  6.  * 
  7.  * PHP versions 4 and 5
  8.  *
  9.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  10.  * that is available through the world-wide-web at the following URI:
  11.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  12.  * the PHP License and are unable to obtain it through the web, please
  13.  * send a note to license@php.net so we can mail you a copy immediately.
  14.  *
  15.  * @category    File
  16.  * @package     File
  17.  * @author      Richard Heyes <richard@php.net>
  18.  * @author      Tal Peer <tal@php.net>
  19.  * @author      Michael Wallner <mike@php.net>
  20.  * @copyright   2002-2005 The Authors
  21.  * @license     http://www.php.net/license/3_0.txt  PHP License 3.0
  22.  * @version     CVS: $Id: File.php,v 1.31 2005/07/21 07:53:09 mike Exp $
  23.  * @link        http://pear.php.net/package/File
  24.  */
  25.  
  26. /**
  27.  * Requires PEAR
  28.  */
  29. require_once 'PEAR.php';
  30.  
  31. /**
  32.  * The default number of bytes for reading
  33.  */
  34. if (!defined('FILE_DEFAULT_READSIZE')) {
  35.     define('FILE_DEFAULT_READSIZE', 1024, true);
  36. }
  37.  
  38. /**
  39.  * The maximum number of bytes for reading lines
  40.  */
  41. if (!defined('FILE_MAX_LINE_READSIZE')) {
  42.     define('FILE_MAX_LINE_READSIZE', 40960, true);
  43. }
  44.  
  45. /**
  46.  * Whether file locks should block
  47.  */
  48. if (!defined('FILE_LOCKS_BLOCK')) {
  49.     define('FILE_LOCKS_BLOCK', true, true);
  50. }
  51.  
  52. /**
  53.  * Mode to use for reading from files
  54.  */
  55. define('FILE_MODE_READ', 'rb', true);
  56.  
  57. /**
  58.  * Mode to use for truncating files, then writing
  59.  */
  60. define('FILE_MODE_WRITE', 'wb', true);
  61.  
  62. /**
  63.  * Mode to use for appending to files
  64.  */
  65. define('FILE_MODE_APPEND', 'ab', true);
  66.  
  67. /**
  68.  * Use this when a shared (read) lock is required
  69.  */
  70. define('FILE_LOCK_SHARED', LOCK_SH | (FILE_LOCKS_BLOCK ? 0 : LOCK_NB), true);
  71.  
  72. /**
  73.  * Use this when an exclusive (write) lock is required
  74.  */
  75. define('FILE_LOCK_EXCLUSIVE', LOCK_EX | (FILE_LOCKS_BLOCK ? 0 : LOCK_NB), true);
  76.  
  77. /**
  78.  * Class for handling files
  79.  * 
  80.  * A class with common functions for writing,
  81.  * reading and handling files and directories
  82.  * 
  83.  * @author  Richard Heyes <richard@php.net>
  84.  * @author  Tal Peer <tal@php.net>
  85.  * @author  Michael Wallner <mike@php.net>
  86.  * @access  public 
  87.  * @package File
  88.  * 
  89.  * @static
  90.  */
  91. class File extends PEAR 
  92. {
  93.     /**
  94.      * Destructor
  95.      * 
  96.      * Unlocks any locked file pointers and closes all filepointers
  97.      * 
  98.      * @access private 
  99.      */
  100.     function _File()
  101.     {
  102.         File::closeAll();
  103.     }
  104.     
  105.     /**
  106.      * Handles file pointers. If a file pointer needs to be opened,
  107.      * it will be. If it already exists (based on filename and mode)
  108.      * then the existing one will be returned.
  109.      * 
  110.      * @access  private 
  111.      * @param   string  $filename Filename to be used
  112.      * @param   string  $mode Mode to open the file in
  113.      * @param   mixed   $lock Type of lock to use
  114.      * @return  mixed   PEAR_Error on error or file pointer resource on success
  115.      */
  116.     function &_getFilePointer($filename, $mode, $lock = false)
  117.     {
  118.         $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
  119.         
  120.         // Win32 is case-insensitive
  121.         if (OS_WINDOWS) {
  122.             $filename = strToLower($filename);
  123.         }
  124.         
  125.         // check if file pointer already exists
  126.         if (    !isset($filePointers[$filename][$mode]) || 
  127.                 !is_resource($filePointers[$filename][$mode])) {
  128.             
  129.             // check if we can open the file in the desired mode
  130.             switch ($mode)
  131.             {
  132.                 case FILE_MODE_READ:
  133.                     if (    !preg_match('/^.+(?<!file):\/\//i', $filename) &&
  134.                             !file_exists($filename)) {
  135.                         return PEAR::raiseError("File does not exist: $filename");
  136.                     }
  137.                 break;
  138.                 
  139.                 case FILE_MODE_APPEND:
  140.                 case FILE_MODE_WRITE:
  141.                     if (file_exists($filename)) {
  142.                         if (!is_writable($filename)) {
  143.                             return PEAR::raiseError("File is not writable: $filename");
  144.                         }
  145.                     } elseif (!is_writable($dir = dirname($filename))) {
  146.                         return PEAR::raiseError("Cannot create file in directory: $dir");
  147.                     }
  148.                 break;
  149.                 
  150.                 default:
  151.                     return PEAR::raiseError("Invalid access mode: $mode");
  152.             }
  153.             
  154.             // open file
  155.             $filePointers[$filename][$mode] = @fopen($filename, $mode);
  156.             if (!is_resource($filePointers[$filename][$mode])) {
  157.                 return PEAR::raiseError('Failed to open file: ' . $filename);
  158.             }
  159.         }
  160.         
  161.         // lock file
  162.         if ($lock) {
  163.             $lock = $mode == FILE_MODE_READ ? FILE_LOCK_SHARED : FILE_LOCK_EXCLUSIVE;
  164.             $locks = &PEAR::getStaticProperty('File', 'locks');
  165.             if (@flock($filePointers[$filename][$mode], $lock)) {
  166.                 $locks[] = &$filePointers[$filename][$mode];
  167.             } elseif (FILE_LOCKS_BLOCK) {
  168.                 return PEAR::raiseError("File already locked: $filename");
  169.             } else {
  170.                 return PEAR::raiseError("Could not lock file: $filename");
  171.             }
  172.         }
  173.         
  174.         return $filePointers[$filename][$mode];
  175.     } 
  176.  
  177.     /**
  178.      * Reads an entire file and returns it.
  179.      * Uses file_get_contents if available.
  180.      * 
  181.      * @access  public 
  182.      * @param   string  $filename Name of file to read from
  183.      * @param   mixed   $lock Type of lock to use
  184.      * @return  mixed   PEAR_Error if an error has occured or a string with the contents of the the file
  185.      */
  186.     function readAll($filename, $lock = false)
  187.     {
  188.         if (function_exists('file_get_contents')) {
  189.             if (false === $file = @file_get_contents($filename)) {
  190.                 return PEAR::raiseError("Cannot read file: $filename");
  191.             }
  192.             return $file;
  193.         }
  194.         
  195.         $file = '';
  196.         while (false !== $buf = File::read($filename, FILE_DEFAULT_READSIZE, $lock)) {
  197.             if (PEAR::isError($buf)) {
  198.                 return $buf;
  199.             }
  200.             $file .= $buf;
  201.         }
  202.         
  203.         // close the file pointer
  204.         File::close($filename, FILE_MODE_READ);
  205.         
  206.         return $file;
  207.     }
  208.  
  209.     /**
  210.      * Returns a specified number of bytes of a file. 
  211.      * Defaults to FILE_DEFAULT_READSIZE.  If $size is 0, all file will be read.
  212.      * 
  213.      * @access  public 
  214.      * @param   string  $filename Name of file to read from
  215.      * @param   integer $size Bytes to read
  216.      * @param   mixed   $lock Type of lock to use
  217.      * @return  mixed   PEAR_Error on error or a string which contains the data read
  218.      *                  Will also return false upon EOF
  219.      */
  220.     function read($filename, $size = FILE_DEFAULT_READSIZE, $lock = false)
  221.     {
  222.         static $filePointers;
  223.         
  224.         if (0 == $size) {
  225.             return File::readAll($filename, $lock);
  226.         } 
  227.  
  228.         if (    !isset($filePointers[$filename]) || 
  229.                 !is_resource($filePointers[$filename])) {
  230.             if (PEAR::isError($fp = &File::_getFilePointer($filename, FILE_MODE_READ, $lock))) {
  231.                 return $fp;
  232.             } 
  233.  
  234.             $filePointers[$filename] = &$fp;
  235.         } else {
  236.             $fp = &$filePointers[$filename];
  237.         } 
  238.  
  239.         return !feof($fp) ? fread($fp, $size) : false;
  240.     } 
  241.  
  242.     /**
  243.      * Writes the given data to the given filename. 
  244.      * Defaults to no lock, append mode.
  245.      * 
  246.      * @access  public 
  247.      * @param   string  $filename Name of file to write to
  248.      * @param   string  $data Data to write to file
  249.      * @param   string  $mode Mode to open file in
  250.      * @param   mixed   $lock Type of lock to use
  251.      * @return  mixed   PEAR_Error on error or number of bytes written to file.
  252.      */
  253.     function write($filename, $data, $mode = FILE_MODE_APPEND, $lock = false)
  254.     {
  255.         if (PEAR::isError($fp = &File::_getFilePointer($filename, $mode, $lock))) {
  256.             return $fp;
  257.         }
  258.         if (-1 === $bytes = @fwrite($fp, $data, strlen($data))) {
  259.             return PEAR::raiseError("Cannot write data: '$data' to file: '$filename'");
  260.         }
  261.         return $bytes;
  262.     } 
  263.  
  264.     /**
  265.      * Reads and returns a single character from given filename
  266.      * 
  267.      * @access  public 
  268.      * @param   string  $filename Name of file to read from
  269.      * @param   mixed   $lock Type of lock to use
  270.      * @return  mixed   PEAR_Error on error or one character of the specified file
  271.      */
  272.     function readChar($filename, $lock = false)
  273.     {
  274.         return File::read($filename, 1, $lock);
  275.     } 
  276.  
  277.     /**
  278.      * Writes a single character to a file
  279.      * 
  280.      * @access  public 
  281.      * @param   string  $filename Name of file to write to
  282.      * @param   string  $char Character to write
  283.      * @param   string  $mode Mode to use when writing
  284.      * @param   mixed   $lock Type of lock to use
  285.      * @return  mixed   PEAR_Error on error, or 1 on success
  286.      */
  287.     function writeChar($filename, $char, $mode = FILE_MODE_APPEND, $lock = false)
  288.     {
  289.         if (PEAR::isError($fp = &File::_getFilePointer($filename, $mode, $lock))) {
  290.             return $fp;
  291.         }
  292.         if (-1 === @fwrite($fp, $char, 1)) {
  293.             return PEAR::raiseError("Cannot write data: '$data' to file: '$filename'");
  294.         }
  295.         return 1;
  296.     } 
  297.  
  298.     /**
  299.      * Returns a line of the file (without trailing CRLF).
  300.      * Maximum read line length is FILE_MAX_LINE_READSIZE.
  301.      * 
  302.      * @access  public 
  303.      * @param   string  $filename Name of file to read from
  304.      * @param   boolean $lock Whether file should be locked
  305.      * @return  mixed   PEAR_Error on error or a string containing the line read from file
  306.      */
  307.     function readLine($filename, $lock = false)
  308.     {
  309.         static $filePointers; // Used to prevent unnecessary calls to _getFilePointer()
  310.         
  311.         if (    !isset($filePointers[$filename]) || 
  312.                 !is_resource($filePointers[$filename])) {
  313.             if (PEAR::isError($fp = &File::_getFilePointer($filename, FILE_MODE_READ, $lock))) {
  314.                 return $fp;
  315.             } 
  316.  
  317.             $filePointers[$filename] = &$fp;
  318.         } else {
  319.             $fp = &$filePointers[$filename];
  320.         } 
  321.  
  322.         if (feof($fp)) {
  323.             return false;
  324.         } 
  325.         
  326.         return rtrim(fgets($fp, FILE_MAX_LINE_READSIZE), "\r\n");
  327.     } 
  328.  
  329.     /**
  330.      * Writes a single line, appending a LF (by default)
  331.      * 
  332.      * @access  public 
  333.      * @param   string  $filename Name of file to write to
  334.      * @param   string  $line Line of data to be written to file
  335.      * @param   string  $mode Write mode, can be either FILE_MODE_WRITE or FILE_MODE_APPEND
  336.      * @param   string  $crlf The CRLF your system is using. UNIX = \n Windows = \r\n Mac = \r
  337.      * @param   mixed   $lock Whether to lock the file
  338.      * @return  mixed   PEAR_Error on error or number of bytes written to file (including appended crlf)
  339.      */
  340.     function writeLine($filename, $line, $mode = FILE_MODE_APPEND, $crlf = "\n", $lock = false)
  341.     {
  342.         if (PEAR::isError($fp = &File::_getFilePointer($filename, $mode, $lock))) {
  343.             return $fp;
  344.         }
  345.         if (-1 === $bytes = fwrite($fp, $line . $crlf)) {
  346.             return PEAR::raiseError("Cannot write data: '$data' to file: '$file'");
  347.         }
  348.         return $bytes;
  349.     } 
  350.  
  351.     /**
  352.      * This rewinds a filepointer to the start of a file
  353.      * 
  354.      * @access  public 
  355.      * @param   string  $filename The filename
  356.      * @param   string  $mode Mode the file was opened in
  357.      * @return  mixed   PEAR Error on error, true on success
  358.      */
  359.     function rewind($filename, $mode)
  360.     {
  361.         if (PEAR::isError($fp = &File::_getFilePointer($filename, $mode))) {
  362.             return $fp;
  363.         }
  364.         if (!@rewind($fp)) {
  365.             return PEAR::raiseError("Cannot rewind file: $filename");
  366.         }
  367.         return true;
  368.     } 
  369.  
  370.     /**
  371.      * Closes all open file pointers
  372.      * 
  373.      * @access  public
  374.      * @return  void
  375.      */
  376.     function closeAll()
  377.     {
  378.         $locks = &PEAR::getStaticProperty('File', 'locks');
  379.         $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
  380.         
  381.         // unlock files
  382.         for ($i = 0, $c = count($locks); $i < $c; $i++) {
  383.             is_resource($locks[$i]) and @flock($locks[$i], LOCK_UN);
  384.         }
  385.         
  386.         // close files
  387.         if (!empty($filePointers)) {
  388.             foreach ($filePointers as $fname => $modes) {
  389.                 foreach (array_keys($modes) as $mode) {
  390.                     if (is_resource($filePointers[$fname][$mode])) {
  391.                         @fclose($filePointers[$fname][$mode]);
  392.                     }
  393.                     unset($filePointers[$fname][$mode]);
  394.                 }
  395.             }
  396.         }
  397.     }
  398.     
  399.     /**
  400.      * This closes an open file pointer
  401.      * 
  402.      * @access  public 
  403.      * @param   string  $filename The filename that was opened
  404.      * @param   string  $mode Mode the file was opened in
  405.      * @return  mixed   PEAR Error on error, true otherwise
  406.      */
  407.     function close($filename, $mode)
  408.     {
  409.         $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
  410.         
  411.         if (OS_WINDOWS) {
  412.             $filename = strToLower($filename);
  413.         }
  414.         if (!isset($filePointers[$filename][$mode])) {
  415.             return true;
  416.         }
  417.         
  418.         $fp = $filePointers[$filename][$mode];
  419.         unset($filePointers[$filename][$mode]);
  420.         
  421.         if (is_resource($fp)) {
  422.             // unlock file
  423.             @flock($fp, LOCK_UN);
  424.             // close file
  425.             if (!@fclose($fp)) {
  426.                 return PEAR::raiseError("Cannot close file: $filename");
  427.             }
  428.         }
  429.         
  430.         return true;
  431.     } 
  432.  
  433.     /**
  434.      * This unlocks a locked file pointer.
  435.      * 
  436.      * @access  public 
  437.      * @param   string  $filename The filename that was opened
  438.      * @param   string  $mode Mode the file was opened in
  439.      * @return  mixed   PEAR Error on error, true otherwise
  440.      */
  441.     function unlock($filename, $mode)
  442.     {
  443.         if (PEAR::isError($fp = &File::_getFilePointer($filename, $mode))) {
  444.             return $fp;
  445.         }
  446.         if (!@flock($fp, LOCK_UN)) {
  447.             return PEAR::raiseError("Cacnnot unlock file: $filename");
  448.         }
  449.         return true;
  450.     } 
  451.  
  452.     /**
  453.      * @deprecated
  454.      */
  455.     function stripTrailingSeparators($path, $separator = DIRECTORY_SEPARATOR)
  456.     {
  457.         return rtrim($path, $separator);
  458.     } 
  459.  
  460.     /**
  461.      * @deprecated
  462.      */
  463.     function stripLeadingSeparators($path, $separator = DIRECTORY_SEPARATOR)
  464.     {
  465.         return ltrim($path, $separator);
  466.     } 
  467.  
  468.     /**
  469.      * @deprecated      Use File_Util::buildPath() instead.
  470.      */
  471.     function buildPath($parts, $separator = DIRECTORY_SEPARATOR)
  472.     {
  473.         require_once 'File/Util.php';
  474.         return File_Util::buildPath($parts, $separator);
  475.     } 
  476.  
  477.     /**
  478.      * @deprecated      Use File_Util::skipRoot() instead.
  479.      */
  480.     function skipRoot($path)
  481.     {
  482.         require_once 'File/Util.php';
  483.         return File_Util::skipRoot($path);
  484.     } 
  485.  
  486.     /**
  487.      * @deprecated      Use File_Util::tmpDir() instead.
  488.      */
  489.     function getTempDir()
  490.     {
  491.         require_once 'File/Util.php';
  492.         return File_Util::tmpDir();
  493.     }
  494.  
  495.     /**
  496.      * @deprecated      Use File_Util::tmpFile() instead.
  497.      */
  498.     function getTempFile($dirname = null)
  499.     {
  500.         require_once 'File/Util.php';
  501.         return File_Util::tmpFile($dirname);
  502.     } 
  503.  
  504.     /**
  505.      * @deprecated      Use File_Util::isAbsolute() instead.
  506.      */
  507.     function isAbsolute($path)
  508.     {
  509.         require_once 'File/Util.php';
  510.         return File_Util::isAbsolute($path);
  511.     } 
  512.  
  513.     /**
  514.      * @deprecated      Use File_Util::relativePath() instead.
  515.      */
  516.     function relativePath($path, $root, $separator = DIRECTORY_SEPARATOR)
  517.     {
  518.         require_once 'File/Util.php';
  519.         return File_Util::relativePath($path, $root, $separator);
  520.     }
  521.  
  522.     /**
  523.      * @deprecated      Use File_Util::realpath() instead.
  524.      */
  525.     function realpath($path, $separator = DIRECTORY_SEPARATOR)
  526.     {
  527.         require_once 'File/Util.php';
  528.         return File_Util::realpath($path, $separator);
  529.     }
  530. }
  531.  
  532. PEAR::registerShutdownFunc(array('File', '_File'));
  533.  
  534. ?>
  535.