【问题标题】:PSR4 Composer Autoload Fatal error: Trait not foundPSR4 Composer 自动加载致命错误:未找到特征
【发布时间】:2017-12-26 12:36:39
【问题描述】:

我正在尝试在我的 php 网站https://github.com/niteshapte/advanced-error-exception-handler-logger-php 中实现这个错误处理类,但我不断收到错误

PHP 致命错误:在第 37 行的 www.example.com/application/core/ErrorExceptionHandler.php 中找不到特征“SingletonTrait”。

第 37 行是第二个 use SingletonTrait; 语句。

我只是在命名空间周围徘徊,然后特征出现了!

我的代码在下面……为简洁起见,我删除了很多代码,但完整的代码可以在上面的 github URL 上查看。

你能看出我做错了什么吗?

www.example.com/application/core/ErrorExceptionHandler.php 的来源

<?php
namespace Utilities;
use SingletonTrait;

if(!defined('DIRECT_ACCESS')) {
    die("Direct access is forbidden.");
}

class ErrorExceptionHandler implements IUtilities {

    // Singleton instance - the line below generates the error
    use SingletonTrait;
....
}

来源 www.example.com/application/core/SingletonTrait.php

<?php
namespace Utilities;
use FrameworkException;

if(!defined('DIRECT_ACCESS')) {
    die("Direct access is forbidden.");
}

trait SingletonTrait {
.....
}

www.example.com/application/core/FrameworkException.php 的来源

<?php
namespace Utilities;

if(!defined('DIRECT_ACCESS')) {
    die("Direct access is forbidden.");
}

class FrameworkException extends \Exception { }

来源 www.example.com/application/core/IUtilities.php

<?php
namespace Utilities;

if(!defined('DIRECT_ACCESS')) {
    die("Direct access is forbidden.");
}

interface IUtilities { }

www.example.com/index.php 的来源

<?php
require '../vendor/autoload.php';

use Utilities\ErrorExceptionHandler;
define("DIRECT_ACCESS", TRUE);
ErrorExceptionHandler::getInstance();

这就是我的 www.example.com/composer.json 中的内容

"autoload": {
    "psr-4": { "": ["application/core/", "application/model/"],
               "Utilities\\": "application/core/",
               "SingletonTrait\\": "application/core/",
               "FrameworkException\\": "application/core/"
    }
}

将其上传到服务器后,我会在 PuTTY 命令行中发出 composer dump-autoload

这会在 www.example.com/vendor/composer/autoload_psr4.php 生成以下源代码

<?php

// autoload_psr4.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'),
    'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
    'Utilities\\' => array($baseDir . '/application/core'),
    'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
    'SingletonTrait\\' => array($baseDir . '/application/core'),
    'Gregwar\\Captcha\\' => array($vendorDir . '/gregwar/captcha'),
    'FrameworkException\\' => array($baseDir . '/application/core'),
    'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
    'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
    '' => array($baseDir . '/application/core', $baseDir . '/application/model'),
);

我已尽可能多地阅读有关自动加载特征的内容,但我没有找到答案。

我的命令行 PHP 版本是 5.6.30。

【问题讨论】:

    标签: php composer-php autoload psr-4


    【解决方案1】:

    另外值得注意的是,调整您的autoload 部分:

    {
        autoload": {
            "psr-4": { 
                "": [
                    "application/core/",         
                    "application/model/"
                ],
               "Utilities\\": "application/core/",
            }
        }
    }
    

    SingletonTraitFrameworkException 类位于 Utilities 命名空间中,因此它们已经被 Utilities\\application/core 的映射所覆盖。

    同样的原因建议删除 SingletonTrait 的导入(正如 Peter Featherstone 已经回答的那样),因为该名称的特征不存在于根命名空间中,但在 @ 987654329@命名空间:

    <?php
    
    namespace Utilities;
    
    if(!defined('DIRECT_ACCESS')) {
        die("Direct access is forbidden.");
    }
    
    class ErrorExceptionHandler implements IUtilities 
    {
        use SingletonTrait;
    
        ....
    }
    

    或者,您可以调整 import 语句,但同样,由于我们已经在 Utilities 命名空间中,这没有任何意义:

    <?php
    
    namespace Utilities;
    
    use Utilities\SingetonTrait;
    
    if(!defined('DIRECT_ACCESS')) {
        die("Direct access is forbidden.");
    }
    
    class ErrorExceptionHandler implements IUtilities 
    {
        use SingletonTrait;
    
        ....
    }
    

    【讨论】:

      【解决方案2】:

      删除ErrorExceptionHandler.php 中的初始use SingletonTrait 声明,它将为您工作。

      在类定义之外用use 语句声明特征并没有什么意义。官方 PHP 文档中有关于特性的评论,您可以在下面看到并直接阅读 here

      请注意,特征(类内部)的“use”运算符和命名空间(类外部)的“use”运算符解析名称的方式不同。命名空间的“使用”始终将其参数视为绝对参数(从全局命名空间开始)

      【讨论】:

      • 天啊!当你知道怎么做时就这么简单!谢谢彼得
      • @Damian - 哈,直到大约 10 分钟前,当我读到你的问题时,我才知道怎么做......在我的开发环境中玩耍并检查手册很快就找到了答案尽管。你今天教会了我一些新东西:-)
      猜你喜欢
      • 1970-01-01
      • 2016-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2017-02-28
      • 1970-01-01
      • 2018-09-16
      相关资源
      最近更新 更多