gpt4 book ai didi

php自动加载器: why does this work?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:47:56 27 4
gpt4 key购买 nike

我一直在试验自动加载器类目录映射技术,这有点费力。我设法提出了一个相当简单的解决方案(表面上),但我完全不明白它是否有效,而其他“更明显”的解决方案却失败了。下面是一些代码片段,可以说明我的困惑。

这是工作代码:

<?php
spl_autoload_register('my_autoloader');

function my_autoloader($class) {
$classMap = array(
'classes/',
'classes/sites/',
'classes/data/'
);
foreach ($classMap as $location) {
if (!@include_once($location . $class . '.php')) { // @ SUPPRESSES include_once WARNINGS
// CLASS DOESN'T EXIST IN THIS DIRECTORY
continue;
} else {
// CLASS IS AUTO-LOADED
break;
}
}
}
?>

这是我认为应该有效但无效的片段:

<?php
spl_autoload_register('my_autoloader');

function my_autoloader($class) {
$classMap = array(
'classes/',
'classes/sites/',
'classes/data/'
);
foreach ($classMap as $location) {
if (file_exists($location . $class . '.php')) {
require_once ($location . $class . '.php');
}
}
}
?>

后者对我来说更有意义,因为虽然这两个版本有效:

<?php
spl_autoload_register('my_autoloader');

function my_autoloader($class) {
require_once ('classes/sites/' . $class . '.php');
}
?>

<?php
spl_autoload_register('my_autoloader');

function my_autoloader($class) {
$location = 'classes/sites/';
require_once ($location . $class . '.php');
}
?>

这个抛出“没有这样的文件或目录...”(注意路径中缺少“sites/”。

<?php
spl_autoload_register('my_autoloader');

function my_autoloader($class) {
require_once ('classes/' . $class . '.php');
}
?>

“没有这样的文件或目录...”错误让我觉得我可以简单地检查一个类的支持文件,如果 (file_exists()) {require_once();打破;}否则{继续;}

为什么那行不通?而且,为什么第一个片段有效?从未明确包含或要求支持路径/文件。

最佳答案

好的,我明白了。我的问题确实是没有正确设置路径;使用 __DIR__ 常量是::ahem::成功之路。这是我现在使用的工作代码:

<?php
spl_autoload_register('my_autoloader');

function my_autoloader($class) {
$classMap = array(
'classes/',
'classes/sites/',
'classes/data/'
);
foreach ($classMap as $location) {
if (file_exists(__DIR__ . '/' . $location . $class . '.php')) {
require_once(__DIR__ . '/' . $location . $class . '.php');
break;
}
}
}
?>

事实证明 __DIR__ 返回调用它的实际文件的目录位置(而不是,比如说,包含它的文件),这意味着只要满足该文件保留在我的/classes 目录的根目录中。而且,它专门用于定义这些类型的设置...

希望这对其他人有帮助!而且,当然,如果有人能阐明为什么这个解决方案不是最优的,我会全神贯注......

编辑:我将执行的一项优化是将 $classMap array() 转换为关联数组(例如,$classMap = array('root' => 'classes/', 'sites' => 'classes/sites/'); 这样我就可以进行查找,而不是循环遍历我随时间创建的所有目录。但是,我想那是另一个线程。

EDIT2:如果有人感兴趣,这里是我想出的将此作为关联数组执行的解决方案。基本上,我在 $GLOBALS 中设置了一个关联数组,并使用它来存储类 -> 包的映射。然后,在自动加载器中,我映射 Packages -> Locations,然后调用实例化类所需的文件。

这是全局配置文件:

<?php
// INITIALIZE GLOBAL Class -> Package map
if (!array_key_exists('packageMap',$GLOBALS)) {
$GLOBALS['packageMap'] = array();
}

spl_autoload_register('my_autoloader');

function my_autoloader($class) {
$classMap = array(
'root'=>'/classes/',
'sites'=>'/classes/sites/',
'data'=>'/classes/data/'
);

// RESOLVE MAPPINGS TO AN ACTUAL LOCATION
$classPackage = $GLOBALS['packageMap'][$class];
$location = $classMap[$classPackage];
if (file_exists(__DIR__ . $location . $class . '.php')) {
require_once(__DIR__ . $location . $class . '.php');
}
}
?>

这是一个使用自动加载器的特定站点配置文件:

<?php   
// LOAD GLOBAL CONFIG FILE
require_once('../config/init.php');

// CREATE LOCAL REFERENCE TO GLOBAL PACKAGE MAP (MOSTLY FOR READABILITY)
$packageMap = $GLOBALS['packageMap'];

// ADD Class -> Package MAPPINGS
$packageMap['DAO'] = 'data';
$packageMap['SomeSite'] = 'sites';
$packageMap['PDOQuery'] = 'data';

// INSTANTIATE SOMETHING IN ONE OF THE PACKAGES
$someSite = new SomeSite();
?>

希望这对其他人有用...如果它对任何人发出任何危险信号,请插话。最终,我想用 apc 替换 $GLOBALS 的使用,但它没有安装在我的托管服务器上:/.我可能会考虑使用 memcached,但我听到的评论不一...

关于php自动加载器: why does this work?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17815236/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com