简体   繁体   中英

PSR4 Composer Autoload Fatal error: Trait not found

I'm attempting to implement this error handling class into my php website https://github.com/niteshapte/advanced-error-exception-handler-logger-php but I keep getting the error

PHP Fatal error: Trait 'SingletonTrait' not found in www.example.com/application/core/ErrorExceptionHandler.php on line 37.

Line 37 is the second use SingletonTrait; statement.

I've only just wrapped my head around namespaces and then traits come along!

My code is below....I've stripped a lot of the code for brevity, but the full code can be viewed at the github URL above.

Can you spot what I'm doing wrong?

Source for 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;
....
}

Source for www.example.com/application/core/SingletonTrait.php

<?php
namespace Utilities;
use FrameworkException;

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

trait SingletonTrait {
.....
}

Source for www.example.com/application/core/FrameworkException.php

<?php
namespace Utilities;

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

class FrameworkException extends \Exception { }

Source for www.example.com/application/core/IUtilities.php

<?php
namespace Utilities;

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

interface IUtilities { }

Source for www.example.com/index.php

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

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

This is what I have in my www.example.com/composer.json

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

Once I've uploaded that to my server, I issue composer dump-autoload at my PuTTY command line.

This generates the following source at 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'),
);

I've read as much as I can about autoloading traits but I haven't found an answer.

My command line PHP version is 5.6.30.

Remove the initial use SingletonTrait declaration inside ErrorExceptionHandler.php and it will work for you.

Traits don't really make sense to be declared with the use statement outside of a class definition. There is a comment about this on the official PHP docs for traits that you can see below and read directly here :

Note that the "use" operator for traits (inside a class) and the "use" operator for namespaces (outside the class) resolve names differently. "use" for namespaces always sees its arguments as absolute (starting at the global namespace)

Also worth noting, adjust your autoload section:

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

The classes SingletonTrait and FrameworkException reside within the Utilities namespace, so they are already covered by the mapping of Utilities\\\\ to application/core .

The same reason suggests to remove the import for SingletonTrait (as already answered by Peter Featherstone ), as a trait of that name doesn't exist in the root namespace, but within the Utilities namespace:

<?php

namespace Utilities;

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

class ErrorExceptionHandler implements IUtilities 
{
    use SingletonTrait;

    ....
}

Alternatively, you could adjust the import statement, but again, since we are already in the Utilities namespace, that doesn't make any sense:

<?php

namespace Utilities;

use Utilities\SingetonTrait;

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

class ErrorExceptionHandler implements IUtilities 
{
    use SingletonTrait;

    ....
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM