Fwd: another suggestion for File.php

From: Date: Fri, 05 Apr 2002 10:43:22 +0000
Subject: Fwd: another suggestion for File.php
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-5197@lists.php.net to get a copy of this message
From: Dan Allen <dan@mojavelinux.com> To: tal@php.net Subject: another suggestion for File.php Date: Thu, 4 Apr 2002 19:21:54 -0800 MIME-Version: 1.0 Received: from [208.210.50.160] by hotmail.com (3.2) with ESMTP id MHotMailBE766350003D40043793D0D232A00CCF0; Thu, 04 Apr 2002 19:21:52 -0800 Received: (qmail 32034 invoked by alias); 5 Apr 2002 03:21:52 -0000 Received: (qmail 32027 invoked from network); 5 Apr 2002 03:21:51 -0000 Received: from unknown (HELO yebo.zinkwazi.com) (63.147.60.69) by php.chek.com with SMTP; 5 Apr 2002 03:21:51 -0000 Received: (from mojavelinux@localhost)by yebo.zinkwazi.com (8.11.6/8.11.6) id g353Lsw02220for tal@php.net; Thu, 4 Apr 2002 19:21:54 -0800 From dan@mojavelinux.com Thu, 04 Apr 2002 19:22:08 -0800 Delivered-To: tal@php.net Message-ID: <20020404192154.A2173@mojavelinux.com> User-Agent: Mutt/1.2.5.1i In order to have several functions access the same static varibles, I came up with an idea of having a function called propertySingleton and it allows you to get the value of a static variable when using the class methods without a class object, such as File::readLine() The method is like this: /** * Emulate the class property so that it can be used without instantiating a class * */ function &propertySingleton($name, $type = null) { static $properties; if (!isset($properties)) { $properties = array(); } if (isset($this)) { $return = &$this->$name; } else { $return = &$properties[$name]; } if ($type) { settype($return, $type); } return $return; } This way you can have a File::rewind() and a File::close() method and still access the static variable filePointers from the File::_getFilePointers functions. Here is a copy of my modified File.php file. As a side note, doesn't it make sense to prefix all private methods with an underscore. In Fie.php it is mixed. Dan -- "I'm old enough to know better, but still to young to care." _________________________________________________________________ Join the world’s largest e-mail service with MSN Hotmail. http://www.hotmail.com

