Blame | Letzte Änderung | Log anzeigen | RSS feed
<?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;}}