squizlabs / PHP_CodeSniffer

PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.
BSD 3-Clause "New" or "Revised" License
10.67k stars 1.48k forks source link

The same rule, only the last one takes effect #3355

Open dongasai opened 3 years ago

dongasai commented 3 years ago

My executive information is as follows:

root@80525e84595d:/var/www/html# php vendor/bin/phpcs -a -p -vvv --ignore=1/pb_proto/*,1/db -
Processing ruleset /var/www/html/phpcs.xml
    Processing rule "Generic.Arrays.DisallowShortArraySyntax"
        => /var/www/html/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Arrays/DisallowShortArraySyntaxSniff.php
        => added rule-specific absolute ignore pattern: 1/1/
    Processing rule "Generic.PHP.ForbiddenFunctions"
        => /var/www/html/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php
        => array property "forbiddenFunctions" set to "time=>\SQLUtil::getCurrTimeStamp"
        => added rule-specific absolute ignore pattern: 1.php
        => added rule-specific absolute ignore pattern: 1.php
    Processing rule "Generic.PHP.ForbiddenFunctions"
        => /var/www/html/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php
        => array property "forbiddenFunctions" set to "delete=>unset,var_dump=>,dump=>,var_export=>"
        => added rule-specific absolute ignore pattern: 1/statistic/*
    Processing rule "Generic.PHP.ForbiddenFunctions"
        => /var/www/html/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php
        => array property "forbiddenFunctions" set to "var_export=>"
        => added rule-specific absolute ignore pattern: function.php
    Processing rule "Generic.PHP.ForbiddenFunctions"
        => /var/www/html/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php
        => array property "forbiddenFunctions" set to "echo=>echos,print_r=>print_rt"
        => added rule-specific absolute ignore pattern: 1/1/function.php
        => added rule-specific absolute ignore pattern: 1/script/*
        => added rule-specific absolute ignore pattern: 1/tests/*

However, only the last rule of generic.php.forbiddenfunctions will take effect. It is expected that all the rules will take effect and will be checked by polling

jrfnl commented 3 years ago

@dongasai Could you show the relevant part of your ruleset ?

Based on the above, I get the impression you are trying to include the Generic.PHP.ForbiddenFunctions sniff multiple times with different property values and different file ignore patterns and expect the ignore patterns to be applied for each set of property values.

That's not how PHPCS works.

If just plainly set, each new property setting will overwrite the previous one.

If instead you want to add to the existing property value, make sure you use extend="true", like so:

 <rule ref="Generic.PHP.ForbiddenFunctions">
  <properties>
   <property name="forbiddenFunctions" type="array" extend="true">
    <element key="sizeof" value="count"/>
   </property>
  </properties>
 </rule>

Also see the code samples in the wiki: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-Ruleset

As for the file ignore patterns, those are cumulative and they are not linked to the property value, but only to the sniff. So all of the ignore patterns will be applied to the sniff during the run, independently of the value set for the property.

If you want to be able to apply the ignore patterns for each property setting, you will need to create custom sniffs which extend the Generic.PHP.ForbiddenFunctions sniff. Based on the above, you would need three different sniffs. You can then set the property value for each either in the sniff itself or via the ruleset based on the names of your custom sniffs and similarly, you can then apply ignore patterns for each of the custom sniffs in your ruleset as well.

dongasai commented 3 years ago

I read the source code. The sniff set is marked with its name. The same name will override the former. Oh, it seems that I can only customize the sniff

dongasai commented 3 years ago

This is not a good feature and we hope to optimize it

gsherwood commented 3 years ago

Just to clarify what is being requested:

Are you trying to set different standards on different file in your code base? So, for example, you only want delete() to be banned for files under the 1/statistic/ directory?

dongasai commented 3 years ago

Just to clarify what is being requested:

Are you trying to set different standards on different file in your code base? So, for example, you only want delete() to be banned for files under the 1/statistic/ directory?

Yes, because different files run in different environments, the statistical folder is run by the developer, the control folder is run by the server (no output allowed), and the test folder is only used for testing (output allowed)

vpratfr commented 6 months ago

Hi,

I have I think the same requirement :

    <!-- No debug functions anywhere in the code -->
    <rule ref="Generic.PHP.ForbiddenFunctions">
        <properties>
            <property name="forbiddenFunctions" type="array">
                <element key="compact" value="null"/>
                <element key="dd" value="null"/>
                <element key="dump" value="null"/>
                <element key="var_dump" value="null"/>
                <element key="ray" value="null"/>
            </property>
        </properties>
    </rule>

    <!-- Use config() over env() except in the config directory where it is allowed -->
    <rule ref="Generic.PHP.ForbiddenFunctions">
        <exclude-pattern>/config/*</exclude-pattern>
        <properties>
            <property name="forbiddenFunctions" type="array">
                <element key="env" value="config"/>
            </property>
        </properties>
    </rule>

In that configuration, the best I could do is to merge both and exclude the config directory, but that means I would have debug functions in there (should not happen, but ideally I would still like to catch that)