autoload.wholeClassCache.inc.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2008-2009 by Konstantin V. Arkhipov                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00012     // we must duplicate this one here, otherwise any fail will be silent
00013     class BaseException extends Exception
00014     {
00015         public function __toString()
00016         {
00017             return
00018                 "[$this->message] in: \n".
00019                 $this->getTraceAsString();
00020         }
00021     }
00022     
00031     /* void */ function __autoload($classname)
00032     {
00033         static $path = null;
00034         static $checksum = null;
00035         static $included = array();
00036         
00037         if (strpos($classname, "\0") !== false) {
00038             /* are you sane? */
00039             return;
00040         }
00041         
00042         $currentPath = get_include_path();
00043         
00044         if ($currentPath != $path) {
00045             $checksum = crc32($currentPath.ONPHP_VERSION);
00046             $path = $currentPath;
00047         }
00048         
00049         $cacheFile = ONPHP_CLASS_CACHE.$checksum.'.occ';
00050         
00051         if (!isset($included[$cacheFile])) {
00052             try {
00053                 include $cacheFile;
00054                 $included[$cacheFile] = true;
00055             } catch (BaseException $e) {
00056                 /* ignore */
00057             }
00058         }
00059         
00060         if (!class_exists($classname)) {
00061             static $pid = null;
00062             
00063             if (!$pid) {
00064                 $pid = getmypid();
00065                 
00066                 register_shutdown_function('__autoload_cleanup');
00067             }
00068             
00069             try {
00070                 $classPath = null;
00071                 
00072                 foreach (
00073                     explode(PATH_SEPARATOR, get_include_path())
00074                     as $directory
00075                 ) {
00076                     $location = $directory.'/'.$classname.EXT_CLASS;
00077                     
00078                     if (is_readable($location)) {
00079                         $classPath = $location;
00080                         break;
00081                     }
00082                 }
00083                 
00084                 if (!$classPath)
00085                     throw new BaseException('failed to find requested class');
00086                 
00087                 $class = file_get_contents($classPath);
00088                 
00089                 eval('?>'.$class);
00090             } catch (BaseException $e) {
00091                 return __autoload_failed($classname, $e->getMessage());
00092             }
00093             
00094             file_put_contents($cacheFile.'-'.$pid, $class, FILE_APPEND);
00095             
00096             $included[$cacheFile] = true;
00097         }
00098     }
00099     
00100     /* void */ function __autoload_cleanup()
00101     {
00102         $pid = getmypid();
00103         
00104         if ($paths = glob(ONPHP_CLASS_CACHE.'*-'.$pid, GLOB_NOSORT)) {
00105             foreach ($paths as $file) {
00106                 rename($file, ONPHP_CLASS_CACHE.basename($file, '-'.$pid));
00107             }
00108         }
00109     }
00110 ?>