一个PHP文件如何使用另一个提供的类
我需要做一个包含PHP类的任务和一些应该运行该类的示例代码。代码:贝娄 autoloader.php一个PHP文件如何使用另一个提供的类,php,oop,Php,Oop,我需要做一个包含PHP类的任务和一些应该运行该类的示例代码。代码:贝娄 autoloader.php <?php /** * A basic PSR style autoloader */ class AutoLoader { protected $dir; protected $ext; public function __construct($dir, $ext = '.php') { $this->dir = rtrim(
<?php
/**
* A basic PSR style autoloader
*/
class AutoLoader
{
protected $dir;
protected $ext;
public function __construct($dir, $ext = '.php')
{
$this->dir = rtrim($dir, DIRECTORY_SEPARATOR);
$this->ext = $ext;
}
public static function register($dir, $ext = '.php')
{
$autoloader = new static($dir, $ext);
spl_autoload_register([$autoloader, 'load']);
return $autoloader;
}
public function load($class)
{
$dir = $this->dir;
if ($ns = $this->get_namespace($class)) {
$dir .= DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $ns);
}
$inc_file = $dir.DIRECTORY_SEPARATOR.$this->get_class($class).$this->ext;
if (file_exists($inc_file)) {
require_once $inc_file;
}
}
// Borrowed from github.com/borisguery/Inflexible
protected static function get_class($value)
{
$className = trim($value, '\\');
if ($lastSeparator = strrpos($className, '\\')) {
$className = substr($className, 1 + $lastSeparator);
}
return $className;
}
// Borrowed from github.com/borisguery/Inflexible
public static function get_namespace($fqcn)
{
if ($lastSeparator = strrpos($fqcn, '\\')) {
return trim(substr($fqcn, 0, $lastSeparator + 1), '\\');
}
return '';
}
}
AutoLoader::register('src')代码>实例化了的新实例
Autoload
类,提供src
目录作为参数,然后
spl_autoload_register([$autoloader, 'load']);
将Autoloader
类中的load
方法注册为
实施
现在,当您尝试使用中未定义的类时
范围,因为您已注册自动加载器,它将尝试
使用Autoloader
中的load
方法在src
目录中查找该类
班级。如果自动加载程序找到该类,它将使用PHP的include
方法将类引入范围,以便
实例化它的一个新实例
您提到的方法在
\Candidate\BoxPacker\DeveloperTestPacker
类
1) 什么是AutoLoader::register('src');是吗
它创建新的AutoLoader类,并将类方法load
注册为AutoLoader,相当于
$autoloader = new AutoLoader('src');
spl_autoload_register([$autoloader, 'load']);
从现在起,新自动加载器已注册(方法$autoloader->load()
为新自动加载器)
src
是类所在的文件夹
看
2) $packer=new\Candidate\BoxPacker\DeveloperTestPacker();创建一个
新的封隔器对象,但这个对象是什么?autoloader.php文件
没有提到
\候选\BoxPacker\DeveloperTestPacker()
$packer
是从src/Candidate/BoxPacker/DeveloperTestPacker.php自动加载的类
3) 行$packer->addbox($box)$包装工->附加项($items);,
$packer->pack();seam调用addbox()、addItems()和
$packer引用的类实例的pack()
请参见src/Candidate/BoxPacker/DeveloperTestPacker.php
重新审视这一点
您使用的是框架还是其他自动加载程序
禁用此代码并查看它在没有或没有的情况下是否可以工作
需要一次“AutoLoader.php”;
自动加载程序::寄存器('src')
如果代码在没有这个自动加载程序的情况下工作,那么类将按其调用的命名空间存在
在本例中,请阅读更多有关名称空间和其他方面的信息
PS:创建新类(我认为)避免自动加载程序。1)您将文件夹src注册为要查看的文件夹(查找要包含的类文件)
2) 不能用你提供的回答
3) 同样的事情
这个脚本的目的是避免使用include,只需编写新的MyClass();如果php抛出错误,它将查找src文件夹,试图找到拥有MyClass类的文件
我更喜欢我的(源代码:)-->,因为它会创建一个缓存文件。从性能角度来看,它更适合
<?php
class ExtensionFilterIteratorDecorator extends FilterIterator {
private $_ext;
public function accept() {
if (substr($this->current(), -1 * strlen($this->_ext)) === $this->_ext) {
return is_readable($this->current());
}
return false;
}
public function setExtension($pExt) {
$this->_ext = $pExt;
}
}
class DirectoriesAutoloaderException extends Exception {
}
class DirectoriesAutoloader {
//--- Singleton
private function __construct() {
}
private static $_instance = false;
public static function instance($pTmpPath) {
if (self::$_instance === false) {
self::$_instance = new DirectoriesAutoloader();
self::$_instance->setCachePath($pTmpPath);
}
return self::$_instance;
}
//--- /Singleton
//--- Cache
private $_cachePath;
public function setCachePath($pTmp) {
if (!is_dir($pTmp))
{
throw new DirectoriesAutoloaderException('Cannot find in given CachePath [' . $pTmp . ']');
}
if (!is_writable($pTmp)) {
throw new DirectoriesAutoloaderException('Cannot write in given CachePath [' . $pTmp . ']');
}
$this->_cachePath = $pTmp;
}
//--- /Cache
//--- Autoload
public function autoload($pClassName) {
//On regarde si on connais la classe
if ($this->_loadClass($pClassName)) {
return true;
}
//Si on a le droit de tenter la regénération du fichier d'autoload, on retente l'histoire
if ($this->_canRegenerate) {
$this->_canRegenerate = false; //pour éviter que l'on
$this->_includesAll();
$this->_saveInCache();
return $this->autoload($pClassName);
}
//on a vraiment rien trouvé.
return false;
}
private $_canRegenerate = true;
//--- /Autoload
/**
* Recherche de toutes les classes dans les répertoires donnés
*/
private function _includesAll() {
//Inclusion de toute les classes connues
foreach ($this->_directories as $directory => $recursive) {
$directories = new AppendIterator ();
//On ajoute tous les chemins à parcourir
if ($recursive) {
$directories->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)));
} else {
$directories->append(new DirectoryIterator($directory));
}
//On va filtrer les fichiers php depuis les répertoires trouvés.
$files = new ExtensionFilterIteratorDecorator($directories);
$files->setExtension('.php');
foreach ($files as $fileName) {
$classes = $this->_extractClasses((string) $fileName);
foreach ($classes as $className => $fileName) {
$this->_classes[strtolower($className)] = $fileName;
}
}
}
}
/**
* Extraction des classes & interfaces d'un fichier
*/
private function _extractClasses($pFileName) {
$toReturn = array();
$tokens = token_get_all(file_get_contents($pFileName, false));
$tokens = array_filter($tokens, 'is_array');
$classHunt = false;
foreach ($tokens as $token) {
if ($token[0] === T_INTERFACE || $token[0] === T_CLASS) {
$classHunt = true;
continue;
}
if ($classHunt && $token[0] === T_STRING) {
$toReturn[$token[1]] = $pFileName;
$classHunt = false;
}
}
return $toReturn;
}
private $_classes = array();
private function _saveIncache() {
$toSave = '<?php $classes = ' . var_export($this->_classes, true) . '; ?>';
file_put_contents($this->_cachePath . 'directoriesautoloader.cache.php', $toSave);
}
/**
* Tente de charger une classe
*/
private function _loadClass($pClassName) {
$className = strtolower($pClassName);
if (count($this->_classes) === 0) {
if (is_readable($this->_cachePath . 'directoriesautoloader.cache.php')) {
require ($this->_cachePath . 'directoriesautoloader.cache.php');
$this->_classes = $classes;
}
}
if (isset($this->_classes[$className])) {
require_once ($this->_classes[$className]);
return true;
}
return false;
}
/**
* Ajoute un répertoire a la liste de ceux à autoloader
*/
public function addDirectory($pDirectory, $pRecursive = true) {
if (!is_readable($pDirectory)) {
throw new DirectoriesAutoloaderException('Cannot read from [' . $pDirectory . ']');
}
$this->_directories[$pDirectory] = $pRecursive ? true : false;
return $this;
}
private $_directories = array();
}
<?php
class ExtensionFilterIteratorDecorator extends FilterIterator {
private $_ext;
public function accept() {
if (substr($this->current(), -1 * strlen($this->_ext)) === $this->_ext) {
return is_readable($this->current());
}
return false;
}
public function setExtension($pExt) {
$this->_ext = $pExt;
}
}
class DirectoriesAutoloaderException extends Exception {
}
class DirectoriesAutoloader {
//--- Singleton
private function __construct() {
}
private static $_instance = false;
public static function instance($pTmpPath) {
if (self::$_instance === false) {
self::$_instance = new DirectoriesAutoloader();
self::$_instance->setCachePath($pTmpPath);
}
return self::$_instance;
}
//--- /Singleton
//--- Cache
private $_cachePath;
public function setCachePath($pTmp) {
if (!is_dir($pTmp))
{
throw new DirectoriesAutoloaderException('Cannot find in given CachePath [' . $pTmp . ']');
}
if (!is_writable($pTmp)) {
throw new DirectoriesAutoloaderException('Cannot write in given CachePath [' . $pTmp . ']');
}
$this->_cachePath = $pTmp;
}
//--- /Cache
//--- Autoload
public function autoload($pClassName) {
//On regarde si on connais la classe
if ($this->_loadClass($pClassName)) {
return true;
}
//Si on a le droit de tenter la regénération du fichier d'autoload, on retente l'histoire
if ($this->_canRegenerate) {
$this->_canRegenerate = false; //pour éviter que l'on
$this->_includesAll();
$this->_saveInCache();
return $this->autoload($pClassName);
}
//on a vraiment rien trouvé.
return false;
}
private $_canRegenerate = true;
//--- /Autoload
/**
* Recherche de toutes les classes dans les répertoires donnés
*/
private function _includesAll() {
//Inclusion de toute les classes connues
foreach ($this->_directories as $directory => $recursive) {
$directories = new AppendIterator ();
//On ajoute tous les chemins à parcourir
if ($recursive) {
$directories->append(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)));
} else {
$directories->append(new DirectoryIterator($directory));
}
//On va filtrer les fichiers php depuis les répertoires trouvés.
$files = new ExtensionFilterIteratorDecorator($directories);
$files->setExtension('.php');
foreach ($files as $fileName) {
$classes = $this->_extractClasses((string) $fileName);
foreach ($classes as $className => $fileName) {
$this->_classes[strtolower($className)] = $fileName;
}
}
}
}
/**
* Extraction des classes & interfaces d'un fichier
*/
private function _extractClasses($pFileName) {
$toReturn = array();
$tokens = token_get_all(file_get_contents($pFileName, false));
$tokens = array_filter($tokens, 'is_array');
$classHunt = false;
foreach ($tokens as $token) {
if ($token[0] === T_INTERFACE || $token[0] === T_CLASS) {
$classHunt = true;
continue;
}
if ($classHunt && $token[0] === T_STRING) {
$toReturn[$token[1]] = $pFileName;
$classHunt = false;
}
}
return $toReturn;
}
private $_classes = array();
private function _saveIncache() {
$toSave = '<?php $classes = ' . var_export($this->_classes, true) . '; ?>';
file_put_contents($this->_cachePath . 'directoriesautoloader.cache.php', $toSave);
}
/**
* Tente de charger une classe
*/
private function _loadClass($pClassName) {
$className = strtolower($pClassName);
if (count($this->_classes) === 0) {
if (is_readable($this->_cachePath . 'directoriesautoloader.cache.php')) {
require ($this->_cachePath . 'directoriesautoloader.cache.php');
$this->_classes = $classes;
}
}
if (isset($this->_classes[$className])) {
require_once ($this->_classes[$className]);
return true;
}
return false;
}
/**
* Ajoute un répertoire a la liste de ceux à autoloader
*/
public function addDirectory($pDirectory, $pRecursive = true) {
if (!is_readable($pDirectory)) {
throw new DirectoriesAutoloaderException('Cannot read from [' . $pDirectory . ']');
}
$this->_directories[$pDirectory] = $pRecursive ? true : false;
return $this;
}
private $_directories = array();
}
$autoloader = DirectoriesAutoloader::instance($config['base_path'] . 'cache/')->addDirectory($config['base_path'] . 'load')->addDirectory($config['base_path'] . 'site/Modules')->addDirectory($config['base_path'] . 'site/Elements');
spl_autoload_register(array($autoloader, 'autoload'));