[ Index ] |
PHP Cross Reference of PHK Manager |
[Summary view] [Print] [Text view]
1 <?php 2 //============================================================================= 3 // 4 // Copyright Francois Laupretre <phk@tekwire.net> 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 // 18 //============================================================================= 19 /** 20 * @copyright Francois Laupretre <phk@tekwire.net> 21 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, V 2.0 22 * @category PHK 23 * @package PHK 24 *///========================================================================== 25 //============================================================================= 26 /** 27 * PHK utility functions 28 * 29 * Static-only 30 * API status: Private 31 * Included in the PHK PHP runtime: Yes 32 * Implemented in the extension: No 33 *///========================================================================== 34 35 namespace PHK\Tools { 36 37 // Ensures PHP_VERSION_ID is set. If version < 5.2.7, emulate. 38 39 if (!defined('PHP_VERSION_ID')) 40 { 41 $v = explode('.',PHP_VERSION); 42 define('PHP_VERSION_ID', ($v[0]*10000+$v[1]*100+$v[2])); 43 } 44 45 //============================================================================= 46 47 if (!class_exists('PHK\Tools\Util',false)) 48 { 49 //============================================================================ 50 51 class Util // Static only 52 { 53 //----- 54 55 private static $verbose=true; 56 57 public static function msg($msg) 58 { 59 if (self::$verbose) echo $msg."\n"; 60 } 61 62 //----- 63 64 public static function varType($var) 65 { 66 return is_object($var) ? 'object '.get_class($var) : gettype($var); 67 } 68 69 //----- 70 // Keep in sync with \Phool\Util 71 72 public static function envIsWeb() 73 { 74 return (php_sapi_name()!='cli'); 75 } 76 77 //---- 78 // Keep in sync with \Phool\Util 79 80 public static function envIsWindows() 81 { 82 return (substr(PHP_OS, 0, 3) == 'WIN'); 83 } 84 85 //---- 86 87 public static function fileSuffix($filename) 88 { 89 $dotpos=strrpos($filename,'.'); 90 if ($dotpos===false) return ''; 91 92 return strtolower(substr($filename,$dotpos+1)); 93 } 94 95 //--------- 96 // Warning: This is not the same code as \Automap\Map::combinePath() and 97 // \Phool\File::combinePath(). Those were modified to support providing 98 // an absolute $rpath. So, the behavior is different if $rpath starts with '/'. 99 // 100 // Combines a base directory and a relative path. If the base directory is 101 // '.', returns the relative part without modification 102 // Use '/' separator on stream-wrapper URIs 103 104 public static function combinePath($dir,$rpath) 105 { 106 if ($dir=='.' || $dir=='') return $rpath; 107 $rpath=trim($rpath,'/'); 108 $rpath=trim($rpath,'\\'); 109 110 $separ=(strpos($dir,':')!==false) ? '/' : DIRECTORY_SEPARATOR; 111 if (($dir==='/') || ($dir==='\\')) $separ=''; 112 else 113 { 114 $c=substr($dir,-1,1); 115 if (($c==='/') || ($c=='\\')) $dir=rtrim($dir,$c); 116 } 117 118 return (($rpath==='.') ? $dir : $dir.$separ.$rpath); 119 } 120 121 //--------------------------------- 122 /** 123 * Adds or removes a trailing separator in a path 124 * 125 * @param string $path Input 126 * @param bool $flag true: add trailing sep, false: remove it 127 * @return bool The result path 128 */ 129 130 public static function trailingSepar($path, $separ) 131 { 132 $path=rtrim($path,'/\\'); 133 if ($path=='') return '/'; 134 if ($separ) $path=$path.'/'; 135 return $path; 136 } 137 138 //--------------------------------- 139 /** 140 * Determines if a given path is absolute or relative 141 * 142 * @param string $path The path to check 143 * @return bool True if the path is absolute, false if relative 144 */ 145 146 public static function isAbsolutePath($path) 147 { 148 return ((strpos($path,':')!==false) 149 ||(strpos($path,'/')===0) 150 ||(strpos($path,'\\')===0)); 151 } 152 153 //--------------------------------- 154 /** 155 * Build an absolute path from a given (absolute or relative) path 156 * 157 * If the input path is relative, it is combined with the current working 158 * directory. 159 * 160 * @param string $path The path to make absolute 161 * @param bool $separ True if the resulting path must contain a trailing separator 162 * @return string The resulting absolute path 163 */ 164 165 public static function mkAbsolutePath($path,$separ=false) 166 { 167 if (!self::isAbsolutePath($path)) $path=self::combinePath(getcwd(),$path); 168 return self::trailingSepar($path,$separ); 169 } 170 171 //--------- 172 // Adapted from PEAR 173 174 public static function loadExtension($ext) 175 { 176 if (extension_loaded($ext)) return; 177 178 if (PHP_OS == 'AIX') $suffix = 'a'; 179 else $suffix = PHP_SHLIB_SUFFIX; 180 181 @dl('php_'.$ext.'.'.$suffix) || @dl($ext.'.'.$suffix); 182 183 if (!extension_loaded($ext)) throw new \Exception("$ext: Cannot load extension"); 184 } 185 186 //--------- 187 // Require several extensions. Allows to list every extensions that are not 188 // present. 189 190 public static function loadExtensions($ext_list) 191 { 192 $failed_ext=array(); 193 foreach($ext_list as $ext) 194 { 195 try { self::loadExtension($ext); } 196 catch (\Exception $e) { $failed_ext[]=$ext; } 197 } 198 if (count($failed_ext)) 199 throw new \Exception('Cannot load the following required extension(s): ' 200 .implode(' ',$failed_ext)); 201 } 202 203 //--------- 204 // Replacement for substr() 205 // Difference : returns '' instead of false (when index out of range) 206 207 public static function substr($buf,$position,$len=NULL) 208 { 209 $str=is_null($len) ? substr($buf,$position) : substr($buf,$position,$len); 210 if ($str===false) $str=''; 211 return $str; 212 } 213 214 //--------- 215 // This function must be called before every file access 216 // Starting with version 5.3.0, 'magic_quotes_runtimes' is deprecated and 217 // mustn't be used any more. 218 219 private static $mqr_exists=null; 220 private static $mqr_level=0; 221 private static $mqr_save; 222 223 public static function disableMQR() 224 { 225 if (is_null(self::$mqr_exists)) 226 self::$mqr_exists=((PHP_VERSION_ID < 50300) 227 && function_exists('set_magic_quotes_runtime')); 228 229 if (!self::$mqr_exists) return; 230 231 if (self::$mqr_level==0) 232 { 233 self::$mqr_save=get_magic_quotes_runtime(); 234 set_magic_quotes_runtime(0); 235 } 236 self::$mqr_level++; 237 } 238 239 //--------- 240 // This function must be called after every file access 241 242 public static function restoreMQR() 243 { 244 if (is_null(self::$mqr_exists)) 245 self::$mqr_exists=((PHP_VERSION_ID < 50300) 246 && function_exists('set_magic_quotes_runtime')); 247 248 if (!self::$mqr_exists) return; 249 250 self::$mqr_level--; 251 if (self::$mqr_level==0) set_magic_quotes_runtime(self::$mqr_save); 252 } 253 254 //--------- 255 // Converts a timestamp to a string 256 // @ to suppress warnings about system timezone 257 258 public static function timeString($time=null) 259 { 260 if ($time=='unlimited') return $time; 261 if (is_null($time)) $time=time(); 262 return @strftime('%d-%b-%Y %H:%M %z',$time); 263 } 264 265 //--------- 266 // HTTP mode only: Compute the base URL we were called with 267 268 public static function httpBaseURL() 269 { 270 if (!self::envIsWeb()) return ''; 271 272 if (!isset($_SERVER['PATH_INFO'])) return $_SERVER['PHP_SELF']; 273 274 $phpself=$_SERVER['PHP_SELF']; 275 $slen=strlen($phpself); 276 277 $pathinfo=$_SERVER['PATH_INFO']; 278 $ilen=strlen($pathinfo); 279 280 // Remove PATH_INFO from PHP_SELF if it is at the end. Don't know 281 // which config does this, but some servers put it, some don't. 282 283 if (($slen > $ilen) && (substr($phpself,$slen-$ilen)==$pathinfo)) 284 $phpself=substr($phpself,0,$slen-$ilen); 285 286 return $phpself; 287 } 288 289 //--------------------------------- 290 // Sends an HTTP 301 redirection 291 292 public static function http301Redirect($path) 293 { 294 header('Location: http://'.$_SERVER['HTTP_HOST'].self::httpBaseURL().$path); 295 header('HTTP/1.1 301 Moved Permanently'); 296 exit(0); 297 } 298 299 //--------------------------------- 300 // Sends an HTTP 404 failure 301 302 public static function http404Fail() 303 { 304 header("HTTP/1.0 404 Not Found"); 305 exit(1); 306 } 307 308 //--------------------------------- 309 // Sends an HTTP 403 failure 310 311 public static function http403Fail() 312 { 313 header("HTTP/1.0 403 Forbidden"); 314 exit(1); 315 } 316 317 //----- 318 319 public static function bool2str($cond) 320 { 321 return $cond ? 'Yes' : 'No'; 322 } 323 324 //--------- 325 326 public static function readFile($path) 327 { 328 if (($data=@file_get_contents($path))===false) 329 throw new \Exception($path.': Cannot get file content'); 330 return $data; 331 } 332 333 //--------- 334 // Throws exceptions and removes '.' and '..' 335 336 public static function scandir($path) 337 { 338 if (($subnames=scandir($path))===false) 339 throw new \Exception($path.': Cannot read directory'); 340 341 $a=array(); 342 foreach($subnames as $f) 343 if (($f!='.') && ($f!='..')) $a[]=$f; 344 345 return $a; 346 } 347 348 //--------- 349 350 public static function trace($msg) 351 { 352 if (($tfile=getenv('PHK_TRACE_FILE')) !== false) 353 { 354 // Append message to trace file 355 if (($fp=fopen($tfile,'a'))===false) throw new \Exception($tfile.': Cannot open trace file'); 356 fwrite($fp,self::timeString().': '.$msg."\n"); 357 fclose($fp); 358 } 359 } 360 361 //--------- 362 // $start=microtime() float 363 364 public static function deltaMS($start) 365 { 366 $delta=microtime(true)-$start; 367 368 return round($delta*1000,2).' ms'; 369 } 370 371 //--------- 372 373 public static function mkArray($data) 374 { 375 if (is_null($data)) return array(); 376 if (!is_array($data)) $data=array($data); 377 return $data; 378 } 379 380 //--------- 381 382 public static function displaySlowPath() 383 { 384 if (getenv('PHK_DEBUG_SLOW_PATH')!==false) 385 { 386 $html=self::envIsWeb(); 387 388 if (isset($GLOBALS['__PHK_SLOW_PATH'])) 389 $data="Slow path entered at:\n".$GLOBALS['__PHK_SLOW_PATH']; 390 else $data="Fast path OK\n"; 391 392 \PHK::infoSection($html,'Fast path result'); 393 394 if ($html) echo "<pre>"; 395 echo $data; 396 if ($html) echo "/<pre>"; 397 } 398 } 399 400 //--------- 401 402 public static function slowPath() 403 { 404 if ((getenv('PHK_DEBUG_SLOW_PATH')!==false) 405 && (!isset($GLOBALS['__PHK_SLOW_PATH']))) 406 { 407 $e=new \Exception(); 408 $GLOBALS['__PHK_SLOW_PATH']=$e->getTraceAsString(); 409 } 410 } 411 412 //----- 413 /** 414 * Sends an \Exception with a message starting with 'Format error' 415 * 416 * @param string $msg Message to send 417 * @return void 418 * @throws \Exception 419 */ 420 421 public static function formatError($msg) 422 { 423 throw new \Exception('Format error: '.$msg); 424 } 425 426 //--------------------------------- 427 // Utility functions called by PHK\Mgr. When using the accelerator, this 428 // data is persistent. So, retrieving it to populate the cache can be done 429 // in PHP. 430 431 public static function getMinVersion($mnt,$caching) 432 { 433 return \PHK\Stream\Wrapper::getFile(false,\PHK\Mgr::commandURI($mnt 434 ,'magicField&name=mv'),$mnt,'magicField',array('name' => 'mv'),'' 435 ,$caching); 436 } 437 438 public static function getOptions($mnt,$caching) 439 { 440 return unserialize(\PHK\Stream\Wrapper::getFile(false,\PHK\Mgr::sectionURI($mnt 441 ,'OPTIONS'),$mnt,'section',array('name' => 'OPTIONS'),'',$caching)); 442 } 443 444 public static function getBuildInfo($mnt,$caching) 445 { 446 return unserialize(\PHK\Stream\Wrapper::getFile(false,\PHK\Mgr::sectionURI($mnt 447 ,'BUILD_INFO'),$mnt,'section',array('name' => 'BUILD_INFO'),'',$caching)); 448 } 449 450 //--------------------------------- 451 452 public static function callMethod($object,$method,$args) 453 { 454 // Special care to avoid endless loops 455 456 if (!method_exists($object,$method)) 457 throw new \Exception("$method: calling non existing method"); 458 459 return call_user_func_array(array($object,$method),$args); 460 } 461 462 //--------------------------------- 463 464 public static function runWebInfo($phk) 465 { 466 $phk->proxy()->crcCheck(); //-- check CRC before running webinfo 467 $phkw=new \PHK\Web\Info($phk); 468 $phkw->run(); 469 } 470 471 //--------------------------------- 472 473 public static function atomicWrite($path,$data) 474 { 475 $tmpf=tempnam(dirname($path),'tmp_'); 476 477 if (file_put_contents($tmpf,$data)!=strlen($data)) 478 throw new \Exception($tmpf.": Cannot write"); 479 480 // Windows does not support renaming to an existing file (looses atomicity) 481 482 if (self::envIsWindows()) @unlink($path); 483 484 if (!rename($tmpf,$path)) 485 { 486 unlink($tmpf); 487 throw new \Exception($path.': Cannot replace file'); 488 } 489 } 490 491 //--------------------------------- 492 /** 493 * Computes a string uniquely identifying a given path on this host. 494 * 495 * Mount point unicity is based on a combination of device+inode+mtime. 496 * 497 * On systems which don't supply a valid inode number (eg Windows), we 498 * maintain a fake inode table, whose unicity is based on the path filtered 499 * through realpath(). It is not perfect because I am not sure that realpath 500 * really returns a unique 'canonical' path, but this is best solution I 501 * have found so far. 502 * 503 * @param string $path The path to be mounted 504 * @return string the computed mount point 505 * @throws \Exception 506 */ 507 508 private static $simul_inode_array=array(); 509 private static $simul_inode_index=1; 510 511 public static function pathUniqueID($prefix,$path,&$mtime) 512 { 513 if (($s=@stat($path))===false) throw new \Exception("$path: File not found"); 514 515 $dev=$s[0]; 516 $inode=$s[1]; 517 $mtime=$s[9]; 518 519 if ($inode==0) // This system does not support inodes 520 { 521 $rpath=realpath($path); 522 if ($rpath === false) throw new \Exception("$path: Cannot compute realpath"); 523 524 if (isset(self::$simul_inode_array[$rpath])) 525 $inode=self::$simul_inode_array[$rpath]; 526 else 527 { // Create a new slot 528 $inode=self::$simul_inode_index++; 529 self::$simul_inode_array[$rpath]=$inode; 530 } 531 } 532 533 return sprintf('%s_%X_%X_%X',$prefix,$dev,$inode,$mtime); 534 } 535 536 //--- 537 } // End of class 538 //=========================================================================== 539 } // End of class_exists 540 //=========================================================================== 541 } // End of namespace 542 //=========================================================================== 543 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jun 4 18:33:15 2015 | Cross-referenced by PHPXref 0.7.1 |