Viewing file: Util.php (14.9 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/** * File::Util * * PHP versions 4 and 5 * * LICENSE: This source file is subject to version 3.0 of the PHP license * that is available through the world-wide-web at the following URI: * http://www.php.net/license/3_0.txt. If you did not receive a copy of * the PHP License and are unable to obtain it through the web, please * send a note to license@php.net so we can mail you a copy immediately. * * @category File * @package File * @author Michael Wallner <mike@php.net> * @copyright 2004-2005 Michael Wallner * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version CVS: $Id: Util.php 309134 2011-03-12 16:45:50Z dufuz $ * @link http://pear.php.net/package/File */
/**#@+ * Sorting Constants */ define('FILE_SORT_NONE', 0); define('FILE_SORT_REVERSE', 1); define('FILE_SORT_NAME', 2); define('FILE_SORT_SIZE', 4); define('FILE_SORT_DATE', 8); define('FILE_SORT_RANDOM', 16); /**#@-*/
/**#@+ * Listing Constants */ define('FILE_LIST_FILES', 1); define('FILE_LIST_DIRS', 2); define('FILE_LIST_DOTS', 4); define('FILE_LIST_ALL', FILE_LIST_FILES | FILE_LIST_DIRS | FILE_LIST_DOTS); /**#@-*/
/** * @ignore */ define('FILE_WIN32', defined('OS_WINDOWS') ? OS_WINDOWS : !strncasecmp(PHP_OS, 'win', 3));
/** * File_Util * * File and directory utility functions. * * @access public * @static */ class File_Util { /** * 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. * * @static * @access public * @param array $parts Array containing the parts to be joined * @param string $separator The directory seperator */ function buildPath($parts, $separator = DIRECTORY_SEPARATOR) { $qs = '/^'. preg_quote($separator, '/') .'+$/'; for ($i = 0, $c = count($parts); $i < $c; $i++) { if (!strlen($parts[$i]) || preg_match($qs, $parts[$i])) { unset($parts[$i]); } elseif (0 == $i) { $parts[$i] = rtrim($parts[$i], $separator); } elseif ($c - 1 == $i) { $parts[$i] = ltrim($parts[$i], $separator); } else { $parts[$i] = trim($parts[$i], $separator); } } return implode($separator, $parts); }
/** * Returns a path without leading / or C:\. If this is not * present the path is returned as is. * * @static * @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_Util::isAbsolute($path)) { if (FILE_WIN32) { return substr($path, $path{3} == '\\' ? 4 : 3); } return ltrim($path, '/'); } 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, %WINDIR%\temp * * @static * @access public * @return string The system tmp directory */ function tmpDir() { if (FILE_WIN32) { if (isset($_ENV['TEMP'])) { return $_ENV['TEMP']; } if (isset($_ENV['TMP'])) { return $_ENV['TMP']; } if (isset($_ENV['windir'])) { return $_ENV['windir'] . '\\temp'; } if (isset($_ENV['SystemRoot'])) { return $_ENV['SystemRoot'] . '\\temp'; } if (isset($_SERVER['TEMP'])) { return $_SERVER['TEMP']; } if (isset($_SERVER['TMP'])) { return $_SERVER['TMP']; } if (isset($_SERVER['windir'])) { return $_SERVER['windir'] . '\\temp'; } if (isset($_SERVER['SystemRoot'])) { return $_SERVER['SystemRoot'] . '\\temp'; } return '\temp'; } if (isset($_ENV['TMPDIR'])) { return $_ENV['TMPDIR']; } if (isset($_SERVER['TMPDIR'])) { return $_SERVER['TMPDIR']; } return '/tmp'; }
/** * Returns a temporary filename using tempnam() and File::tmpDir(). * * @static * @access public * @param string $dirname Optional directory name for the tmp file * @return string Filename and path of the tmp file */ function tmpFile($dirname = null) { if (!isset($dirname)) { $dirname = File_Util::tmpDir(); } return tempnam($dirname, 'temp.'); }
/** * Returns boolean based on whether given path is absolute or not. * * @static * @access public * @param string $path Given path * @return boolean True if the path is absolute, false if it is not */ function isAbsolute($path) { if (preg_match('/(?:\/|\\\)\.\.(?=\/|$)/', $path)) { return false; } if (FILE_WIN32) { return (($path{0} == '/') || preg_match('/^[a-zA-Z]:(\\\|\/)/', $path)); } return ($path{0} == '/') || ($path{0} == '~'); }
/** * Checks for a file's existence, taking the current include path * into consideration * * This method can be called statically * (e.g., File_Util::isIncludable('config.php')) * * @param string $file * @param string $sep the directory separator (optional) * @return string the includable path * @access public * @static */ function isIncludable($file, $sep = DIRECTORY_SEPARATOR) { foreach ((array) explode(PATH_SEPARATOR, ini_get('include_path')) as $path) { if (file_exists($path .= $sep . $file)) { return $path; } } if (file_exists($file)) { return $file; } return null; }
/** * Get path relative to another path * * @static * @access public * @return string * @param string $path * @param string $root * @param string $separator */ function relativePath($path, $root, $separator = DIRECTORY_SEPARATOR) { $path = File_Util::realpath($path, $separator); $root = File_Util::realpath($root, $separator); $dirs = explode($separator, $path); $comp = explode($separator, $root);
if (FILE_WIN32) { if (strcasecmp($dirs[0], $comp[0])) { return $path; } unset($dirs[0], $comp[0]); }
foreach ($comp as $i => $part) { if (isset($dirs[$i]) && $part == $dirs[$i]) { unset($dirs[$i], $comp[$i]); } else { break; } }
return str_repeat('..' . $separator, count($comp)) . implode($separator, $dirs); }
/** * Get real path (works with non-existant paths) * * @static * @access public * @return string * @param string $path * @param string $separator */ function realPath($path, $separator = DIRECTORY_SEPARATOR) { if (!strlen($path)) { return $separator; }
$drive = ''; $path = preg_replace('/[\\\\\/]/', $separator, $path); if (FILE_WIN32) { if (preg_match('/([a-zA-Z]\:)(.*)/', $path, $matches)) { $drive = $matches[1]; $path = $matches[2]; } else { $cwd = getcwd(); $drive = substr($cwd, 0, 2); if ($path{0} !== $separator{0}) { $path = substr($cwd, 3) . $separator . $path; } } } elseif ($path{0} !== $separator) { $path = getcwd() . $separator . $path; }
$dirStack = array(); foreach (explode($separator, $path) as $dir) { if (strlen($dir) && $dir !== '.') { if ($dir == '..') { array_pop($dirStack); } else { $dirStack[] = $dir; } } }
return $drive . $separator . implode($separator, $dirStack); }
/** * Check whether path is in root path * * @static * @access public * @return bool * @param string $path * @param string $root */ function pathInRoot($path, $root) { static $realPaths = array();
if (!isset($realPaths[$root])) { $realPaths[$root] = File_Util::realPath($root); }
return false !== strstr(File_Util::realPath($path), $realPaths[$root]); }
/** * List Directory * * The final argument, $cb, is a callback that either evaluates to true or * false and performs a filter operation, or it can also modify the * directory/file names returned. To achieve the latter effect use as * follows: * * <code> * <?php * function uc(&$filename) { * $filename = strtoupper($filename); * return true; * } * $entries = File_Util::listDir('.', FILE_LIST_ALL, FILE_SORT_NONE, 'uc'); * foreach ($entries as $e) { * echo $e->name, "\n"; * } * ?> * </code> * * @static * @access public * @return array * @param string $path * @param int $list * @param int $sort * @param mixed $cb */ function listDir($path, $list = FILE_LIST_ALL, $sort = FILE_SORT_NONE, $cb = null) { if (!strlen($path) || !is_dir($path)) { return null; }
$entries = array(); for ($dir = dir($path); false !== $entry = $dir->read(); ) { if ($list & FILE_LIST_DOTS || $entry{0} !== '.') { $isRef = ($entry === '.' || $entry === '..'); $isDir = $isRef || is_dir($path .'/'. $entry); if ( ((!$isDir && $list & FILE_LIST_FILES) || ($isDir && $list & FILE_LIST_DIRS)) && (!is_callable($cb) || call_user_func_array($cb, array(&$entry)))) { $entries[] = (object) array( 'name' => $entry, 'size' => $isDir ? null : filesize($path .'/'. $entry), 'date' => filemtime($path .'/'. $entry), ); } } } $dir->close();
if ($sort) { $entries = File_Util::sortFiles($entries, $sort); }
return $entries; }
/** * Sort Files * * @static * @access public * @return array * @param array $files * @param int $sort */ function sortFiles($files, $sort) { if (!$files) { return array(); }
if (!$sort) { return $files; }
if ($sort === 1) { return array_reverse($files); }
if ($sort & FILE_SORT_RANDOM) { shuffle($files); return $files; }
$names = array(); $sizes = array(); $dates = array();
if ($sort & FILE_SORT_NAME) { $r = &$names; } elseif ($sort & FILE_SORT_DATE) { $r = &$dates; } elseif ($sort & FILE_SORT_SIZE) { $r = &$sizes; } else { asort($files, SORT_REGULAR); return $files; }
$sortFlags = array( FILE_SORT_NAME => SORT_STRING, FILE_SORT_DATE => SORT_NUMERIC, FILE_SORT_SIZE => SORT_NUMERIC, );
foreach ($files as $file) { $names[] = $file->name; $sizes[] = $file->size; $dates[] = $file->date; }
if ($sort & FILE_SORT_REVERSE) { arsort($r, $sortFlags[$sort & ~1]); } else { asort($r, $sortFlags[$sort]); }
$result = array(); foreach ($r as $i => $f) { $result[] = $files[$i]; }
return $result; }
/** * Switch File Extension * * @static * @access public * @return string|array * @param string|array $filename * @param string $to new file extension * @param string $from change only files with this extension * @param bool $reverse change only files not having $from extension */ function switchExt($filename, $to, $from = null, $reverse = false) { if (is_array($filename)) { foreach ($filename as $key => $file) { $filename[$key] = File_Util::switchExt($file, $to, $from); } return $filename; }
if ($len = strlen($from)) { $ext = substr($filename, -$len - 1); $cfn = FILE_WIN32 ? 'strcasecmp' : 'strcmp'; if (!$reverse == $cfn($ext, '.'. $from)) { return $filename; } return substr($filename, 0, -$len - 1) .'.'. $to; }
if ($pos = strpos($filename, '.')) { return substr($filename, 0, $pos) .'.'. $to; }
return $filename .'.'. $to; }
/** * Returns the filesize using a prefix like "kilo", "mebi" or "giga" * * @author Christian Weiske <cweiske@cweiske.de> * * @param integer $size The size to convert * @param integer $decimals The number of decimals to use * @param boolean $long Use long names (kilobyte) instead of * short ones (kB) * @param boolean $oldStyle If the old style should be used * @param boolean $useBiBytes If the "BiBytes" names should be * used [applies only to !$bOldStyle] * * @return string The filesize in human readable format * * @static */ function prefixed( $size, $decimals = 1, $long = false, $oldStyle = true, $useBiBytes = true ) { $base = ($oldStyle || $useBiBytes) ? 1024 : 1000; $names = array( '', 'kilo', 'mega', 'giga', 'tera', 'peta', 'exa', 'zetta', 'yotta' ); $max = count($names) - 1;
for ($a = 0; $size >= $base && $a < $max; $a++) { $size /= $base; }
$name = ($oldStyle || !$useBiBytes) ? $names[$a] : $names[$a] . 'bi'; if (!$long) { $name = $oldStyle || !$useBiBytes ? strtoupper(substr($name, 0, 1)) : strtoupper(substr($name, 0, 1)) . 'i'; $name .= 'B'; } else { $name .= $size == 1 ? 'byte' : 'bytes'; }
return round($size, $decimals) . ' ' . $name; }
}
|