| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 | 
							- <?php
 
- class LtAutoloader
 
- {
 
- 	public $conf = array(
 
- 	/**
 
- 	 * 是否自动加载定义了函数的文件
 
- 	 *
 
- 	 * 可选项: 
 
- 	 * # true   自动加载 
 
- 	 * # false  跳过函数,只自动加载定义了class或者interface的文件
 
- 	 */
 
- 		"load_function" => true,
 
- 	/**
 
- 	 * 要扫描的文件类型
 
- 	 *
 
- 	 * 若该属性设置为array("php","inc","php3"), 
 
- 	 * 则扩展名为"php","inc","php3"的文件会被扫描, 
 
- 	 * 其它扩展名的文件会被忽略
 
- 	 */
 
- 		"allow_file_extension" => array("php", "inc"),
 
- 	/**
 
- 	 * 不扫描的目录
 
- 	 *
 
- 	 * 若该属性设置为array(".svn", ".setting"), 
 
- 	 * 则所有名为".setting"的目录也会被忽略
 
- 	 */
 
- 		"skip_dir_names" => array(".svn"),
 
- 	);
 
- 	public $storeHandle;
 
- 	public $autoloadPath;
 
- 	protected $functionFileMapping;
 
- 	protected $fileStore;
 
- 	public function init()
 
- 	{
 
- 		if (!is_object($this->storeHandle))
 
- 		{
 
- 			$this->storeHandle = new LtStoreMemory;
 
- 			$this->fileStore = new LtStoreFile;
 
- 			$this->fileStore->prefix = 'LtAutoloader-token-cache';
 
- 			$this->fileStore->useSerialize = true;
 
- 			$this->fileStore->init();
 
- 		}
 
- 		// Whether scanning directory
 
- 		if (0 == $this->storeHandle->get(".class_total") && 0 == $this->storeHandle->get(".function_total"))
 
- 		{
 
- 			$this->storeHandle->add(".class_total", 0);
 
- 			$this->storeHandle->add(".function_total", 0);
 
- 			$this->storeHandle->add(".functions", array(), 0);
 
- 			$autoloadPath = $this->preparePath($this->autoloadPath);
 
- 			foreach($autoloadPath as $key => $path)
 
- 			{
 
- 				if (is_file($path))
 
- 				{
 
- 					$this->addFileMap($path);
 
- 					unset($autoloadPath[$key]);
 
- 				}
 
- 			}
 
- 			$this->scanDirs($autoloadPath);
 
- 			unset($autoloadPath);
 
- 		}
 
- 		// Whether loading function files
 
- 		if ($this->conf["load_function"])
 
- 		{
 
- 			$this->loadFunction();
 
- 		}
 
- 		spl_autoload_register(array($this, "loadClass"));
 
- 	}
 
- 	public function loadFunction()
 
- 	{
 
- 		if ($functionFiles = $this->storeHandle->get(".functions"))
 
- 		{
 
- 			foreach ($functionFiles as $functionFile)
 
- 			{
 
- 				include($functionFile);
 
- 			}
 
- 		}
 
- 	}
 
- 	public function loadClass($className)
 
- 	{
 
- 		if ($classFile = $this->storeHandle->get(strtolower($className)))
 
- 		{
 
- 			include($classFile);
 
- 		}
 
- 	}
 
- 	protected function convertPath($path)
 
- 	{
 
- 		$path = str_replace("\\", "/", $path);
 
- 		if (!is_readable($path))
 
- 		{
 
- 			trigger_error("Directory is not exists/readable: {$path}");
 
- 			return false;
 
- 		}
 
- 		$path = rtrim(realpath($path), '\\/');
 
- 		if ("WINNT" != PHP_OS && preg_match("/\s/i", $path))
 
- 		{
 
- 			trigger_error("Directory contains space/tab/newline is not supported: {$path}");
 
- 			return false;
 
- 		}
 
- 		return $path;
 
- 	}
 
- 	/**
 
- 	 * The string or an Multidimensional array into a one-dimensional array
 
- 	 *
 
- 	 * @param array $ or string $var
 
- 	 * @return array one-dimensional array
 
- 	 */
 
- 	protected function preparePath($var)
 
- 	{
 
- 		$ret = array();
 
- 		if (!is_array($var))
 
- 		{
 
- 			$var = array($var);
 
- 		}
 
- 		$i = 0;
 
- 		while (isset($var[$i]))
 
- 		{
 
- 			if (!is_array($var[$i]) && $path = $this->convertPath($var[$i]))
 
- 			{
 
- 				$ret[] = $path;
 
- 			}
 
- 			else
 
- 			{
 
- 				foreach($var[$i] as $v)
 
- 				{
 
- 					$var[] = $v;
 
- 				}
 
- 			}
 
- 			unset($var[$i]);
 
- 			$i ++;
 
- 		}
 
- 		return $ret;
 
- 	}
 
- 	/**
 
- 	 * Using iterative algorithm scanning subdirectories
 
- 	 * save autoloader filemap
 
- 	 *
 
- 	 * @param array $dirs one-dimensional
 
- 	 * @return
 
- 	 */
 
- 	protected function scanDirs($dirs)
 
- 	{
 
- 		$i = 0;
 
- 		while (isset($dirs[$i]))
 
- 		{
 
- 			$dir = $dirs[$i];
 
- 			$files = scandir($dir);
 
- 			foreach ($files as $file)
 
- 			{
 
- 				if (in_array($file, array(".", "..")) || in_array($file, $this->conf["skip_dir_names"]))
 
- 				{
 
- 					continue;
 
- 				}
 
- 				$currentFile = $dir . DIRECTORY_SEPARATOR . $file;
 
- 				if (is_file($currentFile))
 
- 				{
 
- 					$this->addFileMap($currentFile);
 
- 				}
 
- 				else if (is_dir($currentFile))
 
- 				{
 
- 					// if $currentFile is a directory, pass through the next loop.
 
- 					$dirs[] = $currentFile;
 
- 				}
 
- 				else
 
- 				{
 
- 					trigger_error("$currentFile is not a file or a directory.");
 
- 				}
 
- 			} //end foreach
 
- 			unset($dirs[$i]);
 
- 			$i ++;
 
- 		} //end while
 
- 	}
 
- 	protected function parseLibNames($src)
 
- 	{
 
- 		$libNames = array();
 
- 		$tokens = token_get_all($src);
 
- 		$level = 0;
 
- 		$found = false;
 
- 		$name = '';
 
- 		foreach ($tokens as $token)
 
- 		{
 
- 			if (is_string($token))
 
- 			{
 
- 				if ('{' == $token)
 
- 				{
 
- 					$level ++;
 
- 				}
 
- 				else if ('}' == $token)
 
- 				{
 
- 					$level --;
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				list($id, $text) = $token;
 
- 				if (T_CURLY_OPEN == $id || T_DOLLAR_OPEN_CURLY_BRACES == $id)
 
- 				{
 
- 					$level ++;
 
- 				}
 
- 				if (0 < $level)
 
- 				{
 
- 					continue;
 
- 				}
 
- 				switch ($id)
 
- 				{
 
- 					case T_STRING:
 
- 						if ($found)
 
- 						{
 
- 							$libNames[strtolower($name)][] = $text;
 
- 							$found = false;
 
- 						}
 
- 						break;
 
- 					case T_CLASS:
 
- 					case T_INTERFACE:
 
- 					case T_FUNCTION:
 
- 						$found = true;
 
- 						$name = $text;
 
- 						break;
 
- 				}
 
- 			}
 
- 		}
 
- 		return $libNames;
 
- 	}
 
- 	protected function addClass($className, $file)
 
- 	{
 
- 		$key = strtolower($className);
 
- 		if ($existedClassFile = $this->storeHandle->get($key))
 
- 		{
 
- 			trigger_error("duplicate class [$className] found in:\n$existedClassFile\n$file\n");
 
- 			return false;
 
- 		}
 
- 		else
 
- 		{
 
- 			$this->storeHandle->add($key, $file);
 
- 			$this->storeHandle->update(".class_total", $this->storeHandle->get(".class_total") + 1);
 
- 			return true;
 
- 		}
 
- 	}
 
- 	protected function addFunction($functionName, $file)
 
- 	{
 
- 		$functionName = strtolower($functionName);
 
- 		if (isset($this->functionFileMapping[$functionName]))
 
- 		{
 
- 			$existedFunctionFile = $this->functionFileMapping[$functionName];
 
- 			trigger_error("duplicate function [$functionName] found in:\n$existedFunctionFile\n$file\n");
 
- 			return false;
 
- 		}
 
- 		else
 
- 		{
 
- 			$this->functionFileMapping[$functionName] = $file;
 
- 			$this->storeHandle->update(".functions", array_unique(array_values($this->functionFileMapping)));
 
- 			$this->storeHandle->update(".function_total", count($this->functionFileMapping));
 
- 			return true;
 
- 		}
 
- 	}
 
- 	protected function addFileMap($file)
 
- 	{
 
- 		if (!in_array(pathinfo($file, PATHINFO_EXTENSION), $this->conf["allow_file_extension"]))
 
- 		{
 
- 			return false;
 
- 		}
 
- 		$libNames = array();
 
- 		if ($this->fileStore instanceof LtStore)
 
- 		{
 
- 			$cachedFileLastModified = (int) @filemtime($this->fileStore->getFilePath($file));
 
- 			if ($cachedFileLastModified < filemtime($file) || !is_array(($libNames = $this->fileStore->get($file))))
 
- 			{
 
- 				$libNames = $this->parseLibNames(trim(file_get_contents($file)));
 
- 				if (0 < $cachedFileLastModified)
 
- 				{
 
- 					$this->fileStore->update($file, $libNames);
 
- 				}
 
- 				else
 
- 				{
 
- 					$this->fileStore->add($file, $libNames);
 
- 				}
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			$libNames = $this->parseLibNames(trim(file_get_contents($file)));
 
- 		}
 
- 		foreach ($libNames as $libType => $libArray)
 
- 		{
 
- 			$method = "function" == $libType ? "addFunction" : "addClass";
 
- 			foreach ($libArray as $libName)
 
- 			{
 
- 				$this->$method($libName, $file);
 
- 			}
 
- 		}
 
- 		return true;
 
- 	}
 
- }
 
 
  |