I want to include PHP_CodeSniffer on my project, so I did this
composer require "squizlabs/php_codesniffer"
just like any other php library and then create an index.php:
<?php
require("vendor/autoload.php");
var_dump(class_exists("PHP_CodeSniffer\Config"));
it returns false instead of true, but when I did this:
<?php
require("vendor/squizlabs/php_codesniffer/autoload.php");
var_dump(class_exists("PHP_CodeSniffer\Config"));
It returns true
So, I think PHP_CodeSniffer does not autoloading itself...
is this intentional, or a bug ?
PHPCS doesn't register an autoloader via composer since designed to be
treated as if its a separate script
On 10 May 2017 20:36, "Rizky" notifications@github.com wrote:
I want to include PHP_CodeSniffer on my project, so i did this
composer require "squizlabs/php_codesniffer"
and then create an index.php:
require("vendor/autoload.php");
var_dump(class_exists("PHP_CodeSniffer\Config"));it returns false instead of true, but when I did this:
require("vendor/squizlabs/php_codesniffer/autoload.php");
var_dump(class_exists("PHP_CodeSniffer\Config"));It returns true
So, I think PHP_CodeSniffer is not autoloading itself...
is this intentional, or a bug ?—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/squizlabs/PHP_CodeSniffer/issues/1463, or mute the
thread
https://github.com/notifications/unsubscribe-auth/ABmozK5jK0lPaO-dz5S8gWWgxX-LDJWmks5r4hHOgaJpZM4NXH9F
.
If so, can I use it this way ? any gotchas ?
You currently need to manually include the PHPCS autoloader if you want to use it like a library.
The PHPCS autoloader is used to determine sniff codes for custom sniffs, where it has no idea what namespace is being used. So it is very important that the PHPCS autoloader be given the first chance to autoload a class. If the composer autoloader goes first, PHPCS can miss out on sniffs being loaded and it will have no idea what the fully qualified class name is, and thus what the sniff code is.
The autoloader does detect the presence of a composer autoloader and takes steps to ensure it is placed first in the autoload queue. It does this by unregistering and then reregistering the composer autoloader. It also uses the composer autoloader (if there is one) to help it figure out some file locations.
To get this working, I had to stop the composer autoloader from being used for PHPCS. If composer includes autoload.php for PHPCS too early, PHPCS' autoloader wont be able to register itself as the first autoloader in the queue.
It is possible that I might be able to allow composer to include the PHPCS autoloader with some more recent modifications that I've done, but it would take extensive testing and possibly break custom coding standards.
So for now, if you want to use PHPCS like a library, manually include its autoload.php file after you include the composer autoloader.
Great, thanks!
@gsherwood Could you explain how to? After I updated from RC3 to 3.0 I tried it with composer.json's autoload.files, but that doesn't work as you pointed out. How can I ensure it is always loaded before the composer autoloader in every environment (running, tests, benchmarks, ...)? Consider that the file is not even in a consistent place depending on whether you are running on a clone of the language server or have the language server as a dependency
https://github.com/felixfbecker/php-language-server/commit/663ccd5f2396489ffd49a09b196150de51e6711a
@felixfbecker It actually needs to be loaded after the composer autoloader, so that it registers itself at the front of the autoload queue. The problem is that if it doesn't go last, another autoloader can come in and put itself at the front, which may cause issues.
So what you need to do is manually include the autoload.php file when your application starts.
Obviously, if you are just using the included phpcs and phpcbf scripts, you don't need to do this because they already look for and include the autoloader. But if you want to use PHPCS code directly, you'll need to do this bit yourself.
For anyone else interested, here is an example of a custom runner doing that sort of thing: https://gist.github.com/gsherwood/aafd2c16631a8a872f0c4a23916962ac
How do you ensure that when running unit tests?
I don't fully understand why a custom autoloader is needed at all
How do you ensure that when running unit tests?
PHPCS has a custom test suite.
I don't fully understand why a custom autoloader is needed at all
A sniff is included by file name, and it is vitally important that PHPCS know exactly what the fully qualified class name is when that happens because that's how it knows the sniff code (e.g., Generic.Category.Something). If another autoloader loads that file, PHPCS won't be able to determine that because it wont get a chance to run code while that is happening.
PHPCS has a custom test suite.
I am not talking about PHPCS' test suite, I am talking about how I should include that autoloader for _my_ testsuite. My point is, applications have multiple entry points. That plus the inconsistent location of the autoloader makes it a hassle to include everywhere.
I am not talking about PHPCS' test suite, I am talking about how I should include that autoloader for my testsuite.
I think that's something you'd need to figure out yourself. I've got no idea about how your test suite works.
@felixfbecker I - of course - also don't know how your test suite works, but you may find some inspiration on how to get it working in this external standard which uses its own test suite to unit test sniffs: https://github.com/wimg/PHPCompatibility/blob/master/Tests/bootstrap.php
For now based on PHPCS 2.x, but will soon also support PHPCS 3.x.
Why did this work fine without including that autloader in RC3 though?
Do I understand this correctly? The phpcs autoloader is used to load sniffs from projects as well?
(I'm still spending time to find the need of a custom autoloader, I prefer things to be boring and the same as all other libraries unless the need is really important)
Do I understand this correctly? The phpcs autoloader is used to load sniffs from projects as well?
Yes, it will load sniffs from custom coding standards without you needing an autoloader, if you're using the right structure and namespacing. Some info is here: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Version-3.0-Upgrade-Guide#upgrading-custom-sniffs
Most helpful comment
You currently need to manually include the PHPCS autoloader if you want to use it like a library.
The PHPCS autoloader is used to determine sniff codes for custom sniffs, where it has no idea what namespace is being used. So it is very important that the PHPCS autoloader be given the first chance to autoload a class. If the composer autoloader goes first, PHPCS can miss out on sniffs being loaded and it will have no idea what the fully qualified class name is, and thus what the sniff code is.
The autoloader does detect the presence of a composer autoloader and takes steps to ensure it is placed first in the autoload queue. It does this by unregistering and then reregistering the composer autoloader. It also uses the composer autoloader (if there is one) to help it figure out some file locations.
To get this working, I had to stop the composer autoloader from being used for PHPCS. If composer includes autoload.php for PHPCS too early, PHPCS' autoloader wont be able to register itself as the first autoloader in the queue.
It is possible that I might be able to allow composer to include the PHPCS autoloader with some more recent modifications that I've done, but it would take extensive testing and possibly break custom coding standards.
So for now, if you want to use PHPCS like a library, manually include its autoload.php file after you include the composer autoloader.