PHP_CodeSniffer: PHPCS 3.x: Autoloading not working with arbitrary namespace prefix

In the upgrade guide, it says:

Note: It doesn’t matter what namespace you use for your sniffs as long as the last part of the namespace is in the format StandardName\Sniffs\Category

I’m currently trying to upgrade the WordPress Coding Standards library and am using the following namespace / class declaration for one of the sniffs:

namespace WordPressCS\WordPress\Sniffs\Arrays;

use WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff;

class ArrayAssignmentRestrictionsSniff extends AbstractArrayAssignmentRestrictionsSniff {
    // sniff code
}

The file AbstractArrayAssignmentRestrictionsSniff class is as expected located in /path/to/WPCS/WordPress/AbstractArrayAssignmentRestrictionsSniff.php and the /path/to/WPCS location is registered with installed_paths.

This results in a Fatal Error:

Fatal error: Class 'WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff' not found in /path/to/WPCS/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php on line 28

Call Stack:
    0.0010     124488   1. {main}() \path\to\PHP_CodeSniffer\bin\phpcs:0
    0.0090     291840   2. PHP_CodeSniffer\Runner->runPHPCS() \path\to\PHP_CodeSniffer\bin\phpcs:18
    0.3030     730056   3. PHP_CodeSniffer\Runner->init() \path\to\PHP_CodeSniffer\src\Runner.php:68
    0.3140     994536   4. PHP_CodeSniffer\Ruleset->__construct() \path\to\PHP_CodeSniffer\src\Runner.php:280
    3.3092    1046176   5. PHP_CodeSniffer\Ruleset->registerSniffs() \path\to\PHP_CodeSniffer\src\Ruleset.php:201
    3.3102    1052392   6. PHP_CodeSniffer\Autoload::loadFile() \path\to\PHP_CodeSniffer\src\Ruleset.php:1069
    3.3142    1077680   7. include('/path/to/WPCS/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php') \path\to\PHP_CodeSniffer\autoload.php:171

Some light debugging shows me that the autoloader is trying to find the file in the following locations:

"\path\to\PHP_CodeSniffer\src\Standards\WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff.php"
"\path\to\WPCS\WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff.php"
"\path\to/PHPCompatibility/WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff.php"
"\path\to/yoastcs\WordPressCS\WordPress\AbstractArrayAssignmentRestrictionsSniff.php"

This would imply that - unless you use Composer and force all users of the standard to use Composer - you cannot use prefixed namespaces.

Or is there a way to “hook in” an extra autoload file which I haven’t found out about yet ? The bootstrap option cannot be used as it is run too late (after the autoloading of the sniffs).

Basically - for the purpose of the autoloading -, I would expect the namespace prefix WordPressCS to be ignored, or, to be stripped off the sniff based namespace if the prefixed file cannot be loaded, in order to “try again”.

While I could use a non-prefixed namespace - after all WP currently does not use namespaces (yet) -, it would be kind of irresponsible to do so IMHO and considering how large the userbase is of the standard, changing the name of the standard would also cause a massive BC break.

Bright ideas or solutions very welcome 😉

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 16 (16 by maintainers)

Commits related to this issue

Most upvoted comments

Closing as this was released a couple of versions back. Autoload problems can now be handled in new issues.

I believe you are talking about option 3 here ?

Sorry, yes I was.

I think I can have an autoload file (defined in a ruleset.xml file) loaded up before the rest of the ruleset is processed. I’m fairly sure I wont be able to define any sort of order because I need to process a ruleset in order to figure out what other rulesets it requires, so loading order would be dependant on how the ruleset is constructed. I don’t know if that’s a problem, but I don’t think it would be a problem in your specific case, so it might be a good first step.

I’ll take a look into it and report back.

So IMHO this is a WP issue and libraries/framework should not try to be backward compatible for something that the age has moved on.

This is not my position and I am committed to getting this working. I’d hate for PHPCS to only be usable with projects that use composer, or to force custom coding standards to be installed via composer for them to work.