PHP CodeSniffer如何检查没有扩展名的文件?

5
在我的团队中,我们使用codesniffer来强制执行Symfony应用程序的编码风格,我们刚刚意识到没有扩展名的文件不会被检查,即使我们明确使用该文件作为参数。根据这个github issue的讨论,这是有意设计的。
这意味着像bin/console这样的文件不会被检查,即使它们是有效的PHP文件,而--extensions参数不接受空参数。
有没有办法让CodeSniffer也检查这些文件?
4个回答

1

来自文档

对于特定文件忽略文件扩展名是 PHP_CodeSniffer 的一个功能,这也是检查没有扩展名的文件的唯一方法。如果您检查整个目录中的文件,则所有没有扩展名的文件都将被忽略,因此您必须单独检查每个这样的文件。

https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage

所以您需要指定文件

语法是

phpcs --file-list=path/to/file/containing/others

其中others是一个每行一个文件的文件。

这将检查others文件中列出的所有文件

例如

File1 File2 Console

要检查这3个文件


如果是这样的话,那么肯定有一个bug,因为看起来php vendor/bin/phpcs ./bin/console命令的行为就像我给了它一个空文件夹作为参数而不是一个文件。为了保险起见,我会打开一个工单。 - Loupax
看起来有一个显式的检查,以防止这种情况发生。https://github.com/squizlabs/PHP_CodeSniffer/blob/master/src/Filters/Filter.php#L144 - Loupax
1
使用--file-list选项无法处理没有扩展名的文件,至少在v3.3.2中是这样。 - piotr_cz

0
根据 Issue #1754 PHP_CodeSniffer does not test PHP files with no extensions ,它不支持开箱即用。您需要编写自己的过滤器并将其作为参数传递。
这里有一个小例子,您应该根据自己的需求进行调整。特别是,此过滤器旨在查找使用PHP编写的shell脚本。它打开所有没有扩展名的文件(对于小型项目很快,但对于大型项目可能会有问题),查找特定的she-bang模式(内置MIME检测函数无法满足我的用例)。例如,您可以添加要查找脚本的位置的白名单。

phpcs.xml

<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="phpcs.xsd">
    <arg name="filter" value="lib/CustomPHP_CodeSniffer/Filters/ExtensionlessPhpScriptsFilter.php"/>
    <rule ref="PSR12"></rule>
    <file>.</file>
</ruleset>

lib/CustomPHP_CodeSniffer/Filters/ExtensionlessPhpScriptsFilter.php

<?php

namespace Lib\CustomPHP_CodeSniffer\Filters;

use PHP_CodeSniffer\Filters\Filter;
use PHP_CodeSniffer\Util\Common;

class ExtensionlessPhpScriptsFilter extends Filter
{
    private const SCRIPT_SHEBANG = '@^#!/opt/php[\d.]+/bin/php@';

    public function accept(): bool
    {
        $filePath = Common::realpath($this->current());
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
        if (is_dir($filePath) || $extension !== '') {
            return parent::accept();
        }

        if ($this->shouldIgnorePath($filePath)) {
            return false;
        }

        return $this->isPhpShellScript($filePath);
    }

    private function isPhpShellScript(string $filePath): bool
    {
        if (is_dir($filePath)) {
            return false;
        }

        $fp = fopen($filePath, 'rb');
        if (!$fp) {
            throw new \RuntimeException("Could not open file to determine type: $filePath");
        }
        $line = fgets($fp, 80);
        fclose($fp);
        if ($line === false) {
            throw new \RuntimeException("Could not read file to determine type: $filePath");
        }

        return (bool)preg_match(self::SCRIPT_SHEBANG, $line);
    }
}

0

我认为你可以指定*作为通配符扩展名。

如果这不起作用,文档中说明:

如果您要求PHP_CodeSniffer检查特定文件而不是整个目录,则会忽略指定文件的扩展名。即使文件具有无效的扩展名或根本没有扩展名,也将检查该文件。在以下示例中,即使--extensions命令行参数指定仅检查.php文件,PHP_CodeSniffer也将检查main.inc文件。检查特定文件时忽略扩展名

$ phpcs --extensions=php /path/to/code/main.inc

如果您明确检查没有扩展名的单个文件,则应该可以正常工作。

此外,它还指出:

忽略特定文件的文件扩展名是 PHP_CodeSniffer 的一个功能,也是检查没有扩展名的文件的唯一方法。如果您检查整个目录中的文件,则会忽略所有没有扩展名的文件,因此您必须单独检查每个这些文件。

请参见https://pear.php.net/manual/en/package.php.php-codesniffer.advanced-usage.php


1
当你“认为”在配置<file> </file><arg name="extensions" value="*"/>中使用*不起作用时,我“知道”它实际上甚至会停止.php文件的工作,如果你从.php切换到* - redanimalwar

-1

我不确定CS是否能够做到这一点,但我认为像bin/console这样的文件大多只有十行左右,所以没有必要使用代码嗅探器进行检查 :) 它们只需要从源代码中引用供应商并运行一些应用程序类即可。此外,在所有项目中它们都是相同的。

仅供参考,这是我们的bin/console。

#!/usr/bin/env php
<?php declare(strict_types = 1);

/** @var \Nette\DI\Container $container */
$container = require __DIR__ . '/../src/bootstrap.php';

/** @var \Symfony\Component\Console\Application $console */
$console = $container->getByType(Symfony\Component\Console\Application::class);

$services = $container->findByType(Symfony\Component\Console\Command\Command::class);

foreach ($services as $service) {
    $console->add(
        $container->getService($service)
    );
}

exit($console->run());

没有必要检查这个。


1
虽然我同意你的观点,但这并不能解决原帖作者的具体问题 :-) - Daniel W.
“大多数只有十行左右”?因为刚刚找到了一个短的吗?PHP非常适合shell脚本,比bash好得多。而且,并不是所有的脚本都需要在外部文件中进行结构化。我有一个名为0common.php的文件,其中包含我在多个脚本中使用的一些函数,但我有很多超过10行的脚本文件,我肯定希望它们被检查,而不必给它们添加.php扩展名。 - redanimalwar
@redanimalwar 不,你没有理解对... 你在谈论做某事的脚本... 它们肯定比10行更长... 但这个问题是关于 bin/console 的,它是CLI应用程序的ENTRYPOINT,根据我10年的经验,即使是我5年前创建的项目也完全相同。 - Lukáš Klíma
我在回答中也说过,这不是直接回答问题,但基本上与此有关,这根本不是问题。 - Lukáš Klíma
我们还使用最严格的工具检查每个文件,但在bin/console的情况下,这就没有意义了。:] - Lukáš Klíma
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接