path.php (2830B)
1 <?php 2 // http://www.liranuna.com/php-path-resolution-class-relative-paths-made-easy/ 3 // Licence : WTFPL 4 /** 5 * @class Path 6 * 7 * @brief Utility class that handles file and directory pathes 8 * 9 * This class handles basic important operations done to file system paths. 10 * It safely renders relative pathes and removes all ambiguity from a relative path. 11 * 12 * @author Liran Nuna 13 */ 14 final class Path 15 { 16 /** 17 * Returns the parent path of this path. 18 * "/path/to/directory" will return "/path/to" 19 * 20 * @arg $path The path to retrieve the parent path from 21 */ 22 public static function dirname($path) { 23 return dirname(self::normalize($path)); 24 } 25 26 /** 27 * Returns the last item on the path. 28 * "/path/to/directory" will return "directory" 29 * 30 * @arg $path The path to retrieve the base from 31 */ 32 public static function basename($path) { 33 return basename(self::normalize($path)); 34 } 35 36 /** 37 * Normalizes the path for safe usage 38 * This function does several operations to the given path: 39 * * Removes unnecessary slashes (///path//to/////directory////) 40 * * Removes current directory references (/path/././to/./directory/./././) 41 * * Renders relative pathes (/path/from/../to/somewhere/in/../../directory) 42 * 43 * @arg $path The path to normalize 44 */ 45 public static function normalize($path) { 46 return array_reduce(explode('/', $path), create_function('$a, $b', ' 47 if($a === 0) 48 $a = "/"; 49 50 if($b === "" || $b === ".") 51 return $a; 52 53 if($b === "..") 54 return dirname($a); 55 56 return preg_replace("/\/+/", "/", "$a/$b"); 57 '), 0); 58 } 59 60 /** 61 * Combines a list of pathes to one safe path 62 * 63 * @arg $root The path or array with values to combine into a single path 64 * @arg ... Relative pathes to root or arrays 65 * 66 * @note This function works with multi-dimentional arrays recursively. 67 */ 68 public static function combine($root, $rel1) { 69 $arguments = func_get_args(); 70 return self::normalize(array_reduce($arguments, create_function('$a,$b', ' 71 if(is_array($a)) 72 $a = array_reduce($a, "Path::combine"); 73 if(is_array($b)) 74 $b = array_reduce($b, "Path::combine"); 75 76 return "$a/$b"; 77 '))); 78 } 79 80 // Ajout par js jahvascriptmaniac+github@gmail.com 81 // Depuis le dossier $a, construire un chemin relatif vers $b. 82 public static function relative($a, $b) { 83 $a = explode('/', self::normalize($a)); 84 $b = explode('/', self::normalize($b)); 85 86 // Zapper la partie commune 87 for ($i = 0; $i < count($a) && $i < count($b); $i++) { 88 if (! ($a[$i] == $b[$i])) break; 89 } 90 91 $rel = "."; 92 for ($j = $i; $j < count($a); $j++) { 93 $rel .= "/.."; 94 } 95 for ($j = $i; $j < count($b); $j++) { 96 $rel .= '/' . $b[$j]; 97 } 98 99 return $rel; 100 } 101 102 /** 103 * Empty, private constructor, to prevent instantiation 104 */ 105 private function __construct() { 106 // Prevents instantiation 107 } 108 } 109 110 ?>