{"id":16,"date":"2023-05-13T21:16:38","date_gmt":"2023-05-13T21:16:38","guid":{"rendered":"https:\/\/wp-yoda.com\/en\/?p=16"},"modified":"2024-01-31T17:27:19","modified_gmt":"2024-01-31T17:27:19","slug":"using-phpcs-linter-in-wordpress-with-wpcs-standard","status":"publish","type":"post","link":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/","title":{"rendered":"Using PHPCS in WordPress with WPCS standard"},"content":{"rendered":"\n<p>In this article we&#8217;ll talk about <strong>what a PHPCS linter is<\/strong>, as well as look at the importance of using it on a team project, customizing it, <strong>integrating PHPCS with the WPCS<\/strong> coding standard, and using it in GitHub Actions.<\/p>\n\n\n  \r\n    \r\n<div id=\"wpj-jtoc\" class=\"wpj-jtoc wpj-jtoc--main --jtoc-the-content --jtoc-theme-basic-light --jtoc-title-align-left --jtoc-toggle-icon --jtoc-toggle-position-right --jtoc-toggle-1 --jtoc-has-numeration --jtoc-numeration-legacy --jtoc-has-custom-styles --jtoc-is-unfolded --jtoc-align-left\" >\r\n  <!-- TOC -->\r\n        <div class=\"wpj-jtoc--toc wpj-jtoc--toc-inline \" >\r\n              <div class=\"wpj-jtoc--header\">\r\n        <div class=\"wpj-jtoc--header-main\">\r\n                    <div class=\"wpj-jtoc--title\">\r\n                        <span class=\"wpj-jtoc--title-label\">Table of contents<\/span>\r\n          <\/div>\r\n                                <div class=\"wpj-jtoc--toggle-wrap\">\r\n                                                          <div class=\"wpj-jtoc--toggle-box\">\r\n                  <div class=\"wpj-jtoc--toggle\"><\/div>\r\n                <\/div>\r\n                          <\/div>\r\n                  <\/div>\r\n      <\/div>\r\n            <div class=\"wpj-jtoc--body\">\r\n            <nav class=\"wpj-jtoc--nav\">\r\n        <ol class=\"wpj-jtoc--items\"><li class=\"wpj-jtoc--item --jtoc-h2\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h2\" data-depth=\"2\">\r\n                                                <a href=\"#what-is-a-linter-lint\"  title=\"What is a linter (Lint)\" data-numeration=\"1\">What is a linter (Lint)<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h2\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h2\" data-depth=\"2\">\r\n                                                <a href=\"#phpcs-php-codesniffer\"  title=\"PHPCS (PHP_CodeSniffer)\" data-numeration=\"2\">PHPCS (PHP_CodeSniffer)<\/a>\r\n                    <\/div><ol class=\"wpj-jtoc--items\"><li class=\"wpj-jtoc--item --jtoc-h3\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h3\" data-depth=\"3\">\r\n                                                <a href=\"#how-to-install\"  title=\"How to install\" data-numeration=\"2.1\">How to install<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h3\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h3\" data-depth=\"3\">\r\n                                                <a href=\"#how-to-use-phpcbf-php-code-beautifier-and-fixer\"  title=\"How to use PHPCBF (PHP Code Beautifier and Fixer)\" data-numeration=\"2.2\">How to use PHPCBF (PHP Code Beautifier and Fixer)<\/a>\r\n                    <\/div><\/li><\/ol><\/li><li class=\"wpj-jtoc--item --jtoc-h2\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h2\" data-depth=\"2\">\r\n                                                <a href=\"#wpcs-wordpress-coding-standards\"  title=\"WPCS (WordPress Coding Standards)\" data-numeration=\"3\">WPCS (WordPress Coding Standards)<\/a>\r\n                    <\/div><ol class=\"wpj-jtoc--items\"><li class=\"wpj-jtoc--item --jtoc-h3\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h3\" data-depth=\"3\">\r\n                                                <a href=\"#how-to-install-wpcs-standard\"  title=\"How to install WPCS standard\" data-numeration=\"3.1\">How to install WPCS standard<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h3\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h3\" data-depth=\"3\">\r\n                                                <a href=\"#configuring-wpcs-rules-best-practices\"  title=\"Configuring WPCS rules (Best Practices)\" data-numeration=\"3.2\">Configuring WPCS rules (Best Practices)<\/a>\r\n                    <\/div><ol class=\"wpj-jtoc--items\"><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#basic-settings\"  title=\"Basic settings\" data-numeration=\"3.2.1\">Basic settings<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#add-cache\"  title=\"Add Cache\" data-numeration=\"3.2.2\">Add Cache<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#what-to-scan\"  title=\"What to scan\" data-numeration=\"3.2.3\">What to scan<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#dont-use-yodaconditions\"  title=\"Don\u2019t use YodaConditions\" data-numeration=\"3.2.4\">Don\u2019t use YodaConditions<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#disabling-phpdocblock\"  title=\"Disabling PHPDocBlock\" data-numeration=\"3.2.5\">Disabling PHPDocBlock<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#class-files-in-camelcase-or-snake-case\"  title=\"Class files in CamelCase or Snake_Case\" data-numeration=\"3.2.6\">Class files in CamelCase or Snake_Case<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#a-ban-on-the-use-of-functions\"  title=\"A ban on the use of functions\" data-numeration=\"3.2.7\">A ban on the use of functions<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#autoescaped-functions\"  title=\"AutoEscaped functions\" data-numeration=\"3.2.8\">AutoEscaped functions<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#allow-php-short-syntax\"  title=\"Allow PHP short syntax\" data-numeration=\"3.2.9\">Allow PHP short syntax<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#using-in-hook-names\"  title=\"Using \u201c\/\u201d in hook names\" data-numeration=\"3.2.10\">Using \u201c\/\u201d in hook names<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#instruction-nesting-level\"  title=\"Instruction nesting level\" data-numeration=\"3.2.11\">Instruction nesting level<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#checking-the-code-for-compatibility-with-wordpress-versions\"  title=\"Checking the code for compatibility with WordPress versions\" data-numeration=\"3.2.12\">Checking the code for compatibility with WordPress versions<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#checking-code-for-compatibility-with-php-versions\"  title=\"Checking code for compatibility with PHP versions\" data-numeration=\"3.2.13\">Checking code for compatibility with PHP versions<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h4\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h4\" data-depth=\"4\">\r\n                                                <a href=\"#other-custom-rules\"  title=\"Other custom rules\" data-numeration=\"3.2.14\">Other custom rules<\/a>\r\n                    <\/div><\/li><\/ol><\/li><\/ol><\/li><li class=\"wpj-jtoc--item --jtoc-h2\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h2\" data-depth=\"2\">\r\n                                                <a href=\"#ignoring-rules-in-code\"  title=\"Ignoring rules in code\" data-numeration=\"4\">Ignoring rules in code<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h2\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h2\" data-depth=\"2\">\r\n                                                <a href=\"#how-to-use-phpcs-with-github-actions\"  title=\"How to use PHPCS with GitHub Actions\" data-numeration=\"5\">How to use PHPCS with GitHub Actions<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h2\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h2\" data-depth=\"2\">\r\n                                                <a href=\"#full-source-code\"  title=\"Full source code\" data-numeration=\"6\">Full source code<\/a>\r\n                    <\/div><\/li><li class=\"wpj-jtoc--item --jtoc-h2\">\r\n        <div class=\"wpj-jtoc--item-content --jtoc-h2\" data-depth=\"2\">\r\n                                                <a href=\"#the-result\"  title=\"The result\" data-numeration=\"7\">The result<\/a>\r\n                    <\/div><\/li><\/ol>      <\/nav>\r\n          <\/div>\r\n      <\/div>\r\n    <\/div>\r\n\n\n\n<h2 class=\"wp-block-heading\">What is a linter (Lint)<\/h2>\n\n\n\n<p><strong>Linter <\/strong>&#8211; is a static code analysis tool that checks for errors, bugs, and vulnerabilities.<br>How and what to check the static analyzer is set in the configuration file.<br>Read more about <strong>Linter<\/strong> by the link <a href=\"https:\/\/en.wikipedia.org\/wiki\/Lint_(software)\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Wiki<\/a>.<\/p>\n\n\n\n<p>There are different kinds of static analyzers: Phan, PHPStan, PSalm, <strong>PHPCS<\/strong>, etc. <br>You have to keep in mind that not all of them are completely static. <br>For example, the <code>PHPStan<\/code> analyzer uses under-the-hood hybrid reflection (<em>Runtime Reflection and Static Reflection<\/em>) for optimizing CPU time and RAM allocation.<\/p>\n\n\n\n<p><br>Using <em>Runtime Reflection<\/em> can lead us to unpleasant side effects like: &#8220;Executing code of a class or function that is called in the analyzed file&#8221;. Read more <a href=\"https:\/\/phpstan.org\/blog\/zero-config-analysis-with-static-reflection#hybrids-are-better-for-the-environment\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">by the link<\/a>.<\/p>\n\n\n\n<p>Although <strong>PHPCS<\/strong>, PHPStan, Phan, and PSalm are static analyzers, using they are different. <br>The last three are used for complex syntactic code analyses with building deeper AST (<em>abstract syntax tree<\/em>). They show us unused code, define type mismatch, and prevent runtime errors in turn allow us to use them while refactoring or supporting legacy code.<\/p>\n\n\n\n<p>Further in the article, I would like to speak in more detail about <strong>PHPCS<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">PHPCS (<strong>PHP_CodeSniffer<\/strong>)<\/h2>\n\n\n\n<p><strong>PHPCS<\/strong> &#8211; is a tool (<em>composer package<\/em>) for simplified static code analysis based on AST construction, checking the code for compliance with coding standards such as PSR2, PSR12, or <strong>WPCS<\/strong> <strong>(WordPress Coding Standards)<\/strong>.<\/p>\n\n\n\n<p><strong><strong>PHP_CodeSniffer<\/strong><\/strong> helps us:<\/p>\n\n\n\n<ul class=\"wp-block-list\" style=\"margin-top:0;margin-right:0;margin-bottom:0;margin-left:0\">\n<li>Monitor compliance with uniform code standards <em>(this is especially important when different people are working on the code)<\/em>.<\/li>\n\n\n\n<li>Write sequential, easy-to-read, supported code.<\/li>\n\n\n\n<li>Reduce the count of bugs and vulnerabilities.<\/li>\n<\/ul>\n\n\n\n<p>Out-of-the-box Liner supports the following coding standards: MySource, PEAR, PSR 1, PSR 2, PSR 12, Squiz, and Zend.<br>If necessary, you can additionally set the standard you require, such as <strong>WPCS<\/strong> or even create your own.<br>It also supports the customization of coding standards for the specific needs of the project, which we will consider in this article.<\/p>\n\n\n\n<p><strong>PHPCS<\/strong> can be used from the command line or integrated into an IDE (e.g. PhpStrom), or it can be built into CI\/CD processes.<\/p>\n\n\n\n<p>The Composer package <strong>PHP_CodeSniffer<\/strong> has two binary files:<\/p>\n\n\n\n<ul class=\"wp-block-list\" style=\"margin-top:0;margin-right:0;margin-bottom:0;margin-left:0\">\n<li><strong>phpcs<\/strong> &#8211; code analysis script for coding standards violations.<\/li>\n\n\n\n<li><strong>phpcbf<\/strong> &#8211; a script to automatically correct these violations.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">How to install<\/h3>\n\n\n\n<p>Let&#8217;s add <strong>PHPCS<\/strong> as a composer dependency:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncomposer require &quot;squizlabs\/php_codesniffer&quot; --dev\n<\/pre><\/div>\n\n\n<p>The flag <code>--dev<\/code> is required, because <strong>PHPCS<\/strong> will be installed into <code>dev dependencies<\/code> of composer.json, which in turn will not be installed for the production environment, in case you use the right installing composer packages.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote has-highlight-background-color has-background is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n<cite>for production using only<em> <\/em><code><em>composer install --no-dev<\/em><\/code> command<\/cite><\/blockquote>\n\n\n\n<p>Add the directive <code>scripts<\/code> with commands for <code>composer.json<\/code>, so that you will be able to run <strong>phpcs<\/strong> and <strong>phpcbf<\/strong> by using composer.<br>This trick can help you avoid errors related to running the wrong version of the binary file because they are run by the Composer itself.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n\/\/..... \n  &quot;require-dev&quot;: {\n    &quot;squizlabs\/php_codesniffer&quot;: &quot;^3.7&quot;\n  },\n  &quot;scripts&quot;: {\n    &quot;phpcs&quot;: &quot;phpcs&quot;,\n    &quot;phpcbf&quot;: &quot;phpcbf&quot;\n  }\n}\n<\/pre><\/div>\n\n\n<p>Further, create a file <code>PHPCSWorkExample.php<\/code> in the project with intentionally broken code styles.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n<cite>I would recommend copying the entire file from the repository (<a href=\"https:\/\/github.com\/renakdup\/using-phpcs-for-wordpress\/commit\/f74c36dbd3b29a611a8026fb02f1c39332c2f121\" target=\"_blank\" rel=\"noreferrer noopener\">see commit)<\/a>. Because your IDE may change the formatting when you insert it.<\/cite><\/blockquote>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n \nclass PHPCSWorkExample {\n    private $name = &#039;test&#039;;\n\tfunction get_test_name() {\n      return $this-&gt;name;\n\t}\n}\n\n<\/pre><\/div>\n\n\n<p>The next step is to try to start the linter.<br>The flag  <code>--standard=PSR2<\/code> means that we will check the file <code>index.php<\/code> for compliance with PSR-2: Coding Style Standard.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncomposer run phpcs -- --standard=PSR2 .\/PHPCSWorkExample.php\n<\/pre><\/div>\n\n\n<p>And what do we see? <br>&#8211; A list of errors that do not match the PSR2 standard of the <code>PHPCSWorkExample.php<\/code> file and at the end of our command ends with an error code.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&gt; phpcs &#039;--standard=PSR2&#039; &#039;.\/PHPCSWorkExample.php&#039;\nFILE: \/usr\/src\/myapp\/PHPCSWorkExample.php\n---------------------------------------------------------------------------------------------------\nFOUND 8 ERRORS AFFECTING 4 LINES\n---------------------------------------------------------------------------------------------------\n 3 | ERROR | &#x5B; ] Each class must be in a namespace of at least one level (a top-level vendor name)\n 3 | ERROR | &#x5B;x] Opening brace of a class must be on the line after the definition\n 6 | ERROR | &#x5B;x] Spaces must be used to indent lines; tabs are not allowed\n 6 | ERROR | &#x5B; ] Method name &quot;PHPCSWorkExample::get_test_name&quot; is not in camel caps format\n 6 | ERROR | &#x5B; ] Visibility must be declared on method &quot;get_test_name&quot;\n 6 | ERROR | &#x5B;x] Opening brace should be on a new line\n 7 | ERROR | &#x5B;x] Line indented incorrectly; expected at least 8 spaces, found 6\n 8 | ERROR | &#x5B;x] Spaces must be used to indent lines; tabs are not allowed\n---------------------------------------------------------------------------------------------------\nPHPCBF CAN FIX THE 5 MARKED SNIFF VIOLATIONS AUTOMATICALLY\n---------------------------------------------------------------------------------------------------\nTime: 61ms; Memory: 6MB\nScript phpcs handling the phpcs event returned with error code 2\n<\/pre><\/div>\n\n\n<p>Note the string in the output of the console:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/..\nPHPCBF CAN FIX THE 5 MARKED SNIFF VIOLATIONS AUTOMATICALLY\n\/\/...\n<\/pre><\/div>\n\n\n<p><strong>PHPCS<\/strong> prompts us to automatically fix the irregularities found by using the <strong>PHPCBF<\/strong> command.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How to use PHPCBF (PHP Code Beautifier and Fixer)<\/h3>\n\n\n\n<p>Let&#8217;s follow <strong>PHPCS<\/strong>&#8216; advice and try to fix errors by using the <strong>PHPCBF<\/strong> command:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncomposer run phpcbf -- --standard=PSR2 .\/PHPCSWorkExample.php\n<\/pre><\/div>\n\n\n<p>We see that <strong>PHPCBF<\/strong> fixed 5 errors in the file, but there are 3 not fixed.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/usr\/src\/myapp # composer run phpcbf -- --standard=PSR2 .\/PHPCSWorkExample.php\n&gt; phpcbf --standard=.\/phpcs.xml &#039;--standard=PSR2&#039; &#039;.\/PHPCSWorkExample.php&#039;\nPHPCBF RESULT SUMMARY\n----------------------------------------------------------------------\nFILE                                                  FIXED  REMAINING\n----------------------------------------------------------------------\n\/usr\/src\/myapp\/PHPCSWorkExample.php                   5      3\n----------------------------------------------------------------------\nA TOTAL OF 5 ERRORS WERE FIXED IN 1 FILE\n----------------------------------------------------------------------\nTime: 50ms; Memory: 6MB\nScript phpcbf --standard=.\/phpcs.xml handling the phpcbf event returned with error code 1\n<\/pre><\/div>\n\n\n<p>Let&#8217;s check this and run the check codestyle command again<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncomposer run phpcbf -- --standard=PSR2 .\/PHPCSWorkExample.php\n<\/pre><\/div>\n\n\n<p>And indeed, we see that now we have only 3 errors, which automatically could not be fixed by <strong>phpcbf<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n-----------------------------------------------------------------------------------------------\nFOUND 3 ERRORS AFFECTING 2 LINES\n-----------------------------------------------------------------------------------------------\n 3 | ERROR | Each class must be in a namespace of at least one level (a top-level vendor name)\n 7 | ERROR | Method name &quot;PHPCSWorkExample::get_test_name&quot; is not in camel caps format\n 7 | ERROR | Visibility must be declared on method &quot;get_test_name&quot;\n-----------------------------------------------------------------------------------------------\n<\/pre><\/div>\n\n\n<p>This happened because <strong>PHPCBF<\/strong> is not always able to fix all errors in the code.<br><br>This can happen for several reasons:<\/p>\n\n\n\n<ul class=\"wp-block-list\" style=\"margin-top:0;margin-right:0;margin-bottom:0;margin-left:0\">\n<li><strong>PHPCBF<\/strong> cannot fix errors if the code is syntactically incorrect, contains logical errors, or requires additional programming. In such cases, it is necessary to edit the code manually.<\/li>\n\n\n\n<li><strong>PHPCBF<\/strong> may not be configured to use all coding rules that are used on the project. If you use non-standard rules that are not supported by <strong>PHPCBF<\/strong>, it will not be able to fix the corresponding errors.<\/li>\n\n\n\n<li>Some <strong>PHPCS<\/strong> rules need to be ignored manually when the situation demands it <em>(About this below)<\/em>.<\/li>\n<\/ul>\n\n\n\n<p>You can only fix such errors manually, relying on the using style guide and the messages from <strong>PHPCS<\/strong> in the console.<br><br>After all the manual corrections, our file will look like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\nnamespace APP;\n \nclass PHPCSWorkExample\n{\n    private $name = &#039;test&#039;;\n    public function getTestName()\n    {\n        return $this-&gt;name;\n    }\n}\n\n<\/pre><\/div>\n\n\n<blockquote class=\"wp-block-quote has-highlight-light-background-color has-background is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n<cite>Remember that automatic code correction tools can lead to unwanted changes in your code, so you should always be careful and check these changes manually.<\/cite><\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote has-highlight-light-background-color has-background is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n<cite>If you find a lot of errors, first I recommend to commit the code and then run the <strong>PHPCBF<\/strong> command and compare the files difference. Then you will be sure that autofix was successful.<\/cite><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">WPCS (<strong>WordPress Coding Standards<\/strong>)<\/h2>\n\n\n\n<p><strong>WPCS<\/strong> (<strong>WordPress Coding Standards<\/strong>) &#8211; is a set of rules for writing code for WordPress.<\/p>\n\n\n\n<p><strong>WordPress Coding Standards<\/strong> for <strong>PHPCS<\/strong> &#8211; is a collection of <strong>PHP_CodeSniffer<\/strong> rules (sniffs) for checking code written for <strong>WordPress<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How to install WPCS standard<\/h3>\n\n\n\n<p>You can install the <strong>WPCS<\/strong> set of rules by using Composer:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncomposer require wp-coding-standards\/wpcs --dev\n<\/pre><\/div>\n\n\n<blockquote class=\"wp-block-quote is-style-default has-black-color has-highlight-light-background-color has-text-color has-background is-layout-flow wp-block-quote-is-layout-flow\">\n<p>As of this writing 13.04.2023, the WPCS sniffer package does not work with PHP above 7.4<\/p>\n<cite>To install the package with the fixes, use the <code>dev-develop<\/code> branch:<br><code>composer require wp-coding-standards\/wpcs:\"dev-develop\" --dev<\/code>  .<br>Read more at the link <a href=\"https:\/\/github.com\/WordPress\/WordPress-Coding-Standards\/issues\/2087\" target=\"_blank\" rel=\"noreferrer noopener\">issues\/2087<\/a><br><\/cite><\/blockquote>\n\n\n\n<p>After installing the <strong>WPCS<\/strong> standard, run the command to see which standards are currently connected to <strong>PHPCS<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncomposer run phpcs -- -i\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nThe installed coding standards are MySource, PEAR, PSR1, PSR2, PSR12, Squiz and Zend\n<\/pre><\/div>\n\n\n<p>But where are our <strong>WordPress Coding Standards<\/strong>?<\/p>\n\n\n\n<p>In order to pull them up, we need to add a package that makes it easy to use the new <strong>PHP_CodeSniffer<\/strong> standards, without having to manually configure them:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncomposer require --dev dealerdirect\/phpcodesniffer-composer-installer\n<\/pre><\/div>\n\n\n<p>Now if we run the command  <code>composer run phpcs -- -i<\/code> , we see that all <strong>WPCS<\/strong> standards are available to us:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nThe installed coding standards are MySource, PEAR, PSR1, PSR2, PSR12, Squiz, Zend, WordPress, WordPress-Core, WordPress-Docs and WordPress-Extra\n<\/pre><\/div>\n\n\n<p>I suggest that you check whether our <code>PHPCSWorkExample.php<\/code> complies with the <strong>WPCS<\/strong> standard:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\ncomposer run phpcs -- --standard=WordPress .\/PHPCSWorkExample.php\n<\/pre><\/div>\n\n\n<p>And we get the result<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&gt; phpcs &#039;--standard=WordPress&#039; &#039;.\/PHPCSWorkExample.php&#039;\nFILE: \/usr\/src\/myapp\/PHPCSWorkExample.php\n---------------------------------------------------------------------------------------------------------------------------------------------------------------------\nFOUND 16 ERRORS AND 1 WARNING AFFECTING 9 LINES\n---------------------------------------------------------------------------------------------------------------------------------------------------------------------\n  1 | ERROR   | &#x5B; ] Filenames should be all lowercase with hyphens as word separators. Expected phpcsworkexample.php, but found PHPCSWorkExample.php.\n  1 | ERROR   | &#x5B; ] Class file names should be based on the class name with &quot;class-&quot; prepended. Expected class-phpcsworkexample.php, but found PHPCSWorkExample.php.\n  1 | ERROR   | &#x5B; ] Missing file doc comment\n  4 | WARNING | &#x5B; ] Found precision alignment of 1 spaces.\n  4 | ERROR   | &#x5B;x] Whitespace found at end of line\n  5 | ERROR   | &#x5B; ] Missing doc comment for class PHPCSWorkExample\n  6 | ERROR   | &#x5B;x] Opening brace should be on the same line as the declaration for class PHPCSWorkExample\n  7 | ERROR   | &#x5B;x] Tabs must be used to indent lines; spaces are not allowed\n  7 | ERROR   | &#x5B; ] Missing member variable doc comment\n  9 | ERROR   | &#x5B;x] Tabs must be used to indent lines; spaces are not allowed\n  9 | ERROR   | &#x5B;x] Expected exactly one space between closing parenthesis and opening control structure; &quot;\n    |         |     &quot; found.\n  9 | ERROR   | &#x5B; ] Method name &quot;getTestName&quot; in class PHPCSWorkExample is not in snake case format, try &quot;get_test_name&quot;\n  9 | ERROR   | &#x5B; ] Missing doc comment for function getTestName()\n 10 | ERROR   | &#x5B;x] Tabs must be used to indent lines; spaces are not allowed\n 10 | ERROR   | &#x5B;x] Opening brace should be on the same line as the declaration\n 11 | ERROR   | &#x5B;x] Tabs must be used to indent lines; spaces are not allowed\n 12 | ERROR   | &#x5B;x] Tabs must be used to indent lines; spaces are not allowed\n---------------------------------------------------------------------------------------------------------------------------------------------------------------------\nPHPCBF CAN FIX THE 9 MARKED SNIFF VIOLATIONS AUTOMATICALLY\n---------------------------------------------------------------------------------------------------------------------------------------------------------------------\nTime: 750ms; Memory: 6MB\nScript phpcs handling the phpcs event returned with error code 2\n\n<\/pre><\/div>\n\n\n<p>Run the <strong>PHPCBF<\/strong> auto fixer again, and we are left with 7 errors in 4 lines.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n--------------------------------------------------------------------------------------------------------------------------------------------------------------\n 1 | ERROR | Filenames should be all lowercase with hyphens as word separators. Expected phpcsworkexample.php, but found PHPCSWorkExample.php.\n 1 | ERROR | Class file names should be based on the class name with &quot;class-&quot; prepended. Expected class-phpcsworkexample.php, but found PHPCSWorkExample.php.\n 1 | ERROR | Missing file doc comment\n 5 | ERROR | Missing doc comment for class PHPCSWorkExample\n 7 | ERROR | Missing member variable doc comment\n 9 | ERROR | Method name &quot;getTestName&quot; in class PHPCSWorkExample is not in snake case format, try &quot;get_test_name&quot;\n 9 | ERROR | Missing doc comment for function getTestName()\n--------------------------------------------------------------------------------------------------------------------------------------------------------------\n<\/pre><\/div>\n\n\n<p>When you have fulfilled all the PHPCS code style requirements, your file will be renamed  <code>class-phpcsworkexample.php<\/code> and look as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\/**\n * PHPCSWorkExample\n *\n * @package APP\n *\/\nnamespace APP;\n\/**\n * PHPCSWorkExample\n *\/\nclass PHPCSWorkExample {\n\t\/**\n\t * Test name.\n\t *\n\t * @var string $name\n\t *\/\n\tprivate $name = &#039;test&#039;;\n\t\/**\n\t * Get test name.\n\t *\n\t * @return string\n\t *\/\n\tpublic function get_test_name() {\n\t\treturn $this-&gt;name;\n\t}\n}\n\n<\/pre><\/div>\n\n\n<blockquote class=\"wp-block-quote has-highlight-light-background-color has-background is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n<cite>Some bugs that <strong>PHPCS<\/strong> has thrown out may seem redundant, and may only make User Expirience worse when dealing with code such as &#8220;strict naming of class files&#8221;.<br><br>&#8211; And yes, you&#8217;re right, in the next chapter we will learn how to configure custom <strong>WPCS<\/strong> rules for our project.<\/cite><\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Configuring WPCS rules (Best Practices)<\/h3>\n\n\n\n<p>The <strong>PHP_CodeSniffer<\/strong> allows developers to configure their own coding standards by creating a <code>phpcs.xml<\/code> file with their own set of rules. Within the file, we can use existing coding standards, and modify them to make them simpler or stricter for the needs of our project.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Basic settings<\/h4>\n\n\n\n<p>First, you need to create a file <code>phpcs.xml<\/code> in the root of project with the next content:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;?xml version=&quot;1.0&quot;?&gt;\n&lt;ruleset name=&quot;WordPress Coding Standards&quot;&gt;\n    &lt;description&gt;A custom set of code standard rules to check for WordPress code.&lt;\/description&gt;\n    &lt;!-- How to scan --&gt;\n    &lt;arg value=&quot;sp&quot;\/&gt;&lt;!-- Show sniff and progress --&gt;\n    &lt;arg name=&quot;basepath&quot; value=&quot;.\/&quot;\/&gt;&lt;!-- Strip the file paths down to the relevant bit --&gt;\n    &lt;arg name=&quot;extensions&quot; value=&quot;php&quot;\/&gt;\n    &lt;arg name=&quot;parallel&quot; value=&quot;10&quot;\/&gt;&lt;!-- Enables parallel processing when available for faster results. --&gt;\n    &lt;arg name=&quot;cache&quot; value=&quot;.phpcs.cache&quot;\/&gt;\n    &lt;!-- What to scan --&gt;\n    &lt;file&gt;.\/&lt;\/file&gt;\n    &lt;!-- Exclude basic project directories --&gt;\n    &lt;exclude-pattern&gt;*\/.idea\/*&lt;\/exclude-pattern&gt;\n    &lt;exclude-pattern&gt;*\/.github\/*&lt;\/exclude-pattern&gt;\n    &lt;exclude-pattern&gt;*\/vendor\/*&lt;\/exclude-pattern&gt;\n    &lt;exclude-pattern&gt;*\/node_modules\/*&lt;\/exclude-pattern&gt;\n    &lt;exclude-pattern&gt;*\/assets\/*&lt;\/exclude-pattern&gt;\n    &lt;exclude-pattern&gt;wp-content\/uploads\/&lt;\/exclude-pattern&gt;\n    &lt;rule ref=&quot;WordPress&quot;\/&gt;\n&lt;\/ruleset&gt;\n<\/pre><\/div>\n\n\n<p>In the config, we specified that we use a <strong>WordPress<\/strong> ruleset, scan only php files, display the scanning process, run in 10 threads to speed up analysis and cache the result in a <code>.phpcs.cache<\/code> file.<\/p>\n\n\n\n<p>Now that our config is ready, all we have to do is to specify where <strong>PHPCS<\/strong> will pick it up from. <br>Go to the <code>composer.json<\/code> file and fix the <code>scripts<\/code> block:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n  &quot;scripts&quot;: {\n    &quot;phpcs&quot;: &quot;phpcs --standard=.\/phpcs.xml&quot;,\n    &quot;phpcbf&quot;: &quot;phpcbf --standard=.\/phpcs.xml&quot;\n  },\n<\/pre><\/div>\n\n\n<p>Now you can execute commands with this config in mind<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncomposer run phpcs\ncomposer run phpcbf\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">Add Cache<\/h4>\n\n\n\n<p>Be sure to add a directive that caches <strong>PHPCS<\/strong> results, as this will save a huge amount of time when the linter is run again:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;arg name=&quot;cache&quot; value=&quot;.phpcs.cache&quot;\/&gt;\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">What to scan<\/h4>\n\n\n\n<p>I recommend using the &#8220;Scan everything but what is forbidden&#8221; approach.<br>I.e. we need to allow scanning everything in directories <code>\/mu-plugins\/<\/code>, <code>\/plugins<\/code>, <code>\/themes<\/code> except what is forbidden. And in the forbidden be third-party plugins and themes, which you can prescribe in the <strong>PHPCS<\/strong> config as exceptions manually.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- .... --&gt; \n   &lt;!-- What to scan --&gt;\n    &lt;file&gt;wp-content\/mu-plugins\/&lt;\/file&gt;\n    &lt;file&gt;wp-content\/plugins\/&lt;\/file&gt;\n    &lt;file&gt;wp-content\/themes\/&lt;\/file&gt;\n    &lt;!-- Exclude &quot;Third-party Themes&quot; --&gt;\n    &lt;exclude-pattern&gt;wp-content\/themes\/twentytwenty\/&lt;\/exclude-pattern&gt;\n    &lt;!-- Exclude &quot;Third-party Plugins&quot; --&gt;\n    &lt;exclude-pattern&gt;wp-content\/plugins\/advanced-custom-fields-pro\/&lt;\/exclude-pattern&gt;\n&lt;!-- .... --&gt;\n<\/pre><\/div>\n\n\n<p>Why is it necessary to do this?<br>The answer is simple: If the developer creates a new theme or plugin, your code will default to the <strong>PHPCS<\/strong> scanning area and your <strong>CI<\/strong> will never miss a standards violation, which is not the case with the &#8220;Scan only what is allowed&#8221; approach. If you use the second one, you will regularly see code with violates the standards.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Don&#8217;t use YodaConditions<\/h4>\n\n\n\n<p>Yoda Conditional is one of the most annoying rules of the <strong>WPCS<\/strong> standard, which brings more problems than benefits.<br>Here is a quote from the HumanMade CodeStyle Convention that details the pain:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n<cite>&lt;!&#8211;<br>OK, real talk right now. Yoda conditions are ridiculous.<br>The fundamental problem that Yoda conditions attempts to solve is:<br>the equality operator is very close to the assignment operator.<br>It&#8217;s easy to mess up and accidentally assign to the variable you&#8217;re<br>trying to check.<br>Here&#8217;s the thing though. Yoda conditions just don&#8217;t read correctly<br>in the code flow. They require you to change the way you think<br>about the control flow.<br>Rather than forcing every conditional to be backwards, why not ban<br>assignment from conditionals? You never really *need* to assign in<br>a conditional.<br>So, here&#8217;s where I stand: no to Yoda conditions. Yes to banning<br>assignment in conditionals.<br>&#8211;&gt;<br><br>Source: <a href=\"https:\/\/github.com\/humanmade\/coding-standards\/blob\/master\/HM\/ruleset.xml\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/humanmade\/coding-standards\/blob\/master\/HM\/ruleset.xml<\/a><\/cite><\/blockquote>\n\n\n\n<p>Prohibit the use of YodaConditional in <code>phpcs.xml<\/code><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- .... --&gt;\n&lt;rule ref=&quot;WordPress&quot;&gt;\n    &lt;!-- .... --&gt;\n    &lt;exclude name=&quot;WordPress.PHP.YodaConditions&quot; \/&gt;\n    &lt;!-- .... --&gt;\n&lt;\/rule&gt;\n&lt;!-- .... --&gt;\n&lt;!-- Prohibit Yoda Conditions expressions --&gt;\n&lt;rule ref=&quot;Generic.ControlStructures.DisallowYodaConditions&quot;\/&gt;\n&lt;!-- .... --&gt;\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">Disabling PHPDocBlock<\/h4>\n\n\n\n<p>The <strong>WPCS<\/strong> rules for comments are quite strict and redundant.<br>If you&#8217;re writing smart code, you shouldn&#8217;t have to write a comment on every property\/method\/class\/file<br>The names of your functions, classes, files, and properties should describe what is happening inside or what entity they belong to.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote has-highlight-light-background-color has-background is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n<cite>Write comments where it is only necessary.<\/cite><\/blockquote>\n\n\n\n<p>We&#8217;ll loosen the commenting rules with the following settings:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- .... --&gt;\n&lt;rule ref=&quot;WordPress&quot;&gt;\n        &lt;!-- .... --&gt;   \n        &lt;exclude name=&quot;Generic.Commenting.DocComment.MissingShort&quot; \/&gt;\n        &lt;!-- Disable dot of end string docblock --&gt;\n        &lt;exclude name=&quot;Squiz.Commenting.InlineComment.InvalidEndChar&quot; \/&gt;\n        &lt;!-- .... --&gt;\n&lt;\/rule&gt;\n&lt;!-- .... --&gt;\n &lt;!-- Disable comments blocks --&gt;\n    &lt;rule ref=&quot;WordPress-Docs&quot;&gt;\n        &lt;exclude name=&quot;Squiz.Commenting.FileComment.Missing&quot; \/&gt;\n        &lt;exclude name=&quot;Squiz.Commenting.FileComment.MissingPackageTag&quot; \/&gt;\n        &lt;exclude name=&quot;Squiz.Commenting.ClassComment.Missing&quot; \/&gt;\n        &lt;exclude name=&quot;Squiz.Commenting.FunctionComment.Missing&quot; \/&gt;\n        &lt;exclude name=&quot;Squiz.Commenting.FunctionComment.SpacingAfterParamType&quot; \/&gt;\n        &lt;exclude name=&quot;Squiz.Commenting.VariableComment.Missing&quot; \/&gt;\n        &lt;exclude name=&quot;Squiz.Commenting.FunctionComment.MissingParamComment&quot; \/&gt;\n        &lt;exclude name=&quot;Squiz.Commenting.FunctionComment.MissingParamTag&quot; \/&gt;\n    &lt;\/rule&gt;\n&lt;!-- .... --&gt;\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">Class files in CamelCase or Snake_Case<\/h4>\n\n\n\n<p>In <strong>WPCS<\/strong> rules, there are strict rules for class file names, and we had to rename our file into <code>class-phpcsworkexample.php<\/code> to comply with them, which does not make the file names readable &#8211; you need a knack for extracting entity names from them.<br>These class names are not at all consistent with the accepted standards in PHP, and moreover, do not lend themselves to sound logic.<br>I suggest disabling these rules, which will allow us to name class files in CamelCase (PSR) or Snake_Case format (<em>I suggest following the CamelCase, because it is a PSR format<\/em>).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- .... --&gt; \n   &lt;rule ref=&quot;WordPress&quot;&gt;\n        &lt;!-- .... --&gt;\n        &lt;exclude name=&quot;WordPress.Files.FileName.InvalidClassFileName&quot; \/&gt;\n        &lt;exclude name=&quot;WordPress.Files.FileName.NotHyphenatedLowercase&quot; \/&gt;\n        &lt;!-- .... --&gt;\n    &lt;\/rule&gt;\n&lt;!-- .... --&gt;\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">A ban on the use of functions<\/h4>\n\n\n\n<p>Some of the functions should be banned for security reasons. Others are debug functions and should not be in production. Others can cause potential bugs in refactoring. For these purposes, in <strong>PHPCS<\/strong> you can add the block of rules below.<br>You can also expand it with your own functions.<br>For example: &#8220;<em>deprecated<\/em>&#8221; by functions in your project that need to be refactored or replaced.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- .... --&gt;\n    &lt;!-- Forbidden functions --&gt;\n    &lt;rule ref=&quot;Generic.PHP.ForbiddenFunctions&quot;&gt;\n        &lt;properties&gt;\n            &lt;property name=&quot;forbiddenFunctions&quot; type=&quot;array&quot;&gt;\n                &lt;element key=&quot;delete&quot; value=&quot;unset&quot;\/&gt;\n                &lt;element key=&quot;print&quot; value=&quot;echo&quot;\/&gt;\n                &lt;element key=&quot;create_function&quot; value=&quot;null&quot;\/&gt;\n                &lt;element key=&quot;sizeof&quot; value=&quot;count&quot;\/&gt;\n                &lt;!-- &lt;element key=&quot;var_dump&quot; value=&quot;null&quot;\/&gt; duplicate of WP rule--&gt;\n                &lt;element key=&quot;print_r&quot; value=&quot;null&quot;\/&gt;\n                &lt;element key=&quot;eval&quot; value=&quot;null&quot;\/&gt;\n                &lt;element key=&quot;compact&quot; value=&quot;null&quot;\/&gt;\n            &lt;\/property&gt;\n        &lt;\/properties&gt;\n    &lt;\/rule&gt;\n&lt;!-- .... --&gt;\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\">AutoEscaped functions<\/h4>\n\n\n\n<p>Some of your functions may already contain escaping inside and unfortunately, <strong>WPCS<\/strong> will not understand it.<br>In this case, you have two ways around it:<\/p>\n\n\n\n<ul class=\"wp-block-list\" style=\"margin-top:0;margin-right:0;margin-bottom:0;margin-left:0\">\n<li>Use <em>phpcs:ignore<\/em> in the code where you use this function<br><code>\/\/phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped<\/code><\/li>\n\n\n\n<li>Add to the auto-escaped functions block in the <em>phpcs.xml<\/em> file<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- .... --&gt;\n  \n  &lt;!-- AutoEscaped functions --&gt;\n    &lt;rule ref=&quot;WordPress.Security.EscapeOutput&quot;&gt;\n        &lt;properties&gt;\n            &lt;property name=&quot;customAutoEscapedFunctions&quot; type=&quot;array&quot;&gt;\n                &lt;element value=&quot;rd_render_attributes&quot; \/&gt;\n                &lt;element value=&quot;rd_get_picture_html&quot; \/&gt;\n            &lt;\/property&gt;\n        &lt;\/properties&gt;\n    &lt;\/rule&gt;\n&lt;!-- .... --&gt;\n<\/pre><\/div>\n\n\n<p>I recommend the 2nd option because your code will be cleaner.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Allow PHP short syntax<\/h4>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- .... --&gt;\n    &lt;rule ref=&quot;WordPress&quot;&gt;\n        &lt;!-- Allow short ternary syntax and short arrays and short open tag --&gt;\n        &lt;exclude name=&quot;Generic.Arrays.DisallowShortArraySyntax&quot; \/&gt;\n        &lt;exclude name=&quot;WordPress.PHP.DisallowShortTernary.Found&quot; \/&gt;\n        &lt;exclude name=&quot;Generic.PHP.DisallowShortOpenTag.EchoFound&quot; \/&gt;\n    &lt;\/rule&gt;\n&lt;!-- .... --&gt;\n    &lt;!-- Disallow long array syntax. --&gt;\n    &lt;rule ref=&quot;Generic.Arrays.DisallowLongArraySyntax.Found&quot;\/&gt;\n&lt;!-- .... --&gt;\n<\/pre><\/div>\n\n\n<p>In the above rules, we allow Short Array Syntax and disallow Long Array Syntax in order to maintain a single-style convention<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\/\/available\n$data = &#x5B;\n\t&#039;one&#039; =&gt; &#039;one-data&#039;,\n\t&#039;two&#039; =&gt; &#039;two-data&#039;,\n\t&#039;three&#039; =&gt; &#039;three-data&#039;,\n];\n\/\/unvailable\n$data = array(\n\t&#039;one&#039; =&gt; &#039;one-data&#039;,\n\t&#039;two&#039; =&gt; &#039;two-data&#039;,\n\t&#039;three&#039; =&gt; &#039;three-data&#039;,\n);\n<\/pre><\/div>\n\n\n<p>Also, allow Ternary Syntax<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\/\/available\n$data = $request ? $request-&gt;data : null;\n<\/pre><\/div>\n\n\n<p>And allow <em>Short Open Tag with Echo<\/em> <code>&lt;?=<\/code> :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;!--available --&gt;\n&lt;p&gt;&lt;?= $a ?&gt;&lt;p&gt;\n<\/pre><\/div>\n\n\n<p>It should not be confused with the ASP style tag <code>&lt;?<\/code> , because the second one was deprecated in PHP and is no longer supported, while <code>&lt;?=<\/code> allows us to write more concise code.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Using &#8220;\/&#8221; in hook names<\/h4>\n\n\n\n<p>Allowing <code>\/<\/code> in hook names allow us to write expressive hooks reminiscent of the concept of <em>namespaces<\/em>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php \n\/\/available\n$path_to_font = apply_filters( &#039;rd\/plugin-name\/class-name\/component-name&#039;, $data );\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- .... --&gt;   \n    &lt;!-- Allow symbol `\/` in hook names. --&gt;\n    &lt;rule ref=&quot;WordPress.NamingConventions.ValidHookName&quot;&gt;\n        &lt;properties&gt;\n            &lt;property name=&quot;additionalWordDelimiters&quot; value=&quot;\/&quot; \/&gt;\n        &lt;\/properties&gt;\n    &lt;\/rule&gt;\n&lt;!-- .... --&gt;\n<\/pre><\/div>\n\n\n<p>In our project, the development team fell in love with this code style quite quickly, because everyone had a direct analogy with the namespaces concept in PHP.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Instruction nesting level<\/h4>\n\n\n\n<p>This rule defines the nesting level of instructions <code>if else<\/code>, <code>while<\/code>, <code>forach<\/code>, <code>for<\/code> etc, and outputs an error if it is exceeded:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- .... --&gt;    \n   &lt;rule ref=&quot;Generic.Metrics.NestingLevel&quot;&gt;\n        &lt;properties&gt;\n            &lt;property name=&quot;absoluteNestingLevel&quot; value=&quot;3&quot;\/&gt;\n        &lt;\/properties&gt;\n    &lt;\/rule&gt;\n&lt;!-- .... --&gt;   \n<\/pre><\/div>\n\n\n<p>This rule inevitably affects the quality of the code and its support, with a high level of nesting the code becomes difficult to read.<br>Here is an example, at nesting level 2 we can write the following code:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\nif ( $data&#x5B;&#039;request&#039;] ) {\n\tif ($data&#x5B;&#039;request&#039;]&#x5B;&#039;method&#039;] === &#039;GET&#039; ) {\n\t\techo &quot;Hello World!&quot;;\n\t}\n}\n<\/pre><\/div>\n\n\n<p>But if we set the value <code>absoluteNestingLevel<\/code> by 1, then we get an error.<\/p>\n\n\n\n<p>I recommend you set it to 3, but sometimes there are complex legacy projects where you have to set it to 4. In general, no one prevents you from adding 2 rules, for legacy code with <code>absoluteNestingLevel=4<\/code> and for the new code with <code>absoluteNestingLevel=3<\/code>. You only need to specify the directories for each rule block.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Checking the code for compatibility with WordPress versions<\/h4>\n\n\n\n<p><strong>WPCS<\/strong> has a sniffer to check the code for the minimum compatible version of <strong>WordPress<\/strong>. This sniffer checks for deprecated functions, classes, and function parameters.<br><br>For deleted features before <code><code>minimum_wp_version<\/code><\/code>, you get an error. When determining the deprecated features between <code><code>minimum_wp_version<\/code><\/code> and the current release, you get a warning.<\/p>\n\n\n\n<p><strong>For example<\/strong>: the function&nbsp;<code>add_object_page()<\/code>&nbsp;was deprecated in WP 4.5. If usage of this function is detected, the sniff will throw an error if the&nbsp;<code>minimum_wp_version<\/code>&nbsp;is&nbsp;<code>4.6<\/code>&nbsp;or higher. It will throw a warning if the&nbsp;<code>minimum_wp_version<\/code>&nbsp;is&nbsp;<code>4.5<\/code>&nbsp;or lower.<\/p>\n\n\n\n<p>Add this rule to our <code>phpcs.xml<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n    &lt;!-- Minimum WP version to check for usage of deprecated functions, classes and function parameters --&gt;\n    &lt;config name=&quot;minimum_wp_version&quot; value=&quot;5.4.1&quot;\/&gt;\n<\/pre><\/div>\n\n\n<blockquote class=\"wp-block-quote has-highlight-light-background-color has-background is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n<cite>Prior to WordPressCS 3.0.0, the setting name for CLI was called&nbsp;<code>minimum_supported_wp_version<\/code>.<\/cite><\/blockquote>\n\n\n\n<p>Specify the version of <strong>WordPress<\/strong> you&#8217;re currently using, or the one you want to upgrade to, to check your code for <strong>compatibility<\/strong>.<\/p>\n\n\n\n<p>You can read more about <code>minimum_wp_version<\/code> <a href=\"https:\/\/github.com\/WordPress\/WordPress-Coding-Standards\/wiki\/Customizable-sniff-properties#various-sniffs-set-the-minimum-supported-wp-version\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">at this link<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Checking code for compatibility with PHP versions<\/h4>\n\n\n\n<p>Using <strong>PHPCompatibilityWP<\/strong>, you can analyze the code base of your <strong>WordPress<\/strong> project for <strong>compatibility<\/strong> with different versions of PHP.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\ncomposer require --dev phpcompatibility\/phpcompatibility-wp:&quot;*&quot;\n<\/pre><\/div>\n\n\n<p>If all went well by running the command below, you will see <code>PHPCompatibility<\/code> and <code>PHPCompatibilityWP<\/code> in available code styles<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nvendor\/bin\/phpcs -i\n<\/pre><\/div>\n\n\n<p>To make our parser check for <strong>compatibility with PHP<\/strong> versions, we add the following rules to <code>phpcs.xml<\/code> :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;!-- Check PHP version compatibility --&gt;\n&lt;rule ref=&quot;PHPCompatibilityWP&quot;\/&gt;\n&lt;!-- Check for cross-version support for PHP 7.2 and higher. --&gt;\n&lt;config name=&quot;testVersion&quot; value=&quot;7.2-&quot;\/&gt;\n<\/pre><\/div>\n\n\n<p>Our analyzed code will now be checked for compatibility with the minimum version of PHP 7.2. And this will allow us to check the code for deprecated or removed PHP functions as well as detect the use of new unsupported PHP features.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Other custom rules<\/h4>\n\n\n\n<p>For other custom rules, you can find information <a href=\"https:\/\/github.com\/squizlabs\/PHP_CodeSniffer\/wiki\/Customisable-Sniff-Properties\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">by the link<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ignoring rules in code<\/h2>\n\n\n\n<p>In addition to configuring the config, <strong>PHPCS<\/strong> has the ability to ignore the rules point-by-point in the code.<\/p>\n\n\n\n<p>You just need to add to the ignored line <code>\/\/ phpcs:ignore<\/code> .<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n$test = &quot;Hello World&quot;;\necho $test; \/\/phpcs:ignore\n<\/pre><\/div>\n\n\n<p>I recommend specifying the rule you ignore because ignoring all the rules <code>\/\/ phpcs:ignore<\/code>  you can miss a vulnerability in your code, which will be added afterward.<br><br>The following example demonstrates ignoring only concrete rule <code>WordPress.DB.SlowDBQuery.slow_db_query_meta_query<\/code><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\/\/......\n$duplicated_posts = new WP_Query(\n\t&#x5B;\n\t\t&#039;post_type&#039;  =&gt; &#039;any&#039;,\n\t\t&#039;meta_query&#039; =&gt; &#x5B; \/\/ phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query\n\t\t\t&#x5B;\n\t\t\t\t&#039;key&#039;   =&gt; META_DP_ORIGINAL,\n\t\t\t\t&#039;value&#039; =&gt; $post_id,\n\t\t\t],\n\t\t],\n\t]\n);\n<\/pre><\/div>\n\n\n<p>You can get the names of the rules that <strong>PHPCS<\/strong> complains about from the linter error log in a console.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to use PHPCS with GitHub Actions<\/h2>\n\n\n\n<p>Using <strong>PHPCS<\/strong> together in the <strong>GitHub Actions CI<\/strong> allows an automated code review before merging MR\/PR into the main branch. If an error is found, the <strong>GitHub Action<\/strong> Job terminates with a failure and reports it in the code review. Inside the Job itself, you are able to read the error logs.<br><br>Here is the code of the working action:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\nname: Workflow with PHPCS linter\nenv:\n  PHP_VER: &quot;8.2&quot;\n  COMPOSER_VER: &quot;2.5.1&quot;\non:\n  push:\n    branches: &#x5B; &quot;main&quot;, &quot;dev&quot; ]\n  pull_request:\n    types: &#x5B;synchronize, opened, reopened]\njobs:\n  php-ci:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\/checkout@v3\n      - name: Cache Composer dependencies\n        uses: actions\/cache@v3\n        with:\n          path: \/tmp\/composer-cache\n          key: ${{ runner.os }}-${{ hashFiles(&#039;**\/composer.lock&#039;) }}\n      - uses: php-actions\/composer@v6\n        with:\n          php_version: ${{ env.PHP_VER }}\n          version: ${{ env.COMPOSER_VER }}\n      - name: Get PHPCS Cache\n        id: phpcs-cache\n        run: |\n          echo &quot;file=.phpcs.cache&quot; &gt;&gt; $GITHUB_OUTPUT\n      - uses: actions\/cache@v3\n        with:\n          path: ${{ steps.phpcs-cache.outputs.file }}\n          key: ${{ runner.os }}-phpcs-${{ hashFiles(&#039;**\/.phpcs.cache&#039;) }}\n          restore-keys: |\n            ${{ runner.os }}-phpcs-\n      - name: Run PHPCS\n        run: composer run phpcs\n\n<\/pre><\/div>\n\n\n<p>What&#8217;s going on here?<\/p>\n\n\n\n<ul class=\"wp-block-list\" style=\"margin-top:0;margin-right:0;margin-bottom:0;margin-left:0\">\n<li>As with local env, we first need to get the code from git, for which <strong>GitHub Action<\/strong> uses the ready-made <code>actions\/checkout@v3<\/code> action.<\/li>\n\n\n\n<li>Then we need to install the composer dependencies, to do this in <strong>GitHub Action<\/strong> we use <code>php-actions\/composer@v6<\/code> action.<\/li>\n\n\n\n<li>When packages are installed, we move on to <code>Get PHPCS Cache<\/code> job in such we get <strong>PHPCS<\/strong> cache, to speed up our job.<\/li>\n\n\n\n<li>After the cache file is received, we can execute the <code>Run PHPCS<\/code> .<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/wp-yoda.com\/wp-content\/uploads\/2023\/04\/image-1-1024x573.png\" alt=\"WPCS in WordPress with Github Actions\" class=\"wp-image-210\"\/><\/figure>\n\n\n\n<p>In the picture, you can see the result of <strong>GitHub Action<\/strong> jobs. In the expanded item you can see the output of <strong>PHPCS<\/strong>.<br>You can see a real example of <strong>PHPCS<\/strong> with configured <strong>WPCS<\/strong> rules and <strong>Github Action<\/strong> <a href=\"https:\/\/github.com\/renakdup\/using-phpcs-for-wordpress\/actions\/runs\/4715246123\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">by the link<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Full source code<\/h2>\n\n\n\n<p>The full code of this article you can be found in the <a href=\"https:\/\/github.com\/renakdup\/using-phpcs-for-wordpress\/\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub repository<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The result<\/h2>\n\n\n\n<p>In this article we covered what <strong>PHPCS<\/strong> is and the differences between <strong>PHPCS<\/strong> and other static analyzers. We took a look at the <strong>WPCS<\/strong> standard and how you can set up your own code style. We wrote a simple <strong>GitHub Action CI<\/strong> to run <strong>PHPCS<\/strong>.<br><br>This <s>not-so-basic<\/s> information should be enough for you to use <strong>PHPCS<\/strong> with <strong>WPCS<\/strong> on a <strong>WordPress<\/strong> project and improve code quality while team development.<br>Don&#8217;t be shy to experiment and offer something new on your project.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article we&#8217;ll talk about what a PHPCS linter is, as well as look at the importance of using it on a team project, customizing it, integrating PHPCS with the WPCS coding standard, and using it in GitHub Actions.<\/p>\n","protected":false},"author":1,"featured_media":420,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[4,5,6,8,9,10],"class_list":["post-16","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-wordpress","tag-linter","tag-php_codesniffer","tag-phpcs","tag-wordpress","tag-wordpress-coding-standards","tag-wpcs"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Using PHPCS in WordPress with WPCS standard - WP Yoda<\/title>\n<meta name=\"description\" content=\"In this article we&#039;ll talk about what a PHPCS linter is, as well as look at the importance of using it on a team project, customizing it, integrating PHPCS with the WPCS coding standard, and using it in GitHub Actions.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using PHPCS in WordPress with WPCS standard - WP Yoda\" \/>\n<meta property=\"og:description\" content=\"In this article we&#039;ll talk about what a PHPCS linter is, as well as look at the importance of using it on a team project, customizing it, integrating PHPCS with the WPCS coding standard, and using it in GitHub Actions.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/\" \/>\n<meta property=\"og:site_name\" content=\"WP Yoda\" \/>\n<meta property=\"article:published_time\" content=\"2023-05-13T21:16:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-31T17:27:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wp-yoda.com\/en\/wp-content\/uploads\/sites\/2\/2023\/05\/Component-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1455\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/\"},\"author\":{\"name\":\"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439\",\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/#\\\/schema\\\/person\\\/195c797aee113d174e07e4887a9fe464\"},\"headline\":\"Using PHPCS in WordPress with WPCS standard\",\"datePublished\":\"2023-05-13T21:16:38+00:00\",\"dateModified\":\"2024-01-31T17:27:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/\"},\"wordCount\":2746,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/05\\\/Component-1.png\",\"keywords\":[\"linter\",\"PHP_CodeSniffer\",\"phpcs\",\"WordPress\",\"WordPress Coding Standards\",\"wpcs\"],\"articleSection\":[\"WordPress\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/\",\"url\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/\",\"name\":\"Using PHPCS in WordPress with WPCS standard - WP Yoda\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/05\\\/Component-1.png\",\"datePublished\":\"2023-05-13T21:16:38+00:00\",\"dateModified\":\"2024-01-31T17:27:19+00:00\",\"description\":\"In this article we'll talk about what a PHPCS linter is, as well as look at the importance of using it on a team project, customizing it, integrating PHPCS with the WPCS coding standard, and using it in GitHub Actions.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/#primaryimage\",\"url\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/05\\\/Component-1.png\",\"contentUrl\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/05\\\/Component-1.png\",\"width\":1455,\"height\":720,\"caption\":\"Using PHPCS in WordPress with the WPCS standard\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wordpress\\\/using-phpcs-linter-in-wordpress-with-wpcs-standard\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using PHPCS in WordPress with WPCS standard\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/\",\"name\":\"WP Yoda\",\"description\":\"Notes about PHP, WordPress and IT\",\"publisher\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/#organization\",\"name\":\"WP Yoda\",\"url\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/05\\\/Andrew_222_Master_Yoda__WordPress_plain_background_763a84a4-5042-4fac-9bdb-4562c05563e7.png\",\"contentUrl\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/05\\\/Andrew_222_Master_Yoda__WordPress_plain_background_763a84a4-5042-4fac-9bdb-4562c05563e7.png\",\"width\":1024,\"height\":1024,\"caption\":\"WP Yoda\"},\"image\":{\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/#\\\/schema\\\/person\\\/195c797aee113d174e07e4887a9fe464\",\"name\":\"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d3f11053e005f02e0dc3049c010b45034646963c7af8edac8076c3767022d750?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d3f11053e005f02e0dc3049c010b45034646963c7af8edac8076c3767022d750?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d3f11053e005f02e0dc3049c010b45034646963c7af8edac8076c3767022d750?s=96&r=g\",\"caption\":\"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439\"},\"sameAs\":[\"https:\\\/\\\/wp-yoda.com\"],\"url\":\"https:\\\/\\\/wp-yoda.com\\\/en\\\/author\\\/admin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using PHPCS in WordPress with WPCS standard - WP Yoda","description":"In this article we'll talk about what a PHPCS linter is, as well as look at the importance of using it on a team project, customizing it, integrating PHPCS with the WPCS coding standard, and using it in GitHub Actions.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/","og_locale":"en_US","og_type":"article","og_title":"Using PHPCS in WordPress with WPCS standard - WP Yoda","og_description":"In this article we'll talk about what a PHPCS linter is, as well as look at the importance of using it on a team project, customizing it, integrating PHPCS with the WPCS coding standard, and using it in GitHub Actions.","og_url":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/","og_site_name":"WP Yoda","article_published_time":"2023-05-13T21:16:38+00:00","article_modified_time":"2024-01-31T17:27:19+00:00","og_image":[{"width":1455,"height":720,"url":"https:\/\/wp-yoda.com\/en\/wp-content\/uploads\/sites\/2\/2023\/05\/Component-1.png","type":"image\/png"}],"author":"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439","twitter_card":"summary_large_image","twitter_misc":{"Written by":"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/#article","isPartOf":{"@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/"},"author":{"name":"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439","@id":"https:\/\/wp-yoda.com\/en\/#\/schema\/person\/195c797aee113d174e07e4887a9fe464"},"headline":"Using PHPCS in WordPress with WPCS standard","datePublished":"2023-05-13T21:16:38+00:00","dateModified":"2024-01-31T17:27:19+00:00","mainEntityOfPage":{"@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/"},"wordCount":2746,"commentCount":3,"publisher":{"@id":"https:\/\/wp-yoda.com\/en\/#organization"},"image":{"@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/#primaryimage"},"thumbnailUrl":"https:\/\/wp-yoda.com\/en\/wp-content\/uploads\/sites\/2\/2023\/05\/Component-1.png","keywords":["linter","PHP_CodeSniffer","phpcs","WordPress","WordPress Coding Standards","wpcs"],"articleSection":["WordPress"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/","url":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/","name":"Using PHPCS in WordPress with WPCS standard - WP Yoda","isPartOf":{"@id":"https:\/\/wp-yoda.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/#primaryimage"},"image":{"@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/#primaryimage"},"thumbnailUrl":"https:\/\/wp-yoda.com\/en\/wp-content\/uploads\/sites\/2\/2023\/05\/Component-1.png","datePublished":"2023-05-13T21:16:38+00:00","dateModified":"2024-01-31T17:27:19+00:00","description":"In this article we'll talk about what a PHPCS linter is, as well as look at the importance of using it on a team project, customizing it, integrating PHPCS with the WPCS coding standard, and using it in GitHub Actions.","breadcrumb":{"@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/#primaryimage","url":"https:\/\/wp-yoda.com\/en\/wp-content\/uploads\/sites\/2\/2023\/05\/Component-1.png","contentUrl":"https:\/\/wp-yoda.com\/en\/wp-content\/uploads\/sites\/2\/2023\/05\/Component-1.png","width":1455,"height":720,"caption":"Using PHPCS in WordPress with the WPCS standard"},{"@type":"BreadcrumbList","@id":"https:\/\/wp-yoda.com\/en\/wordpress\/using-phpcs-linter-in-wordpress-with-wpcs-standard\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wp-yoda.com\/en\/"},{"@type":"ListItem","position":2,"name":"Using PHPCS in WordPress with WPCS standard"}]},{"@type":"WebSite","@id":"https:\/\/wp-yoda.com\/en\/#website","url":"https:\/\/wp-yoda.com\/en\/","name":"WP Yoda","description":"Notes about PHP, WordPress and IT","publisher":{"@id":"https:\/\/wp-yoda.com\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wp-yoda.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/wp-yoda.com\/en\/#organization","name":"WP Yoda","url":"https:\/\/wp-yoda.com\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wp-yoda.com\/en\/#\/schema\/logo\/image\/","url":"https:\/\/wp-yoda.com\/en\/wp-content\/uploads\/sites\/2\/2023\/05\/Andrew_222_Master_Yoda__WordPress_plain_background_763a84a4-5042-4fac-9bdb-4562c05563e7.png","contentUrl":"https:\/\/wp-yoda.com\/en\/wp-content\/uploads\/sites\/2\/2023\/05\/Andrew_222_Master_Yoda__WordPress_plain_background_763a84a4-5042-4fac-9bdb-4562c05563e7.png","width":1024,"height":1024,"caption":"WP Yoda"},"image":{"@id":"https:\/\/wp-yoda.com\/en\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/wp-yoda.com\/en\/#\/schema\/person\/195c797aee113d174e07e4887a9fe464","name":"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d3f11053e005f02e0dc3049c010b45034646963c7af8edac8076c3767022d750?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/d3f11053e005f02e0dc3049c010b45034646963c7af8edac8076c3767022d750?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d3f11053e005f02e0dc3049c010b45034646963c7af8edac8076c3767022d750?s=96&r=g","caption":"\u0410\u043d\u0434\u0440\u0435\u0439 \u041f\u0438\u0441\u0430\u0440\u0435\u0432\u0441\u043a\u0438\u0439"},"sameAs":["https:\/\/wp-yoda.com"],"url":"https:\/\/wp-yoda.com\/en\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/posts\/16","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/comments?post=16"}],"version-history":[{"count":0,"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/posts\/16\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/media\/420"}],"wp:attachment":[{"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/media?parent=16"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/categories?post=16"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wp-yoda.com\/en\/wp-json\/wp\/v2\/tags?post=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}