带有命名空间的PHP类不能通过spl_autoload_register加载吗? [英] PHP classes with a namespace cannot be loaded via spl_autoload_register?
问题描述
当在类中实现名称空间时,在使用spl_autoload_register
加载类时遇到问题.
I have a problem in loading classes with spl_autoload_register
when a namespace is implemented in a class.
下面的类autoloader
,但是当使用否名称空间时,加载任何类都没有问题,
the class autoloader
below, but I have no problem loading any class when no namespace is used,
class autoloader
{
/**
* Set the property.
*/
public $directory;
public $recursive;
/**
* Receive the supplied data.
* @string $directory
* @array $recursive default: models
*/
public function __construct($directory, $recursive = array('search' => 'models') )
{
# Store the data into the property.
$this->directory = $directory;
$this->recursive = $recursive;
# When using spl_autoload_register() with class methods, it might seem that it can use only public methods, though it can use private/protected methods as well, if registered from inside the class:
spl_autoload_register(array($this,'get_class'));
}
private function get_class($class_name)
{
# List all the class directories in the array.
if ($this->recursive)
{
$array_directories = self::get_recursive_directory($this->directory);
}
else
{
if (is_array($this->directory)) $array_directories = $this->directory;
else $array_directories = array($this->directory);
}
# Set the class file name.
$file_name = 'class_'.strtolower($class_name).'.php';
# Loop the array.
foreach($array_directories as $path_directory)
{
if(file_exists($path_directory.$file_name))
{
# There is no need to use include/require_once. Autoload is a fallback when the system can't find the class you are instantiating.
# If you've already included it once via an autoload then the system knows about it and won't run your autoload method again anyway.
# So, just use the regular include/require - they are faster.
include $path_directory.$file_name;
}
}
}
# However the memory consumption of this can be huge if you have a very large directory tree with only a few matches.
# @source: http://stackoverflow.com/questions/9294543/search-and-list-specific-directories-only
public function get_recursive_directory($directory)
{
# Create an object that allows us to iterate directories recursively.
# Stolen from here:
# http://www.php.net/manual/en/class.recursivedirectoryiterator.php#102587
$iterator = new RecursiveIteratorIterator
(
new RecursiveDirectoryIterator($directory),
RecursiveIteratorIterator::CHILD_FIRST
);
# This will hold the result.
$result = array();
# Loop the directory contents.
foreach ($iterator as $path)
{
# If object is a directory and matches the search term ('models')...
if ($path->isDir() && $path->getBasename() === $this->recursive['search'])
{
# Add it to the result array.
# Must replace the slash in the class - dunno why!
$result[] = str_replace('\\', '/', $path).'/';
//$result[] = (string) $path . '/';
}
}
# Return the result in an array.
return $result;
}
}
例如tag
类
namespace hello;
class tag extends \core
{
}
现在通过autoloader
类加载该类,
# Autoload the classes from the specific folder.
$autoloader = new autoloader("C:/wamp/www/website/local/applications/master/sides/models/", $recursive = false);
# Instantiate the tag.
$tag = new hello\tag($connection);
结果
致命错误:找不到类"hello \ tag" C:\ wamp \ www \ website \ local \ applications \ master \ sides \ views \ tags.php 在第 7
Fatal error: Class 'hello\tag' not found in C:\wamp\www\website\local\applications\master\sides\views\tags.php on line 7
有什么主意如何修复我的autoloader
类,以便无论是否有名称空间都可以加载这些类?
Any idea how I can fix my autoloader
class so that I can load the classes whether there is a namespace or not?
我保存课程和课程名称的文件夹,
The folder where I keep the classes and the class naming,
C:\wamp\www\website\local\applications\master\sides\models\
class_tag.php
class_something.php
推荐答案
您的错误出在您的get_class()
方法中. $class_name
包含具有名称空间的完全限定的类名.在您的情况下,您必须从类名中删除名称空间.
Your error is in your get_class()
method. $class_name
contains the fully qualified classname with it's namespace. In your case you have to strip the namespace from your classname.
$file_name = 'class_'.strtolower(array_pop(explode('\\', $class_name))).'.php';
我强烈建议使用 PSR-0 自动加载的标准.如果要使用任何库,则很有可能它们使用相同的标准,并且只有一个自动加载器.
I highly recommend using PSR-0 standard for autoloading. If you will be using any libraries it is very likely that they are using the same standard and you only have one autoloader.
这篇关于带有命名空间的PHP类不能通过spl_autoload_register加载吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!