| 
<?php
// +---------------------------------------------------------------+
 // | File Stats Class                                              |
 // +---------------------------------------------------------------+
 // | Works with large files on 32 bit systems                      |
 // +---------------------------------------------------------------+
 // | Authors:       Jamie Curnow  <[email protected]>                    |
 // +---------------------------------------------------------------+
 
 // $Id:$
 
 
 class File_Stats {
 
 
 const TYPE_DIR            = 1;
 const TYPE_FILE           = 2;
 
 const OPSYS_LINUX         = 1;
 const OPSYS_BSD           = 2;
 const OPSYS_WIN           = 3;
 
 
 
 /**
 * What is this operating system?
 *
 * @var     int
 * @access  protected
 *
 **/
 protected $_opsys = self::OPSYS_LINUX;
 
 /**
 * Should we use Windows COM objects?
 *
 * @var     bool
 * @access  protected
 *
 **/
 protected $_use_win_com = true;
 
 /**
 * Are we using a 32 bit operating system/PHP binary?
 *
 * @var     bool
 * @access  protected
 *
 **/
 protected $_is_32_bit = true;
 
 
 
 
 /**
 * Constructor
 *
 * @access public
 * @return void
 */
 public function __construct() {
 $this->_determineOpSys();
 $this->_is_32_bit = (PHP_INT_MAX > 2147483647 ? false : true);
 }
 
 
 /**
 * Should we use Windows COM Objects?
 *
 * @access protected
 * @param  bool   $bool
 * @return void
 */
 public function setUseWinCom($bool) {
 $this->_use_win_com = (bool) $bool;
 }
 
 
 /**
 * Determine the operating system we're running on
 *
 * @access protected
 * @return int
 */
 protected function _determineOpSys() {
 $name = strtolower(php_uname('s'));
 if (strpos($name, 'win') !== false) {
 $this->_opsys = self::OPSYS_WIN;
 } else if (strpos($name, 'bsd') !== false) {
 $this->_opsys = self::OPSYS_BSD;
 } else if (strpos($name, 'linux') !== false) {
 $this->_opsys = self::OPSYS_LINUX;
 }
 }
 
 
 /**
 * Get the filesize of a file
 *
 * @access public
 * @param  string  $file
 * @return int
 */
 public function getFileSize($file) {
 // Only go into workaround methods if this is a 32 bit operating system
 if ($this->_is_32_bit) {
 $filesize = 0;
 if ($this->_opsys == self::OPSYS_WIN && $this->_use_win_com) {
 // Don't bother checking if filesize() failed, on windows it doesn't fail
 // and instead rolls over the integer boundary.
 $filesize = $this->_getLargeFileSize($file);
 } else {
 $filesize = (@filesize($file) ? filesize($file) : $this->_getLargeFileSize($file));
 }
 return $filesize;
 } else {
 return filesize($file);
 }
 }
 
 
 /**
 * Attempt to return the filesize for files larger than 2gb on 32bit systems
 *
 * @access protected
 * @param  string  $file
 * @return float
 */
 protected function _getLargeFileSize($file) {
 if ($file && strlen($file)) {
 switch ($this->_opsys) {
 case self::OPSYS_BSD:
 return (float) exec('stat -f %z '. escapeshellarg ($file));
 break;
 case self::OPSYS_LINUX:
 $file = $this->_getRealPath($file);
 return (float) exec('stat -c %s '. escapeshellarg ($file));
 break;
 case self::OPSYS_WIN:
 try {
 $fsobj = new COM("Scripting.FileSystemObject");
 $f = $fsobj->GetFile($file);
 return $f->Size;
 } catch(Exception $e) {
 return 0;
 }
 break;
 }
 }
 return 0;
 }
 
 
 /**
 * Get the Modified Time of a file
 *
 * @access public
 * @param  string  $file
 * @return int
 */
 public function getFileModifiedTime($file) {
 // Only go into workaround methods if this is a 32 bit operating system
 if ($this->_is_32_bit) {
 return (@filemtime($file) ? filemtime($file) : $this->_getLargeFileModifiedTime($file));
 } else {
 return filemtime($file);
 }
 }
 
 
 /**
 * Attempt to return the modified time for files larger than 2gb on 32bit systems
 *
 * @access protected
 * @param  string  $file
 * @return int
 */
 protected function _getLargeFileModifiedTime($file) {
 if ($file && strlen($file)) {
 switch ($this->_opsys) {
 case self::OPSYS_BSD:
 return exec('stat -f %m '. escapeshellarg ($file));
 break;
 case self::OPSYS_LINUX:
 $file = $this->_getRealPath($file);
 return exec('stat -c %Y '. escapeshellarg ($file));
 break;
 }
 }
 return 0;
 }
 
 
 /**
 * Find out the Type of file on disk, it's either a Directory or a File.
 *
 * @access public
 * @param  string  $file
 * @return int
 */
 public function getFileType($file) {
 // Only go into workaround methods if this is a 32 bit operating system
 if ($this->_is_32_bit) {
 return $this->_getLargeFileType($file);
 } else {
 return (is_dir($file) ? self::TYPE_DIR : self::TYPE_FILE);
 }
 }
 
 
 /**
 * Attempt to return the filetype for files/dirs larger than 2gb on 32bit systems
 *
 * @access protected
 * @param  string  $file
 * @return float
 */
 protected function _getLargeFileType($file) {
 if ($file && strlen($file)) {
 switch ($this->_opsys) {
 case self::OPSYS_BSD:
 $type = strtolower(exec('stat -f %HT '. escapeshellarg ($file)));
 if (strpos($type, 'directory') !== false) {
 return self::TYPE_DIR;
 } else if (strpos($type, 'symbolic') !== false) {
 $file = $this->_getRealPath($file);
 return $this->_getLargeFileType($file);
 } else {
 return self::TYPE_FILE;
 }
 return $var;
 break;
 case self::OPSYS_LINUX:
 $var = false;
 $type = strtolower(exec ('stat -c %F '. escapeshellarg ($file)));
 if (strpos($type, 'directory') !== false) {
 return self::TYPE_DIR;
 } else if (strpos($type, 'symbolic') !== false) {
 $file = $this->_getRealPath($file);
 return $this->_getLargeFileType($file);
 } else {
 return self::TYPE_FILE;
 }
 return $var;
 break;
 case self::OPSYS_WIN:
 return (is_dir($file) ? self::TYPE_DIR : self::TYPE_FILE);
 break;
 }
 }
 return false;
 }
 
 
 /**
 * A 32 bit compatible version of realpath()
 *
 * @access protected
 * @param  string  $file
 * @return string
 */
 protected function _getRealPath($file) {
 if ($file && strlen($file)) {
 // Only go into workaround methods if this is a 32 bit operating system
 if ($this->_is_32_bit) {
 switch ($this->_opsys) {
 case self::OPSYS_LINUX:
 $var = false;
 return exec ('readlink -f '. escapeshellarg ($file));
 break;
 }
 }
 return realpath($file);
 }
 return false;
 }
 
 
 }
 
 
 
 |