<?php // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2002 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Richard Heyes <richard@php.net> | // | Tal Peer <tal@php.net> | // +----------------------------------------------------------------------+ /** * Class for handling files * * A class with common functions for writing, * reading and handling files and directories * * @author Richard Heyes <richard@php.net> * @author Tal Peer <tal@php.net> * @access public * @version 0.9 * @package File */ require_once('PEAR.php'); /** * The default number of bytes for reading * @const FILE_DEFAULT_READSIZE */ define('FILE_DEFAULT_READSIZE', 1024, true); /** * Mode to use for reading from files * @const FILE_MODE_READ */ define('FILE_MODE_READ', 'rb', true); /** * Mode to use for truncating files, then writing * @const FILE_MODE_WRITE */ define('FILE_MODE_WRITE', 'wb', true); /** * Mode to use for appending to files * @const FILE_MODE_APPEND */ define('FILE_MODE_APPEND', 'ab', true); /** * Use this when a shared (read) lock is required * @const FILE_LOCK_SHARED */ define('FILE_LOCK_SHARED', LOCK_SH, true); /** * Use this when an exclusive (write) lock is required * @const FILE_LOCK_EXCLUSIVE */ define('FILE_LOCK_EXCLUSIVE', LOCK_EX, true); class File extends PEAR { /** * Array of filepointers * @var array $filePointers */ var $filePointers; /** * Array of references to locked filepointers * @var array $locks */ var $locks; /** * Constructor * @access public */ function File() { $this->PEAR(); $this->filePointers = array(); $this->locks = array(); } /** * Destructor * * Unlocks any locked file pointers * @access public */ function _File() { for($i=0; $i<count($this->locks); $i++){ flock($this->locks[$i], LOCK_UN); } } /** * Emulate the class property so that it can be used without instantiating a class * */ function &propertySingleton($name, $type = null) { static $properties; if (!isset($properties)) { $properties = array(); } if (isset($this)) { $return = &$this->$name; } else { $return = &$properties[$name]; } if ($type) { settype($return, $type); } return $return; } /** * Handles file pointers. If a file pointer needs to be opened, * it will be. If it already exists (based on filename and mode) * then the existing one will be returned. * * @access private * @param string $filename Filename to be used * @param string $mode Mode to open the file in * @param mixed $lock Type of lock to use * @return mixed PEAR_Error on error and file pointer resource on success */ function &_getFilePointer($filename, $mode, $lock = false) { $filePointers =& File::propertySingleton('filePointers', 'array'); if (!isset($filePointers[$filename][$mode]) OR !is_resource($filePointers[$filename][$mode])) { $filePointers[$filename][$mode] = @fopen($filename, $mode); if (false === $filePointers[$filename][$mode]) { return new PEAR_Error('Failed to open file: ' . $filename); } } if ($lock) { if (flock($filePointers[$filename][$mode], $lock)) { $this->locks[] = &$filePointers[$filename][$mode]; } } return $filePointers[$filename][$mode]; } /** * Reads an entire file and returns it. * * @access public * @param string $filename Name of file to read from * @param mixed $lock Type of lock to use * @return mixed PEAR_Error if an error has occured or a string with the contents of the the file */ function readAll($filename, $lock = false) { $file = ''; while (($tmp = File::read($filename, FILE_DEFAULT_READSIZE, $lock)) !== FALSE) { if (PEAR::isError($tmp)) { return $tmp; } $file .= $tmp; } return $file; } /** * Close the file by using fclose and erasing reference to file * * @param string $filename name of the file to be rewound * @param string $mode mode that the file was opened in * * @access private * @return mixed true on success, PEAR_Error on failure */ function close($filename, $mode) { $filePointers =& File::propertySingleton('filePointers', 'array'); if (!isset($filePointers[$filename][$mode]) OR !is_resource($filePointers[$filename][$mode])) { return new PEAR_Error('File is not open, cannot close: ' . $filename); } if(!fclose($filePointers[$filename][$mode])) { return new PEAR_Error('File could not be closed: ' . $filename); } unset($filePointers[$filename][$mode]); return true; } /** * Take the pointer in the file back to the beginning of the file * * @param string $filename name of the file to be rewound * @param string $mode mode that the file was opened in * * @access private * @return mixed true on success, PEAR_Error on failure */ function rewind($filename, $mode) { $filePointers =& File::propertySingleton('filePointers', 'array'); if (!isset($filePointers[$filename][$mode]) || !is_resource($filePointers[$filename][$mode])) { return new PEAR_Error('File is not open, cannot rewind: ' . $filename); } if (!rewind($filePointers[$filename][$mode])) { return new PEAR_Error('File could not be rewound: ' . $filename); } return true; } /** * Reads an entire CSV file and returns it as a 2-D array based on delimiter provided. * * @access public * @param string $filename Name of file to read from * @param string $delimiter (optional) delimiter to use for CVS data * @param bool $close (optional) either close or rewind the file when done * @param mixed $lock Type of lock to use * @return mixed PEAR_Error if an error has occured or a 2-D array with the contents of the the file */ function readAllCSV($filename, $delimiter = ',', $close = true, $lock = false) { $data = ''; while (($line = File::readLineCSV($filename, $delimiter, FILE_DEFAULT_READSIZE, $lock)) !== FALSE) { if (PEAR::isError($line)) { return $line; } $data[] = $line; } if ($close) { if (PEAR::isError($result = File::close($filename, FILE_MODE_READ))) { return $result; } } else { if (PEAR::isError($result = File::rewind($filename, FILE_MODE_READ))) { return $result; } } return $data; } /** * Reads a line from a CSV file and returns it as an array based on delimiter provided. * * @access public * @param string $filename Name of file to read from * @param string $delimiter (optional) delimiter to use for CVS data * @param mixed $lock Type of lock to use * @return mixed PEAR_Error if an error has occured or an array with the contents * of the the line seperated on the delimiter */ function readLineCSV($filename, $delimiter = ',', $size = FILE_DEFAULT_READSIZE, $lock = false) { if(!PEAR::isError($fp = &File::_getFilePointer($filename, FILE_MODE_READ, $lock))){ return !feof($fp) ? fgetcsv($fp, $size, $delimiter) : false; } return $fp; } /** * Returns a specified number of bytes of a file. Defaults to 1024. * * @access public * @param string $filename Name of file to read from * @param int $size Bytes to read * @param mixed $lock Type of lock to use * @return mixed PEAR_Error on error or a string which contains the data read * Will also return false upon EOF */ function read($filename, $size = FILE_DEFAULT_READSIZE, $lock = false) { if (0 == $size) { return File::readAll($filename); } if(!PEAR::isError($fp = &File::_getFilePointer($filename, FILE_MODE_READ, $lock))){ return !feof($fp) ? fread($fp, $size) : false; } return $fp; } /** * Writes the given data to the given filename. Defaults to no lock, append mode. * * @access public * @param string $filename Name of file to write to * @param int $data Data to write to file * @param string $mode Mode to open file in * @param mixed $lock Type of lock to use * @return mixed PEAR_Error on error or number of bytes written to file. */ function write($filename, $data, $mode = FILE_MODE_APPEND, $lock = false) { if (!PEAR::isError($fp = &File::_getFilePointer($filename, $mode, $lock))) { if (($bytes = fwrite($fp, $data, strlen($data))) == -1) { return new PEAR_Error(sprintf('fwrite() call failed to write data: "%s" to file: "%s"', $data, $filename)); } else { return $bytes; } } return $fp; } /** * Reads and returns a single character from given filename * * @access public * @param string $filename Name of file to read from * @param mixed $lock Type of lock to use * @return mixed PEAR_Error on error or one character of the specified file */ function readChar($filename, $lock = false) { return File::read($filename, 1, $lock); } /** * Writes a single character to a file * * @access public * @param string $filename Name of file to write to * @param string $char Character to write * @param string $mode Mode to use when writing * @param mixed $lock Type of lock to use * @return mixed PEAR_Error on error, or 1 on success */ function writeChar($filename, $char, $mode = FILE_MODE_APPEND, $lock = false) { if (!PEAR::isError($fp = &File::_getFilePointer($filename, $mode, $lock))) { if (fwrite($fp, $char, 1) == -1) { return new PEAR_Error(sprintf('fwrite() call failed to write data: "%s" to file: "%s"', $data, $filename)); } else { return 1; } } return $fp; } /** * Returns a line of the file * * @access public * @param string $filename Name of file to read from * @param boolean $lock Type of lock to use * @return mixed PEAR_Error on error or a string containing the line read from file */ function readLine($filename, $lock = false) { if (!PEAR::isError($fp = &File::_getFilePointer($filename, FILE_MODE_READ, $lock))) { $fileString = ""; while (($fileChar = fgetc($fp)) != "\n" AND !feof($fp)) { $fileString .= $fileChar; } return substr($fileString, -1) == "\r" ? substr($fileString, 0, -1) : $fileString; } return $fp; } /** * Writes a single line, appending a LF (by default) * * @access public * @param string $filename Name of file to write to * @param string $line Line of data to be written to file * @param string $mode Write mode, can be either FILE_MODE_WRITE or FILE_MODE_APPEND * @param string $crlf The CRLF your system is using. UNIX = \n Windows = \r\n Mac = \r * @return mixed PEAR_Error on error or number of bytes written to file (including appended crlf) */ function writeLine($filename, $line, $mode = FILE_MODE_APPEND, $crlf = "\n", $lock = false) { if(!PEAR::isError($fp = &File::_getFilePointer($filename, $mode, $lock))){ if (($bytes = fwrite($fp, $line . $crlf)) == -1) { return new PEAR_Error(sprintf('fwrite() call failed to write data: "%s" to file: "%s"', $data, $filename)); } else { return $bytes; } } return $fp; } /** * Returns a string path built from the array $pathParts. Where a join occurs * multiple separators are removed. Joins using the optional separator, defaulting * to the PHP DIRECTORY_SEPARATOR constant. * * @access public * @param array $parts Array containing the parts to be joined * @param string $seperator The system directory seperator */ function buildPath($parts, $separator = DIRECTORY_SEPARATOR) { for ($i = 0; $i < count($parts); $i++) { if (0 == $i) { $parts[$i] = File::stripTrailingSeparators($parts[$i], $separator); } elseif(count($parts) - 1 == $i) { $parts[$i] = File::stripLeadingSeparators($parts[$i], $separator); } else { $parts[$i] = File::stripTrailingSeparators($parts[$i], $separator); $parts[$i] = File::stripLeadingSeparators($parts[$i], $separator); } } return implode($separator, $parts); } /** * Strips trailing separators from the given path * * @access public * @param string $path Path to use * @param string $separator Separator to look for * @return string Resulting path */ function stripTrailingSeparators($path, $separator = DIRECTORY_SEPARATOR) { while (substr($path, -1) == $separator) { $path = substr($path, 0, -1); } return $path; } /** * Strips leading separators from the given path * * @access public * @param string $path Path to use * @param string $separator Separator to look for * @return string Resulting path */ function stripLeadingSeparators($path, $separator = DIRECTORY_SEPARATOR) { while (substr($path, 0, 1) == $separator) { $path = substr($path, 1); } return $path; } /** * Returns a path without leading / or C:\. If this is not * present the path is returned as is. * * @access public * @param string $path The path to be processed * @return string The processed path or the path as is */ function skipRoot($path) { if (File::isAbsolute($path)) { if (DIRECTORY_SEPARATOR == "/") { return substr($path,1); } elseif(DIRECTORY_SEPARATOR == "\\") { return substr($path, 3); } } else { return $path; } } /** * Returns the temp directory according to either the TMP, TMPDIR, or TEMP env * variables. If these are not set it will also check for the existence of * /tmp, C:\WINNT\TEMP amd C:\WINDOWS\TEMP. * * @access public * @return string The system tmp directory */ function getTempDir() { if (getenv("TMP")) { $tmpDir = getenv("TMP"); } elseif(getenv("TMPDIR")) { $tmpDir = getenv("TMPDIR"); } elseif(getenv("TEMP")) { $tmpDir = getenv("TEMP"); } elseif(file_exists('/tmp') AND is_writeable('/tmp')) { $tmpDir = '/tmp'; } elseif(file_exists('C:\\WINNT\\TEMP') AND is_writeable('C:\\WINNT\\TEMP')) { $tmpDir = 'C:\\WINNT\\TEMP'; } elseif(file_exists('C:\\WINDOWS\\TEMP') AND is_writeable('C:\\WINDOWS\\TEMP')) { $tmpDir = 'C:\\WINDOWS\\TEMP'; } else { if (DIRECTORY_SEPARATOR == "\\") { $tmpDir = "C:\\"; } else { $tmpDir = "/"; } } return $tmpDir; } /* * Returns a temporary filename using tempnam() and the above getTmpDir() function. * * @access public * @return string Filename and path of the tmp file */ function getTempFile() { return tempnam(File::getTempDir(), 'temp.'); } /** * Returns boolean based on whether given path is absolute or not. * * @access public * @param string $path Given path * @return boolean True if the path is absolute, false if it is not */ function isAbsolute($path) { if (DIRECTORY_SEPARATOR == '/' AND substr($path, 0, 1) == '/') { return true; } elseif(DIRECTORY_SEPARATOR == '\\' AND preg_match('/^[a-z]:\\\/i', $path)) { return true; } return false; } } ?>
« previous php.pear.dev (#5197) next »