[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 /** 3 * File/Directory manipulation 4 * 5 * PHP versions 4 and 5 6 * 7 * LICENSE: This source file is subject to version 3.0 of the PHP license 8 * that is available through the world-wide-web at the following URI: 9 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 10 * the PHP License and are unable to obtain it through the web, please 11 * send a note to license@php.net so we can mail you a copy immediately. 12 * 13 * @category pear 14 * @package System 15 * @author Tomas V.V.Cox <cox@idecnet.com> 16 * @copyright 1997-2005 The PHP Group 17 * @license http://www.php.net/license/3_0.txt PHP License 3.0 18 * @version CVS: $Id: System.php,v 1.51 2005/11/16 03:28:56 cellog Exp $ 19 * @link http://pear.php.net/package/PEAR 20 * @since File available since Release 0.1 21 */ 22 23 /** 24 * base class 25 */ 26 require_once 'PEAR.php'; 27 require_once 'Console/Getopt.php'; 28 29 $GLOBALS['_System_temp_files'] = array(); 30 31 /** 32 * System offers cross plattform compatible system functions 33 * 34 * Static functions for different operations. Should work under 35 * Unix and Windows. The names and usage has been taken from its respectively 36 * GNU commands. The functions will return (bool) false on error and will 37 * trigger the error with the PHP trigger_error() function (you can silence 38 * the error by prefixing a '@' sign after the function call). 39 * 40 * Documentation on this class you can find in: 41 * http://pear.php.net/manual/ 42 * 43 * Example usage: 44 * if (!@System::rm('-r file1 dir1')) { 45 * print "could not delete file1 or dir1"; 46 * } 47 * 48 * In case you need to to pass file names with spaces, 49 * pass the params as an array: 50 * 51 * System::rm(array('-r', $file1, $dir1)); 52 * 53 * @category pear 54 * @package System 55 * @author Tomas V.V. Cox <cox@idecnet.com> 56 * @copyright 1997-2005 The PHP Group 57 * @license http://www.php.net/license/3_0.txt PHP License 3.0 58 * @version Release: 1.4.5 59 * @link http://pear.php.net/package/PEAR 60 * @since Class available since Release 0.1 61 */ 62 class System 63 { 64 /** 65 * returns the commandline arguments of a function 66 * 67 * @param string $argv the commandline 68 * @param string $short_options the allowed option short-tags 69 * @param string $long_options the allowed option long-tags 70 * @return array the given options and there values 71 * @access private 72 */ 73 function _parseArgs($argv, $short_options, $long_options = null) 74 { 75 if (!is_array($argv) && $argv !== null) { 76 $argv = preg_split('/\s+/', $argv, -1, PREG_SPLIT_NO_EMPTY); 77 } 78 return Console_Getopt::getopt2($argv, $short_options); 79 } 80 81 /** 82 * Output errors with PHP trigger_error(). You can silence the errors 83 * with prefixing a "@" sign to the function call: @System::mkdir(..); 84 * 85 * @param mixed $error a PEAR error or a string with the error message 86 * @return bool false 87 * @access private 88 */ 89 function raiseError($error) 90 { 91 if (PEAR::isError($error)) { 92 $error = $error->getMessage(); 93 } 94 trigger_error($error, E_USER_WARNING); 95 return false; 96 } 97 98 /** 99 * Creates a nested array representing the structure of a directory 100 * 101 * System::_dirToStruct('dir1', 0) => 102 * Array 103 * ( 104 * [dirs] => Array 105 * ( 106 * [0] => dir1 107 * ) 108 * 109 * [files] => Array 110 * ( 111 * [0] => dir1/file2 112 * [1] => dir1/file3 113 * ) 114 * ) 115 * @param string $sPath Name of the directory 116 * @param integer $maxinst max. deep of the lookup 117 * @param integer $aktinst starting deep of the lookup 118 * @return array the structure of the dir 119 * @access private 120 */ 121 122 function _dirToStruct($sPath, $maxinst, $aktinst = 0) 123 { 124 $struct = array('dirs' => array(), 'files' => array()); 125 if (($dir = @opendir($sPath)) === false) { 126 System::raiseError("Could not open dir $sPath"); 127 return $struct; // XXX could not open error 128 } 129 $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? 130 $list = array(); 131 while (false !== ($file = readdir($dir))) { 132 if ($file != '.' && $file != '..') { 133 $list[] = $file; 134 } 135 } 136 closedir($dir); 137 sort($list); 138 if ($aktinst < $maxinst || $maxinst == 0) { 139 foreach($list as $val) { 140 $path = $sPath . DIRECTORY_SEPARATOR . $val; 141 if (is_dir($path) && !is_link($path)) { 142 $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1); 143 $struct = array_merge_recursive($tmp, $struct); 144 } else { 145 $struct['files'][] = $path; 146 } 147 } 148 } 149 return $struct; 150 } 151 152 /** 153 * Creates a nested array representing the structure of a directory and files 154 * 155 * @param array $files Array listing files and dirs 156 * @return array 157 * @see System::_dirToStruct() 158 */ 159 function _multipleToStruct($files) 160 { 161 $struct = array('dirs' => array(), 'files' => array()); 162 settype($files, 'array'); 163 foreach ($files as $file) { 164 if (is_dir($file) && !is_link($file)) { 165 $tmp = System::_dirToStruct($file, 0); 166 $struct = array_merge_recursive($tmp, $struct); 167 } else { 168 $struct['files'][] = $file; 169 } 170 } 171 return $struct; 172 } 173 174 /** 175 * The rm command for removing files. 176 * Supports multiple files and dirs and also recursive deletes 177 * 178 * @param string $args the arguments for rm 179 * @return mixed PEAR_Error or true for success 180 * @access public 181 */ 182 function rm($args) 183 { 184 $opts = System::_parseArgs($args, 'rf'); // "f" do nothing but like it :-) 185 if (PEAR::isError($opts)) { 186 return System::raiseError($opts); 187 } 188 foreach($opts[0] as $opt) { 189 if ($opt[0] == 'r') { 190 $do_recursive = true; 191 } 192 } 193 $ret = true; 194 if (isset($do_recursive)) { 195 $struct = System::_multipleToStruct($opts[1]); 196 foreach($struct['files'] as $file) { 197 if (!@unlink($file)) { 198 $ret = false; 199 } 200 } 201 foreach($struct['dirs'] as $dir) { 202 if (!@rmdir($dir)) { 203 $ret = false; 204 } 205 } 206 } else { 207 foreach ($opts[1] as $file) { 208 $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; 209 if (!@$delete($file)) { 210 $ret = false; 211 } 212 } 213 } 214 return $ret; 215 } 216 217 /** 218 * Make directories. 219 * 220 * The -p option will create parent directories 221 * @param string $args the name of the director(y|ies) to create 222 * @return bool True for success 223 * @access public 224 */ 225 function mkDir($args) 226 { 227 $opts = System::_parseArgs($args, 'pm:'); 228 if (PEAR::isError($opts)) { 229 return System::raiseError($opts); 230 } 231 $mode = 0777; // default mode 232 foreach($opts[0] as $opt) { 233 if ($opt[0] == 'p') { 234 $create_parents = true; 235 } elseif($opt[0] == 'm') { 236 // if the mode is clearly an octal number (starts with 0) 237 // convert it to decimal 238 if (strlen($opt[1]) && $opt[1]{0} == '0') { 239 $opt[1] = octdec($opt[1]); 240 } else { 241 // convert to int 242 $opt[1] += 0; 243 } 244 $mode = $opt[1]; 245 } 246 } 247 $ret = true; 248 if (isset($create_parents)) { 249 foreach($opts[1] as $dir) { 250 $dirstack = array(); 251 while (!@is_dir($dir) && $dir != DIRECTORY_SEPARATOR) { 252 array_unshift($dirstack, $dir); 253 $dir = dirname($dir); 254 } 255 while ($newdir = array_shift($dirstack)) { 256 if (!is_writeable(dirname($newdir))) { 257 $ret = false; 258 break; 259 } 260 if (!mkdir($newdir, $mode)) { 261 $ret = false; 262 } 263 } 264 } 265 } else { 266 foreach($opts[1] as $dir) { 267 if (!@is_dir($dir) && !mkdir($dir, $mode)) { 268 $ret = false; 269 } 270 } 271 } 272 return $ret; 273 } 274 275 /** 276 * Concatenate files 277 * 278 * Usage: 279 * 1) $var = System::cat('sample.txt test.txt'); 280 * 2) System::cat('sample.txt test.txt > final.txt'); 281 * 3) System::cat('sample.txt test.txt >> final.txt'); 282 * 283 * Note: as the class use fopen, urls should work also (test that) 284 * 285 * @param string $args the arguments 286 * @return boolean true on success 287 * @access public 288 */ 289 function &cat($args) 290 { 291 $ret = null; 292 $files = array(); 293 if (!is_array($args)) { 294 $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); 295 } 296 for($i=0; $i < count($args); $i++) { 297 if ($args[$i] == '>') { 298 $mode = 'wb'; 299 $outputfile = $args[$i+1]; 300 break; 301 } elseif ($args[$i] == '>>') { 302 $mode = 'ab+'; 303 $outputfile = $args[$i+1]; 304 break; 305 } else { 306 $files[] = $args[$i]; 307 } 308 } 309 if (isset($mode)) { 310 if (!$outputfd = fopen($outputfile, $mode)) { 311 $err = System::raiseError("Could not open $outputfile"); 312 return $err; 313 } 314 $ret = true; 315 } 316 foreach ($files as $file) { 317 if (!$fd = fopen($file, 'r')) { 318 System::raiseError("Could not open $file"); 319 continue; 320 } 321 while ($cont = fread($fd, 2048)) { 322 if (isset($outputfd)) { 323 fwrite($outputfd, $cont); 324 } else { 325 $ret .= $cont; 326 } 327 } 328 fclose($fd); 329 } 330 if (@is_resource($outputfd)) { 331 fclose($outputfd); 332 } 333 return $ret; 334 } 335 336 /** 337 * Creates temporary files or directories. This function will remove 338 * the created files when the scripts finish its execution. 339 * 340 * Usage: 341 * 1) $tempfile = System::mktemp("prefix"); 342 * 2) $tempdir = System::mktemp("-d prefix"); 343 * 3) $tempfile = System::mktemp(); 344 * 4) $tempfile = System::mktemp("-t /var/tmp prefix"); 345 * 346 * prefix -> The string that will be prepended to the temp name 347 * (defaults to "tmp"). 348 * -d -> A temporary dir will be created instead of a file. 349 * -t -> The target dir where the temporary (file|dir) will be created. If 350 * this param is missing by default the env vars TMP on Windows or 351 * TMPDIR in Unix will be used. If these vars are also missing 352 * c:\windows\temp or /tmp will be used. 353 * 354 * @param string $args The arguments 355 * @return mixed the full path of the created (file|dir) or false 356 * @see System::tmpdir() 357 * @access public 358 */ 359 function mktemp($args = null) 360 { 361 static $first_time = true; 362 $opts = System::_parseArgs($args, 't:d'); 363 if (PEAR::isError($opts)) { 364 return System::raiseError($opts); 365 } 366 foreach($opts[0] as $opt) { 367 if($opt[0] == 'd') { 368 $tmp_is_dir = true; 369 } elseif($opt[0] == 't') { 370 $tmpdir = $opt[1]; 371 } 372 } 373 $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp'; 374 if (!isset($tmpdir)) { 375 $tmpdir = System::tmpdir(); 376 } 377 if (!System::mkDir(array('-p', $tmpdir))) { 378 return false; 379 } 380 $tmp = tempnam($tmpdir, $prefix); 381 if (isset($tmp_is_dir)) { 382 unlink($tmp); // be careful possible race condition here 383 if (!mkdir($tmp, 0700)) { 384 return System::raiseError("Unable to create temporary directory $tmpdir"); 385 } 386 } 387 $GLOBALS['_System_temp_files'][] = $tmp; 388 if ($first_time) { 389 PEAR::registerShutdownFunc(array('System', '_removeTmpFiles')); 390 $first_time = false; 391 } 392 return $tmp; 393 } 394 395 /** 396 * Remove temporary files created my mkTemp. This function is executed 397 * at script shutdown time 398 * 399 * @access private 400 */ 401 function _removeTmpFiles() 402 { 403 if (count($GLOBALS['_System_temp_files'])) { 404 $delete = $GLOBALS['_System_temp_files']; 405 array_unshift($delete, '-r'); 406 System::rm($delete); 407 $GLOBALS['_System_temp_files'] = array(); 408 } 409 } 410 411 /** 412 * Get the path of the temporal directory set in the system 413 * by looking in its environments variables. 414 * Note: php.ini-recommended removes the "E" from the variables_order setting, 415 * making unavaible the $_ENV array, that s why we do tests with _ENV 416 * 417 * @return string The temporal directory on the system 418 */ 419 function tmpdir() 420 { 421 if (OS_WINDOWS) { 422 if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { 423 return $var; 424 } 425 if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { 426 return $var; 427 } 428 if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { 429 return $var; 430 } 431 return getenv('SystemRoot') . '\temp'; 432 } 433 if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) { 434 return $var; 435 } 436 return '/tmp'; 437 } 438 439 /** 440 * The "which" command (show the full path of a command) 441 * 442 * @param string $program The command to search for 443 * @param mixed $fallback Value to return if $program is not found 444 * 445 * @return mixed A string with the full path or false if not found 446 * @author Stig Bakken <ssb@php.net> 447 */ 448 function which($program, $fallback = false) 449 { 450 // avaible since 4.3.0RC2 451 if (defined('PATH_SEPARATOR')) { 452 $path_delim = PATH_SEPARATOR; 453 } else { 454 $path_delim = OS_WINDOWS ? ';' : ':'; 455 } 456 // full path given 457 if (basename($program) != $program) { 458 $path_elements[] = dirname($program); 459 $program = basename($program); 460 } else { 461 // Honor safe mode 462 if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) { 463 $path = getenv('PATH'); 464 if (!$path) { 465 $path = getenv('Path'); // some OSes are just stupid enough to do this 466 } 467 } 468 $path_elements = explode($path_delim, $path); 469 } 470 471 if (OS_WINDOWS) { 472 $exe_suffixes = getenv('PATHEXT') 473 ? explode($path_delim, getenv('PATHEXT')) 474 : array('.exe','.bat','.cmd','.com'); 475 // allow passing a command.exe param 476 if (strpos($program, '.') !== false) { 477 array_unshift($exe_suffixes, ''); 478 } 479 // is_executable() is not available on windows for PHP4 480 $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file'; 481 } else { 482 $exe_suffixes = array(''); 483 $pear_is_executable = 'is_executable'; 484 } 485 486 foreach ($exe_suffixes as $suff) { 487 foreach ($path_elements as $dir) { 488 $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; 489 if ($pear_is_executable($file)) { 490 return $file; 491 } 492 } 493 } 494 return $fallback; 495 } 496 497 /** 498 * The "find" command 499 * 500 * Usage: 501 * 502 * System::find($dir); 503 * System::find("$dir -type d"); 504 * System::find("$dir -type f"); 505 * System::find("$dir -name *.php"); 506 * System::find("$dir -name *.php -name *.htm*"); 507 * System::find("$dir -maxdepth 1"); 508 * 509 * Params implmented: 510 * $dir -> Start the search at this directory 511 * -type d -> return only directories 512 * -type f -> return only files 513 * -maxdepth <n> -> max depth of recursion 514 * -name <pattern> -> search pattern (bash style). Multiple -name param allowed 515 * 516 * @param mixed Either array or string with the command line 517 * @return array Array of found files 518 * 519 */ 520 function find($args) 521 { 522 if (!is_array($args)) { 523 $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); 524 } 525 $dir = array_shift($args); 526 $patterns = array(); 527 $depth = 0; 528 $do_files = $do_dirs = true; 529 for ($i = 0; $i < count($args); $i++) { 530 switch ($args[$i]) { 531 case '-type': 532 if (in_array($args[$i+1], array('d', 'f'))) { 533 if ($args[$i+1] == 'd') { 534 $do_files = false; 535 } else { 536 $do_dirs = false; 537 } 538 } 539 $i++; 540 break; 541 case '-name': 542 if (OS_WINDOWS) { 543 if ($args[$i+1]{0} == '\\') { 544 // prepend drive 545 $args[$i+1] = addslashes(substr(getcwd(), 0, 2) . $args[$i + 1]); 546 } 547 // escape path separators to avoid PCRE problems 548 $args[$i+1] = str_replace('\\', '\\\\', $args[$i+1]); 549 } 550 $patterns[] = "(" . preg_replace(array('/\./', '/\*/'), 551 array('\.', '.*', ), 552 $args[$i+1]) 553 . ")"; 554 $i++; 555 break; 556 case '-maxdepth': 557 $depth = $args[$i+1]; 558 break; 559 } 560 } 561 $path = System::_dirToStruct($dir, $depth); 562 if ($do_files && $do_dirs) { 563 $files = array_merge($path['files'], $path['dirs']); 564 } elseif ($do_dirs) { 565 $files = $path['dirs']; 566 } else { 567 $files = $path['files']; 568 } 569 if (count($patterns)) { 570 $patterns = implode('|', $patterns); 571 $ret = array(); 572 for ($i = 0; $i < count($files); $i++) { 573 if (preg_match("#^$patterns\$#", $files[$i])) { 574 $ret[] = $files[$i]; 575 } 576 } 577 return $ret; 578 } 579 return $files; 580 } 581 } 582 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |