PHP 命名空间和 spl_autoload_register

Posted

技术标签:

【中文标题】PHP 命名空间和 spl_autoload_register【英文标题】:PHP namespacing and spl_autoload_register 【发布时间】:2014-04-25 01:20:06 【问题描述】:

我的 spl_autoload_register 工作正常,但后来我决定添加一些命名空间以实现 PSR2 合规性,但似乎无法使其正常工作。

目录结构:

-index.php
-classes/
  -Class1.class.php
  -Class2.class.php
  -Class3.class.php

每个班级都以:

namespace Foo;

Class ClassX 

索引.php:

<?php

spl_autoload_register(function($class) 
    include 'classes/' . $class . '.class.php';
);

$myObj = new Class1();

echo $myObj->doSomething();

此产品出现错误Fatal error: Class 'Class1' not found in /var/www/myApp/index.php on line X

我的第一个想法是我的实例化需要使用命名空间,所以我将index.php 更改为:

$myObj = new Foo\Class1();

但是,我得到 Warning: include(classes/Foo\Class1.class.php): failed to open stream: No such file or directory in /var/www/myApp/index.php on line 6

如果我手动包含一切正常,include 'classes/Class1.class.php'; 等等。

【问题讨论】:

【参考方案1】:

所以问题是$class 被返回到spl_autoload_register 是名称空间\类名,带有的反斜杠完好无损。所以当我实例化一个新对象时:

$myObj = new Foo\Class1();

包含路径变为/var/www/myApp/classes/Foo\Class1.php,反斜杠打破了路径。

我实现了这个来修复反斜杠,现在它可以工作了,虽然我不知道为什么这是必要的。

spl_autoload_register(function($class) 
    include 'classes/' . str_replace('\\', '/', $class) . '.class.php';
);

【讨论】:

这不给Warning: include(classes/Foo/Class1.class.php):吗? 我觉得应该有更优雅的解决方案,而不仅仅是手动改变斜线方向。你找到更好的方法了吗? 我对这个答案不满意的原因是因为它在没有str_replace 的情况下在我的 Vagrant 盒子上运行良好,但是当我在 BlueHost 上部署它时它无法正常工作,需要其他类型斜线。 好吧,我放弃了,没有比这个答案更好的了。【参考方案2】:

尝试在路径前使用 DIR 常量,例如:

spl_autoload_register(function($class) 
    include __DIR__.'/classes/' . $class . '.class.php';
);

它将确保相对路径始终相同。

你必须使用“正确”的文件夹结构:

myproject/
-loader.php
-class/
-- Namespace1/
--- Class1.class.php
--- Class2.class.php

-- Namespace2/
--- Class3.class.php

【讨论】:

虽然这是一个很好的提示,但遗憾的是在这种情况下它不是解决方法。 我已经更新了我的答案。如果你想看看,我有一个使用类似结构的项目:code.google.com/p/flat-framework。它仍处于起步阶段,但也许它会以某种方式帮助你......

以上是关于PHP 命名空间和 spl_autoload_register的主要内容,如果未能解决你的问题,请参考以下文章

现代PHP-命名空间

PHP 命名空间和“使用”

php命名空间和autoload

php命名空间

PHP 命名空间(namespace)

PHP——大话PHP设计模式——命名空间和类的自动载入