在 PHP 中自动加载类的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17806301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best Way To Autoload Classes In PHP
提问by Sjwdavies
I'm working on a project whereby I have the following file structure:
我正在做一个项目,其中我有以下文件结构:
index.php
|---lib
|--|lib|type|class_name.php
|--|lib|size|example_class.php
I'd like to auto load the classes, class_name and example_class (named the same as the PHP classes), so that in index.php the classes would already be instantiated so I could do:
我想自动加载类,class_name 和 example_class(与 PHP 类命名相同),以便在 index.php 中类已经被实例化,所以我可以这样做:
$class_name->getPrivateParam('name');
I've had a look on the net but can't quite find the right answer - can anyone help me out?
我在网上看了一下,但不能完全找到正确的答案 - 任何人都可以帮助我吗?
EDIT
编辑
Thanks for the replies. Let me expand on my scenario. I'm trying to write a WordPress plugin that can be dropped into a project and additional functionality added by dropping a class into a folder 'functionality' for example, inside the plugin. There will never be 1000 classes, at a push maybe 10?
感谢您的回复。让我扩展一下我的场景。我正在尝试编写一个 WordPress 插件,它可以放入一个项目中,并通过将一个类放入一个文件夹“功能”中来添加附加功能,例如,在插件内部。永远不会有 1000 个班级,一推也许 10 个班?
I could write a method to iterate through the folder structure of the 'lib' folder, including every class then assigning it to a variable (of the class name), but didn't think that was a very efficient way to do it but it perhaps seems that's the best way to achieve what I need?
我可以编写一个方法来遍历“lib”文件夹的文件夹结构,包括每个类,然后将其分配给一个变量(类名),但不认为这是一种非常有效的方法,但它也许这似乎是实现我所需要的最佳方式?
回答by Serge Velikanov
Please, if you need to autoload classes - use the namespaces and class names conventions with SPL autoload, it will save your time for refactoring. And of course, you will need to instantiate every class as an object. Thank you.
请,如果您需要自动加载类 - 在 SPL 自动加载中使用命名空间和类名称约定,它将节省您的重构时间。当然,您需要将每个类实例化为一个对象。谢谢你。
Like in this thread: PHP Autoloading in Namespaces
就像在这个线程中一样: 命名空间中的 PHP 自动加载
But if you want a complex workaround, please take a look at Symfony's autoload class: https://github.com/symfony/ClassLoader/blob/master/ClassLoader.php
但是如果你想要一个复杂的解决方法,请看一下 Symfony 的自动加载类:https: //github.com/symfony/ClassLoader/blob/master/ClassLoader.php
Or like this (I did it in one of my projects):
或者像这样(我在我的一个项目中做到了):
<?
spl_autoload_register(function($className)
{
$namespace=str_replace("\","/",__NAMESPACE__);
$className=str_replace("\","/",$className);
$class=CORE_PATH."/classes/".(empty($namespace)?"":$namespace."/")."{$className}.class.php";
include_once($class);
});
?>
and then you can instantiate your class like this:
然后你可以像这样实例化你的类:
<?
$example=new NS1\NS2\ExampleClass($exampleConstructParam);
?>
and this is your class (found in /NS1/NS2/ExampleClass.class.php):
这是您的课程(在/NS1/NS2/ExampleClass.class.php 中找到):
<?
namespace NS1\NS2
{
class Symbols extends \DB\Table
{
public function __construct($param)
{
echo "hello!";
}
}
}
?>
回答by lilobase
If you have an access to the command line, you can try it with composer in the classMap section with something like this:
如果您可以访问命令行,则可以在 classMap 部分使用 composer 尝试使用以下内容:
{
"autoload": {
"classmap": ["yourpath/", "anotherpath/"]
}
}
then you have a wordpress plugin to enable composer in the wordpress cli : http://wordpress.org/plugins/composer/
那么你有一个 wordpress 插件来在 wordpress cli 中启用作曲家:http: //wordpress.org/plugins/composer/
回答by Hassan Azimi
function __autoload($class_name) {
$class_name = strtolower($class_name);
$path = "{$class_name}.php";
if (file_exists($path)) {
require_once($path);
} else {
die("The file {$class_name}.php could not be found!");
}
}
UPDATE:__autoload()
is deprecated as of PHP 7.2
更新:__autoload()
自 PHP 7.2 起已弃用
回答by Daniel W.
http://php.net/manual/de/function.spl-autoload-register.php
http://php.net/manual/de/function.spl-autoload-register.php
spl_autoload_register(function ($class) {
@require_once('lib/type/' . $class . '.php');
@require_once('lib/size/' . $class . '.php');
});
回答by anttwuan
I have an example here that I use for autoloading and initiliazing.
Basically a better version of spl_autoload_register since it only tries to require the class file whenever you initializes the class.
Here it automatically gets every file inside your class folder, requires the files and initializes it. All you have to do, is name the class the same as the file.
index.php
我在这里有一个用于自动加载和初始化的示例。
基本上是 spl_autoload_register 的更好版本,因为它只在您初始化类时才尝试要求类文件。
在这里它会自动获取类文件夹中的每个文件,需要这些文件并对其进行初始化。您所要做的就是将类命名为与文件相同的名称。
索引.php
<?php
require_once __DIR__ . '/app/autoload.php';
$loader = new Loader(false);
User::dump(['hello' => 'test']);
autoload.php
自动加载.php
<?php
class Loader
{
public static $library;
protected static $classPath = __DIR__ . "/classes/";
protected static $interfacePath = __DIR__ . "/classes/interfaces/";
public function __construct($requireInterface = true)
{
if(!isset(static::$library)) {
// Get all files inside the class folder
foreach(array_map('basename', glob(static::$classPath . "*.php", GLOB_BRACE)) as $classExt) {
// Make sure the class is not already declared
if(!in_array($classExt, get_declared_classes())) {
// Get rid of php extension easily without pathinfo
$classNoExt = substr($classExt, 0, -4);
$file = static::$path . $classExt;
if($requireInterface) {
// Get interface file
$interface = static::$interfacePath . $classExt;
// Check if interface file exists
if(!file_exists($interface)) {
// Throw exception
die("Unable to load interface file: " . $interface);
}
// Require interface
require_once $interface;
//Check if interface is set
if(!interface_exists("Interface" . $classNoExt)) {
// Throw exception
die("Unable to find interface: " . $interface);
}
}
// Require class
require_once $file;
// Check if class file exists
if(class_exists($classNoExt)) {
// Set class // class.container.php
static::$library[$classNoExt] = new $classNoExt();
} else {
// Throw error
die("Unable to load class: " . $classNoExt);
}
}
}
}
}
/*public function get($class)
{
return (in_array($class, get_declared_classes()) ? static::$library[$class] : die("Class <b>{$class}</b> doesn't exist."));
}*/
}
You can easily manage with a bit of coding, to require classes in different folders too.
Hopefully this can be of some use to you.
您可以通过一些编码轻松管理,以要求不同文件夹中的类。
希望这对你有用。
回答by Supun Kavinda
You can specify a namespaces-friendly autoloading using this autoloader.
您可以使用此自动加载器指定命名空间友好的自动加载。
<?php
spl_autoload_register(function($className) {
$file = __DIR__ . '\' . $className . '.php';
$file = str_replace('\', DIRECTORY_SEPARATOR, $file);
if (file_exists($file)) {
include $file;
}
});
Make sure that you specify the class file's location corretly.
确保正确指定类文件的位置。