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