我正在尝试为内部使用构建自己的框架。 我有这样的结构:
index.php
boot /
booter.php
application /
controllers /
indexcontroller.php
core /
template.class.php
model.class.php
controller.class.php
cache /
memcached.php
something /
something.php
Booter.php包含:(它目前仅适用于位于核心目录中的文件):
class Booter
{
private static $controller_path, $model_path, $class_path;
public static function setDirs($controller_path = 'application/controllers', $model_path = 'application/models', $classes_path = 'core')
{
self::$controller_path = $controller_path;
self::$model_path = $model_path;
self::$class_path = $classes_path;
spl_autoload_register(array('Booter', 'LoadClass'));
if ( DEBUG )
Debugger::log('Setting dirs...');
}
protected static function LoadClass($className)
{
$className = strtolower($className);
if ( file_exists(DIR . '/' . self::$model_path . '/' . $className . '.php') )
{
require(DIR . '/' . self::$model_path . '/' . $className . '.php');
}
else if ( file_exists(DIR . '/' . self::$class_path . '/' . $className . '.class.php') )
{
require(DIR . '/' . self::$class_path . '/' . $className . '.class.php');
}
else if ( file_exists(DIR . '/' . self::$controller_path . '/' . $className . '.php') )
{
require(DIR . '/' . self::$controller_path . '/' . $className . '.php');
}
if ( DEBUG )
Debugger::log('AutoLoading classname: '.$className);
}
}
我的application / controllers / indexcontroller看起来像这样:
<?
class IndexController extends Controller
{
public function ActionIndex()
{
$a = new Model; // It works
$a = new Controller; //It works too
}
}
?>
以下是我的问题:
[问题1]
我的代码目前正在运行:
$a = new Model; // Class Model gets included from core/model.class.php
如何通过具有命名空间的类实现包含文件?例如:
$a = new Cache\Memcached; // I would like to include file from /core/CACHE/Memcached.php
$a = new AnotherNS\smth; // i would like to include file from /core/AnotherNS/smth.php
等等。我如何能够处理命名空间?
[问题2]
对于类,控制器和模型使用单个自动加载是一个好习惯,还是应该使用3种不同的方法定义3种不同的spl_autoload_register?为什么?
答案 0 :(得分:3)
我通常在应用程序根目录下的文件夹bootstrap.php
中有一个conf
文件。我的代码通常位于src
文件夹中,也位于根目录中,因此,这对我来说很好用:
<?php
define('APP_ROOT', dirname(__DIR__) . DIRECTORY_SEPARATOR);
set_include_path(
implode(PATH_SEPARATOR,
array_unique(
array_merge(
array(
APP_ROOT . 'src',
APP_ROOT . 'test'
),
explode(PATH_SEPARATOR, get_include_path())
)
)
)
);
spl_autoload_register(function ($class) {
$file = sprintf("%s.php", str_replace('\\', DIRECTORY_SEPARATOR, $class));
if (($classPath = stream_resolve_include_path($file)) != false) {
require $classPath;
}
}, true);
您可以将其概括为您的&#34; Booter&#34; class并将目录附加到include路径。如果你有明确定义的命名空间名称,那么colisions就没有问题。
修改强> 如果您按照PSR-1进行操作,则此方法有效。
答案 1 :(得分:2)
问题1:
在自动加载器中,将\(对于命名空间)更改为DIRECTORY_SEPARATOR
。这应该有效:
protected static function LoadClass($className)
{
$className = strtolower($className);
$className = str_replace('\\', DIRECTORY_SEPARATOR, $className);
...
}
始终使用DIRECTORY_SEPARATOR
,特别是如果该软件有可能在其他平台上使用的话。
问题2:
我会使用一个并按命名空间分隔您的类。但是,我认为这取决于您希望如何构建框架以及如何分离代码。其他人可能能够更好地回答这个问题。