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

w41d8nur  于 2022-11-28  发布在  PHP
关注(0)|答案(4)|浏览(150)

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

kx1ctssn

kx1ctssn1#

从文档中
忽略特定文件的文件扩展名是PHP_CodeSniffer的一个特性,也是检查没有扩展名的文件的唯一方法。如果你检查整个文件目录,所有没有扩展名的文件都将被忽略,所以你必须分别检查每个文件
https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage
因此您需要指定文件
语法为
phpcs --文件列表=路径/到/文件/包含/其他
其中others是一个每行一个文件结构的文件。
这将检查其他文件中列出的所有文件
埃格
文件1文件2控制台
检查3个文件

qlckcl4x

qlckcl4x2#

我认为您可以将*指定为通配符扩展名。
如果这不起作用,它在文档中声明:
如果您要求PHP_CodeSniffer检查一个特定的文件而不是整个目录,指定文件的扩展名将被忽略。即使该文件的扩展名无效或根本没有扩展名,该文件也会被检查。在下面的示例中,main.incPHP_CodeSniffer将检查www.example.com文件,即使命令行参数--extensions指定只检查.php文件。检查特定文件时忽略扩展名

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

因此,如果您显式检查没有扩展名的单个文件,它应该可以工作。
它还指出:
忽略特定文件的扩展名是PHP_CodeSniffer的一个特性,也是检查没有扩展名的文件的唯一方法。如果你检查整个文件目录,所有没有扩展名的文件都将被忽略,所以你必须分别检查每个文件。
请参阅https://pear.php.net/manual/en/package.php.php-codesniffer.advanced-usage.php

0sgqnhkj

0sgqnhkj3#

根据Issue #1754 PHP_CodeSniffer does not test PHP files with no extensions,它不被支持。你需要编写你自己的过滤器并将其作为参数传递。
这里有一个小例子,你应该根据自己的需要进行调整。(小项目速度快,大项目可能麻烦)寻找特定的she-bang模式(builtin MIME detection functions对我的用例不起作用)。例如,您可以添加一个位置白色名单来查找脚本。
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);
    }
}
6jjcrrmo

6jjcrrmo4#

我不知道CS是否可以做到这一点,但我认为像bin/console这样的文件大多数都是10行,所以没有必要用codesniffer检查它们:)它们应该只需要供应商和从源代码运行一些Application类。而且它们在所有项目中都是一样的。
仅供参考,我们的垃圾箱/控制台。

#!/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());

没有理由检查这个。

相关问题