【问题标题】:PSR-0 auto-load testing problemsPSR-0 自动加载测试问题
【发布时间】:2014-04-16 11:03:30
【问题描述】:

我正在摆弄自动加载,并尝试创建一个符合 PSR-0 标准的文件结构。但是我收到了这个错误:

Warning: require(GetMatchHistory\api.php): failed to open stream: No such file or directory in C:\xampp\htdocs\Test\Test.php on line 15

Fatal error: require(): Failed opening required 'GetMatchHistory\api.php' (include_path='.;C:\xampp\php\PEAR') in C:\xampp\htdocs\Test\Test.php on line 15

这是我的文件结构:

我正在使用带有这个自动加载功能的测试 PHP:

function autoload($className)
{
    $className = ltrim($className, '\\');
    $fileName  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

    require $fileName;
}

spl_autoload_register('autoload');

$Query = new GetMatchHistory_api();

此函数是从建议的 PSR-0 函数 here 复制粘贴的

我是否误解了结构应该如何? “api.php”中的类是GetMatchHistory_api

编辑:另一个问题

我使用了 MrCode 建议的答案,但是现在我遇到了一个问题,即自动加载器无法加载另一个目录中的类。

use Classes\Queries\History\GetMatchHistoryAPI;
use Classes\Queries\History\GetMatchHistoryBASE;
use Classes\Utilities\send;

当我从GetMatchHistoryAPI 内部的函数中调用send 类时,我收到错误:

Warning: require(Classes\Queries\History\send.php): failed to open stream: No such file or directory in C:\xampp\htdocs\Test\Test.php on line 15

但是,从上图可以看出,发送类不在该文件路径中。为什么会出现这个错误?

【问题讨论】:

  • 您不应该要求一个不存在的文件。那么仍然是一个致命错误,但是因为找不到该类,而不是因为失败的要求。细节,但更清楚。
  • @Rudie 我看到该文件在该目录中不存在。但是我不确定为什么会这样。如果按照上面的代码,我输入$Query = new send(),则该文件在正确的位置“找到”(对不起,术语不好),但当send 类从另一个类执行时不是。
  • 我知道。我实际上并没有评论这个问题,对不起。致命错误应该是“未找到 X 类”,而不是“无法包含文件 Y”。根本没有帮助你,但它更“正确”。

标签: php namespaces autoload psr-0


【解决方案1】:

基于该结构,您需要将类重命名为 Classes_Queries_GetMatchHistory_api 并将实例化它的代码更改为:

$Query = new Classes_Queries_GetMatchHistory_api();

原因是您的Test.php 位于根目录,而api 类位于目录Classes/Queries/GetMatchHistory


使用命名空间而不是下划线方法的示例:

api.php:

namespace Classes\Queries\GetMatchHistory;

class api
{

}

Test.php:

spl_autoload_register('autoload');
$Query = new Classes\Queries\GetMatchHistory\api();

或者使用use:

use Classes\Queries\GetMatchHistory\api;

spl_autoload_register('autoload');
$Query = new api();

解决您的评论:

我将拥有相同的类名,但在不同的文件夹下(因此 GetMatchHistory - api.php 和 GetMatchDetails - api.php)。但是,我想这会在调用类时变得过于模棱两可

命名空间旨在解决这个问题。命名空间允许您拥有同名的类(但在不同的命名空间中)并避免任何冲突。

例如,您在GetMatchHistoryGetMatchDetails 下都有一个api 类。

文件:类/查询/GetMatchHistory/api.php

namespace Classes\Queries\GetMatchHistory;

class api
{
    public function __construct(){
        echo 'this is the GetMatchHistory api';
    }
}

文件:类/查询/GetMatchDetails/api.php

namespace Classes\Queries\GetMatchDetails;

class api
{
    public function __construct(){
        echo 'this is the GetMatchDetails api, I am separate to the other!';
    }
}

文件:Test.php(使用示例)

spl_autoload_register('autoload');

$historyApi = new Classes\Queries\GetMatchHistory\api();
$detailsApi = new Classes\Queries\GetMatchDetails\api();

如果你愿意,你可以给一个别名而不是输入整个完全限定的命名空间:

use Classes\Queries\GetMatchHistory\api as HistoryApi;
use Classes\Queries\GetMatchDetails\api as DetailsApi;

$historyApi = new HistoryApi();
$detailsApi = new DetailsApi();

如您所见,命名空间使多个具有相同名称的不同类成为可能,而不会发生冲突或产生歧义。

【讨论】:

  • 谢谢你的回复,这个话题还是让我很困惑。在我有api.phpbase.phpdb.php 的地方,我将拥有相同的类名,但在不同的文件夹下(因此 GetMatchHistory - api.php 和 GetMatchDetails - api.php)。但是,我想这会在调用类时变得过于模棱两可。
  • 另外,我遇​​到了另一个问题,如果您有机会,我会重视您的意见!
  • 查看我的编辑以解决您对相同类名的评论(此处不适合)。关于你的send 错误,你能展示你如何在 Test.php 中实例化类吗?还显示send.php 的内容,以便我可以看到类名和命名空间。
  • 感谢您的回答!!关于发送部分,Here 是 Test.php 的内容,Here 是 send.php 的内容。有关其他信息,此行是 GetMatchHistoryAPI 中用于启动发送类的内容:@987654343 @
  • 因为您在 GetMatchHistoryAPI 中使用 send 类,您需要: 1. 使用完整的命名空间(包括根反斜杠),例如 $request = new \Classes\Utilities\send(self::steamurl, $this->_get_data_query()); 或 2. 在 api.php 内有 @987654346 @ 并且您可以保持现有代码不变。
猜你喜欢
  • 2014-08-02
  • 2019-12-22
  • 2014-03-24
  • 2015-01-08
  • 2014-02-14
  • 2014-07-25
  • 2013-11-09
  • 2018-07-25
  • 1970-01-01
相关资源
最近更新 更多