这是我自动加载我controllers文件夹中的所有类的方法,
# auto load controller classes
function __autoload($class_name)
{
$filename = 'class_'.strtolower($class_name).'.php';
$file = AP_SITE.'controllers/'.$filename;
if (file_exists($file) == false)
{
return false;
}
include ($file);
}
Run Code Online (Sandbox Code Playgroud)
但我也有models文件夹中的课程,我也想自动加载它们 - 我该怎么办?我应该复制上面的自动加载,只是改变路径models/(但不是重复?)?
谢谢.
编辑:
这些是我在控制器文件夹中的类文件名:
class_controller_base.php
class_factory.php
etc
Run Code Online (Sandbox Code Playgroud)
这些是我在模型文件夹中的类文件名:
class_model_page.php
class_model_parent.php
etc
Run Code Online (Sandbox Code Playgroud)
这就是我通常命名我的控制器类的方法(我使用下划线和低位),
class controller_base
{
...
}
class controller_factory
{
...
}
Run Code Online (Sandbox Code Playgroud)
这就是我通常命名我的模型类的方法(我使用下划线和lowcaps),
class model_page
{
...
}
class model_parent
{
...
}
Run Code Online (Sandbox Code Playgroud)
br3*_*3nt 62
我看到你正在使用controller_*****和model_*****作为类命名约定.
我读了一篇很棒的文章,它提出了一个使用php的替代命名约定namespace.
我喜欢这个解决方案,因为我把课程放在哪里并不重要.该__autoload会无论发现它是在我的文件结构.它还允许我随意调用我的课程.我的代码不需要类命名约定.
例如,您可以设置文件夹结构,如:
您的课程可以像这样设置:
<?php
namespace application\controllers;
class Base {...}
Run Code Online (Sandbox Code Playgroud)
和:
<?php
namespace application\models;
class Page {...}
Run Code Online (Sandbox Code Playgroud)
自动加载器可能看起来像这样(或者在最后看到'关于自动加载的说明'):
function __autoload($className) {
$file = $className . '.php';
if(file_exists($file)) {
require_once $file;
}
}
Run Code Online (Sandbox Code Playgroud)
然后......你可以用三种方式调用类:
$controller = new application\controllers\Base();
$model = new application\models\Page();
Run Code Online (Sandbox Code Playgroud)
要么,
<?php
use application\controllers as Controller;
use application\models as Model;
...
$controller = new Controller\Base();
$model = new Model\Page();
Run Code Online (Sandbox Code Playgroud)
要么,
<?php
use application\controllers\Base;
use application\models\Page;
...
$controller = new Base();
$model = new Page();
Run Code Online (Sandbox Code Playgroud)
编辑 - 关于自动加载的说明:
我的主要自动装载机看起来像这样:
// autoload classes based on a 1:1 mapping from namespace to directory structure.
spl_autoload_register(function ($className) {
# Usually I would just concatenate directly to $file variable below
# this is just for easy viewing on Stack Overflow)
$ds = DIRECTORY_SEPARATOR;
$dir = __DIR__;
// replace namespace separator with directory separator (prolly not required)
$className = str_replace('\\', $ds, $className);
// get full name of file containing the required class
$file = "{$dir}{$ds}{$className}.php";
// get file if it is readable
if (is_readable($file)) require_once $file;
});
Run Code Online (Sandbox Code Playgroud)
这个自动加载器是类名到目录结构的直接1:1映射; 命名空间是目录路径,类名是文件名.所以application\controllers\Base()上面定义的类将加载文件www/application/controllers/Base.php.
我将自动加载器放入一个文件bootstrap.php,它位于我的根目录中.这可以直接包含,也可以将php.ini修改为auto_prepend_file,以便在每个请求中自动包含它.
通过使用spl_autoload_register,您可以注册多个自动加载功能,以任何方式加载类文件.即,您可以将一些或所有类放在一个目录中,或者可以将一些或所有命名空间类放在一个文件中.非常灵活:)
ale*_*lex 27
您应该为类命名,以便下划线(_)转换为目录分隔符(/).一些PHP框架就是这样做的,比如Zend和Kohana.
所以,你为你的班级命名Model_Article并将文件放入classes/model/article.php,然后你的自动加载确实......
function __autoload($class_name)
{
$filename = str_replace('_', DIRECTORY_SEPARATOR, strtolower($class_name)).'.php';
$file = AP_SITE.$filename;
if ( ! file_exists($file))
{
return FALSE;
}
include $file;
}
Run Code Online (Sandbox Code Playgroud)
另请注意,您可以使用spl_autoload_register()任何功能进行自动加载功能.它也更灵活,允许您定义多个自动加载类型功能.
如果必须有多个自动加载功能,spl_autoload_register()允许这样做.它有效地创建了一个自动加载功能队列,并按照它们的定义顺序遍历每个功能.相比之下,__ autoload()只能定义一次.
编辑
注意: 自PHP 7.2.0起,__ autoload已被弃用.非常不鼓励依赖此功能.有关更多详细信息,请参阅PHP文档.http://php.net/manual/en/function.autoload.php
我必须提一下"好"的自动加载脚本和代码结构,所以请仔细阅读以下内容
记住:
例如:Example.php包含
class Example {}
Run Code Online (Sandbox Code Playgroud)
例如:/Path1/Path2/Example.php匹配
namespace Path1\Path2;
class Example {}
Run Code Online (Sandbox Code Playgroud)
例如:/Path1/Path2/Example.php with root:
namespace APP\Path1\Path2;
class Example {}
Run Code Online (Sandbox Code Playgroud)
考虑到这一点,我制作了以下脚本:
function Loader( $Class ) {
// Cut Root-Namespace
$Class = str_replace( __NAMESPACE__.'\\', '', $Class );
// Correct DIRECTORY_SEPARATOR
$Class = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, __DIR__.DIRECTORY_SEPARATOR.$Class.'.php' );
// Get file real path
if( false === ( $Class = realpath( $Class ) ) ) {
// File not found
return false;
} else {
require_once( $Class );
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
在哪里放置..
Remeber:
快乐的编码;-)
其他答案的一点评论: 这只是我的个人意见 - 没有意图!
/sf/answers/369624741/ @alex很好的解决方案,但不要让你的类名为坏文件结构付费;-)这是命名空间的工作
/sf/answers/369635731/ @Mark-Eirich它的工作原理,但这种方式非常讨厌/丑陋/缓慢/僵硬[...]风格..
/sf/answers/369886681/ @tealou要解决他的问题这是迄今为止最明确的方法:-) ..
/sf/answers/673964231/ @ br3nt这反映了我的观点,但请(!)..不要使用strtr !! ..带我到:
/sf/answers/830641521/ @Iscariot ..给你,一点点"你知道废话基准:
Time sprintf preg_replace strtr str_replace v1 str_replace v2
08:00:00 AM 1.1334 2.0955 48.1423 1.2109 1.4819
08:40:00 AM 1.0436 2.0326 64.3492 1.7948 2.2337
11:30:00 AM 1.1841 2.5524 62.0114 1.5931 1.9200
02:00:00 PM 0.9783 2.4832 52.6339 1.3966 1.4845
03:00:00 PM 1.0463 2.6164 52.7829 1.1828 1.4981
Average 1.0771 2.3560 55.9839 1.4357 1.7237
Method Times Slower (than sprintf)
preg_replace 2.19
strtr 51.97
str_replace v1 1.33
str_replace v2 1.6
Run Code Online (Sandbox Code Playgroud)
资料来源:http://www.simplemachines.org/community/index.php? topic = 175031.0
有问题吗?..(但他实际上是完全正确的道路,包括)
/sf/answers/878399091/ @Sunil-Kartikey /sf/answers/1210076311/ @jurrien
永远不要在时间关键环境中循环!不要在os上搜索文件!- 慢
/sf/answers/1485511331/ @sagits ..比Marks好多了;-)