resolved conflicts

This commit is contained in:
2025-03-31 03:46:05 +03:00
6454 changed files with 1520539 additions and 9 deletions
@@ -0,0 +1,107 @@
<documentation title="Array Indent">
<standard>
<![CDATA[
The opening brace of a multi-line array must be indented at least to the same level as the start of the statement.
]]>
</standard>
<code_comparison>
<code title="Valid: Opening brace of a multi-line array indented to the same level as the start of the statement.">
<![CDATA[
$b = <em>[</em>
1,
2,
];
if ($condition) {
$a =
<em> [</em>
1,
2,
];
}
]]>
</code>
<code title="Invalid: Opening brace of a multi-line array not indented to the same level as the start of the statement.">
<![CDATA[
if ($condition) {
$a =
<em>[</em>
1,
2,
];
}
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
Each array element must be indented exactly four spaces from the start of the statement.
]]>
</standard>
<code_comparison>
<code title="Valid: Each array element is indented by exactly four spaces.">
<![CDATA[
$a = array(
<em> </em>1,
<em> </em>2,
<em> </em>3,
);
]]>
</code>
<code title="Invalid: Array elements not indented by four spaces.">
<![CDATA[
$a = array(
<em> </em>1,
<em> </em>2,
<em> </em>3,
);
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
The array closing brace must be on a new line.
]]>
</standard>
<code_comparison>
<code title="Valid: Array closing brace on its own line.">
<![CDATA[
$a = [
1,
2,<em>
]</em>;
]]>
</code>
<code title="Invalid: Array closing brace not on its own line.">
<![CDATA[
$a = [
1,
2,<em>]</em>;
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
The closing brace must be aligned with the start of the statement containing the array opener.
]]>
</standard>
<code_comparison>
<code title="Valid: Closing brace aligned with the start of the statement containing the array opener.">
<![CDATA[
$a = array(
1,
2,
<em>)</em>;
]]>
</code>
<code title="Invalid: Closing brace not aligned with the start of the statement containing the array opener.">
<![CDATA[
$a = array(
1,
2,
<em> )</em>;
]]>
</code>
</code_comparison>
</documentation>
@@ -0,0 +1,269 @@
<documentation title="Doc Comment">
<standard>
<![CDATA[
Enforces rules related to the formatting of DocBlocks ("Doc Comments") in PHP code.
DocBlocks are a special type of comment that can provide information about a structural element. In the context of DocBlocks, the following are considered structural elements:
class, interface, trait, enum, function, property, constant, variable declarations and require/include[_once] statements.
DocBlocks start with a `/**` marker and end on `*/`. This sniff will check the formatting of all DocBlocks, independently of whether or not they are attached to a structural element.
]]>
</standard>
<standard>
<![CDATA[
A DocBlock must not be empty.
]]>
</standard>
<code_comparison>
<code title="Valid: DocBlock with some content.">
<![CDATA[
/**
* <em>Some content.</em>
*/
]]>
</code>
<code title="Invalid: Empty DocBlock.">
<![CDATA[
/**
* <em></em>
*/
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
The opening and closing DocBlock tags must be the only content on the line.
]]>
</standard>
<code_comparison>
<code title="Valid: The opening and closing DocBlock tags have to be on a line by themselves.">
<![CDATA[
<em>/**</em>
* Short description.
<em>*/</em>
]]>
</code>
<code title="Invalid: The opening and closing DocBlock tags are not on a line by themselves.">
<![CDATA[
<em>/** Short description. */</em>
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
The DocBlock must have a short description, and it must be on the first line.
]]>
</standard>
<code_comparison>
<code title="Valid: DocBlock with a short description on the first line.">
<![CDATA[
/**
* <em>Short description.</em>
*/
]]>
</code>
<code title="Invalid: DocBlock without a short description or short description not on the first line.">
<![CDATA[
/**
* <em></em>@return int
*/
/**
<em> *</em>
* Short description.
*/
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
Both the short description, as well as the long description, must start with a capital letter.
]]>
</standard>
<code_comparison>
<code title="Valid: Both the short and long description start with a capital letter.">
<![CDATA[
/**
* <em>S</em>hort description.
*
* <em>L</em>ong description.
*/
]]>
</code>
<code title="Invalid: Neither short nor long description starts with a capital letter.">
<![CDATA[
/**
* <em>s</em>hort description.
*
* <em>l</em>ong description.
*/
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
There must be exactly one blank line separating the short description, the long description and tag groups.
]]>
</standard>
<code_comparison>
<code title="Valid: One blank line separating the short description, the long description and tag groups.">
<![CDATA[
/**
* Short description.
<em> *<em>
* Long description.
<em> *</em>
* @param int $foo
*/
]]>
</code>
<code title="Invalid: More than one or no blank line separating the short description, the long description and tag groups.">
<![CDATA[
/**
* Short description.
<em> *
*
</em>
* Long description.<em>
</em> * @param int $foo
*/
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
Parameter tags must be grouped together.
]]>
</standard>
<code_comparison>
<code title="Valid: Parameter tags grouped together.">
<![CDATA[
/**
* Short description.
*
<em> * @param int $foo
* @param string $bar</em>
*/
]]>
</code>
<code title="Invalid: Parameter tags not grouped together.">
<![CDATA[
/**
* Short description.
*
* @param int $foo
<em> *</em>
* @param string $bar
*/
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
Parameter tags must not be grouped together with other tags.
]]>
</standard>
<code_comparison>
<code title="Valid: Parameter tags are not grouped together with other tags.">
<![CDATA[
/**
* Short description.
*
<em> * @param int $foo</em>
*
* @since 3.4.8
* @deprecated 6.0.0
*/
]]>
</code>
<code title="Invalid: Parameter tags grouped together with other tags.">
<![CDATA[
/**
* Short description.
*
<em> * @param int $foo
* @since 3.4.8
* @deprecated 6.0.0</em>
*/
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
Tag values for different tags in the same group must be aligned with each other.
]]>
</standard>
<code_comparison>
<code title="Valid: Tag values for different tags in the same tag group are aligned with each other.">
<![CDATA[
/**
* Short description.
*
* @since<em> 0.5.0</em>
* @deprecated<em> 1.0.0</em>
*/
]]>
</code>
<code title="Invalid: Tag values for different tags in the same tag group are not aligned with each other.">
<![CDATA[
/**
* Short description.
*
* @since<em> 0.5.0</em>
* @deprecated<em> 1.0.0</em>
*/
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
Parameter tags must be defined before other tags in a DocBlock.
]]>
</standard>
<code_comparison>
<code title="Valid: Parameter tags are defined first.">
<![CDATA[
/**
* Short description.
*
* <em>@param string $foo</em>
*
* @return void
*/
]]>
</code>
<code title="Invalid: Parameter tags are not defined first.">
<![CDATA[
/**
* Short description.
*
* @return void
*
* <em>@param string $bar</em>
*/
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
There must be no additional blank (comment) lines before the closing DocBlock tag.
]]>
</standard>
<code_comparison>
<code title="Valid: No additional blank lines before the closing DocBlock tag.">
<![CDATA[
/**
* Short description.<em>
</em> */
]]>
</code>
<code title="Invalid: Additional blank lines before the closing DocBlock tag.">
<![CDATA[
/**
* Short description.
<em> *</em>
*/
]]>
</code>
</code_comparison>
</documentation>
@@ -0,0 +1,38 @@
<documentation title="Require Strict Types">
<standard>
<![CDATA[
The strict_types declaration must be present.
]]>
</standard>
<code_comparison>
<code title="Valid: `strict_types` declaration is present.">
<![CDATA[
declare(<em>strict_types=1</em>);
declare(encoding='UTF-8', <em>strict_types=0</em>);
]]>
</code>
<code title="Invalid: Missing `strict_types` declaration.">
<![CDATA[
declare(encoding='ISO-8859-1'<em></em>);
]]>
</code>
</code_comparison>
<standard>
<![CDATA[
The strict_types declaration must be enabled.
]]>
</standard>
<code_comparison>
<code title="Valid: `strict_types` declaration is enabled.">
<![CDATA[
declare(strict_types=<em>1</em>);
]]>
</code>
<code title="Invalid: `strict_types` declaration is disabled.">
<![CDATA[
declare(strict_types=<em>0</em>);
]]>
</code>
</code_comparison>
</documentation>
@@ -0,0 +1,39 @@
<documentation title="Unnecessary Heredoc">
<standard>
<![CDATA[
If no interpolation or expressions are used in the body of a heredoc, nowdoc syntax should be used instead.
]]>
</standard>
<code_comparison>
<code title="Valid: Using nowdoc syntax for a text string without any interpolation or expressions.">
<![CDATA[
$nowdoc = <em><<<'EOD'</em>
some text
EOD;
]]>
</code>
<code title="Invalid: Using heredoc syntax for a text string without any interpolation or expressions.">
<![CDATA[
$heredoc = <em><<<EOD</em>
some text
EOD;
]]>
</code>
</code_comparison>
<code_comparison>
<code title="Valid: Using heredoc syntax for a text string containing interpolation or expressions.">
<![CDATA[
$heredoc = <em><<<"EOD"</em>
some $text
EOD;
]]>
</code>
<code title="Invalid: Using heredoc syntax for a text string without any interpolation or expressions.">
<![CDATA[
$heredoc = <em><<<"EOD"</em>
some text
EOD;
]]>
</code>
</code_comparison>
</documentation>
@@ -0,0 +1,23 @@
<documentation title="Heredoc Nowdoc Identifier Spacing">
<standard>
<![CDATA[
There should be no space between the <<< and the heredoc/nowdoc identifier string.
]]>
</standard>
<code_comparison>
<code title="Valid: No space between the &lt;&lt;&lt; and the identifier string.">
<![CDATA[
$heredoc = <em><<<EOD</em>
some text
EOD;
]]>
</code>
<code title="Invalid: Whitespace between the &lt;&lt;&lt; and the identifier string.">
<![CDATA[
$heredoc = <em><<< END</em>
some text
END;
]]>
</code>
</code_comparison>
</documentation>
@@ -0,0 +1,97 @@
<?php
/**
* Prefer the use of nowdoc over heredoc.
*
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
* @copyright 2024 PHPCSStandards and contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Standards\Generic\Sniffs\Strings;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class UnnecessaryHeredocSniff implements Sniff
{
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array<int|string>
*/
public function register()
{
return [T_START_HEREDOC];
}//end register()
/**
* Processes this test, when one of its tokens is encountered.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token in
* the stack passed in $tokens.
*
* @return void
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
if (isset($tokens[$stackPtr]['scope_closer']) === false) {
// Just to be safe. Shouldn't be possible as in that case, the opener shouldn't be tokenized
// to T_START_HEREDOC by PHP.
return; // @codeCoverageIgnore
}
$closer = $tokens[$stackPtr]['scope_closer'];
$body = '';
// Collect all the tokens within the heredoc body.
for ($i = ($stackPtr + 1); $i < $closer; $i++) {
$body .= $tokens[$i]['content'];
}
$tokenizedBody = token_get_all(sprintf("<?php <<<EOD\n%s\nEOD;\n?>", $body));
foreach ($tokenizedBody as $ptr => $bodyToken) {
if (is_array($bodyToken) === false) {
continue;
}
if ($bodyToken[0] === T_DOLLAR_OPEN_CURLY_BRACES
|| $bodyToken[0] === T_VARIABLE
) {
// Contains interpolation or expression.
$phpcsFile->recordMetric($stackPtr, 'Heredoc contains interpolation or expression', 'yes');
return;
}
if ($bodyToken[0] === T_CURLY_OPEN
&& is_array($tokenizedBody[($ptr + 1)]) === false
&& $tokenizedBody[($ptr + 1)] === '$'
) {
// Contains interpolation or expression.
$phpcsFile->recordMetric($stackPtr, 'Heredoc contains interpolation or expression', 'yes');
return;
}
}//end foreach
$phpcsFile->recordMetric($stackPtr, 'Heredoc contains interpolation or expression', 'no');
$warning = 'Detected heredoc without interpolation or expressions. Use nowdoc syntax instead';
$fix = $phpcsFile->addFixableWarning($warning, $stackPtr, 'Found');
if ($fix === true) {
$identifier = trim(ltrim($tokens[$stackPtr]['content'], '<'));
$replaceWith = "'".trim($identifier, '"')."'";
$replacement = str_replace($identifier, $replaceWith, $tokens[$stackPtr]['content']);
$phpcsFile->fixer->replaceToken($stackPtr, $replacement);
}
}//end process()
}//end class
@@ -0,0 +1,69 @@
<?php
/**
* Ensures heredoc/nowdoc identifiers do not have any whitespace before them.
*
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
* @copyright 2024 PHPCSStandards and contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Standards\Generic\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class HereNowdocIdentifierSpacingSniff implements Sniff
{
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array<int|string>
*/
public function register()
{
return [
T_START_HEREDOC,
T_START_NOWDOC,
];
}//end register()
/**
* Processes this test, when one of its tokens is encountered.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token in
* the stack passed in $tokens.
*
* @return void
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
if (strpos($tokens[$stackPtr]['content'], ' ') === false
&& strpos($tokens[$stackPtr]['content'], "\t") === false
) {
// Nothing to do.
$phpcsFile->recordMetric($stackPtr, 'Heredoc/nowdoc identifier', 'no space between <<< and ID');
return;
}
$phpcsFile->recordMetric($stackPtr, 'Heredoc/nowdoc identifier', 'space between <<< and ID');
$error = 'There should be no space between the <<< and the heredoc/nowdoc identifier string';
$data = [$tokens[$stackPtr]['content']];
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceFound', $data);
if ($fix === true) {
$replacement = str_replace([' ', "\t"], '', $tokens[$stackPtr]['content']);
$phpcsFile->fixer->replaceToken($stackPtr, $replacement);
}
}//end process()
}//end class
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (long array syntax missing parentheses).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
$var = array
@@ -0,0 +1,6 @@
<?php
namespace Code\IsNamespaced ?>
<?php
class MyClass {}
interface MyInterface {}
@@ -0,0 +1,13 @@
<?php
namespace Code\IsNamespaced;
class FooBar {}
namespace Code\AnotherNamespace;
namespace Code\IsNamespaced ?>
<?php
echo '123';
?>
<?php
class FooBar {}
@@ -0,0 +1,13 @@
<?php
namespace E;
namespace\functionCall();
class MyClass {}
interface YourInterface {}
namespace F;
namespace\functionCall();
class MyClass {}
namespace /*comment*/ G;
namespace\functionCall();
class MyClass {}
@@ -0,0 +1,8 @@
<?php
namespace Foo\Bar;
class MyClass {}
interface YourInterface {}
namespace Foo /*comment*/ \ /*comment*/ Bar;
class MyClass {}
interface YourInterface {}
@@ -0,0 +1,5 @@
<?php
namespace {
class MyClass {}
trait YourTrait {}
}
@@ -0,0 +1,8 @@
<?php
// Intentional parse error/live coding.
// This should be the only test in this file.
// This is a two-file test: test case file 97 and 98 belong together.
// Testing against false positives during live coding and invalid class names being stored in the cache.
class
@@ -0,0 +1,8 @@
<?php
// Intentional parse error/live coding.
// This should be the only test in this file.
// This is a two-file test: test case file 97 and 98 belong together.
// Testing against false positives during live coding and invalid class names being stored in the cache.
class
@@ -0,0 +1,7 @@
<?php
// Intentional parse error/live coding.
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
namespace
@@ -0,0 +1,86 @@
<?php
/*
* Test empty statement: two consecutive semicolons without executable code between them.
*/
function_call(); // OK.
// The below examples are all bad.
function_call();;
function_call();
;
function_call();
/* some comment */;
function_call();
/* some comment */ ;
?>
<input name="<?php ; something_else(); ?>" />
<input name="<?php something_else(); ; ; ?>" />
/*
* Test empty statement: no code between PHP open and close tag.
*/
<input name="<?php something_else() ?>" /> <!-- OK. -->
<input name="<?php something_else(); ?>" /> <!-- OK. -->
<input name="<?php /* comment */ ?>" /> <!-- OK. -->
<input name="<?php ?>" /> <!-- Bad. -->
<input name="<?php
?>" /> <!-- Bad. -->
<!--
/*
* Test detecting & fixing a combination of the two above checks.
*/
-->
<?php ; ?>
<input name="<?php ;; ?>" /> <!-- Bad. -->
<!-- Tests with short open echo tag. -->
<input name="<?= 'some text' ?>" /> <!-- OK. -->
<input name="<?= ?>" /> <!-- Bad. -->
<input name="<?= ; ?>" /> <!-- Bad. -->
<?php
// Guard against false positives for two consecutive semicolons in a for statement.
for ( $i = 0; ; $i++ ) {}
// Test for useless semicolons.
for ( $i = 0; ; $i++ ) {};
if (true) {};
while (true) {};
class ABC {} ; ;
switch ( $a ) {
case 1:
break;
case 2:
break;
default:
break; ;
};
// Do not break closures and anonymous classes and curlies without scope owners.
$a = function () {};
$b = new class {};
echo $a{0};
if ($foo) {
;
}
// Do not remove semicolon after match.
$c = match ($a) {
1 => true,
};
@@ -0,0 +1,80 @@
<?php
/*
* Test empty statement: two consecutive semicolons without executable code between them.
*/
function_call(); // OK.
// The below examples are all bad.
function_call();
function_call();
function_call();
/* some comment */
function_call();
/* some comment */
?>
<input name="<?php something_else(); ?>" />
<input name="<?php something_else(); ?>" />
/*
* Test empty statement: no code between PHP open and close tag.
*/
<input name="<?php something_else() ?>" /> <!-- OK. -->
<input name="<?php something_else(); ?>" /> <!-- OK. -->
<input name="<?php /* comment */ ?>" /> <!-- OK. -->
<input name="" /> <!-- Bad. -->
<input name="" /> <!-- Bad. -->
<!--
/*
* Test detecting & fixing a combination of the two above checks.
*/
-->
<input name="" /> <!-- Bad. -->
<!-- Tests with short open echo tag. -->
<input name="<?= 'some text' ?>" /> <!-- OK. -->
<input name="" /> <!-- Bad. -->
<input name="" /> <!-- Bad. -->
<?php
// Guard against false positives for two consecutive semicolons in a for statement.
for ( $i = 0; ; $i++ ) {}
// Test for useless semicolons.
for ( $i = 0; ; $i++ ) {}
if (true) {}
while (true) {}
class ABC {}
switch ( $a ) {
case 1:
break;
case 2:
break;
default:
break;
}
// Do not break closures and anonymous classes and curlies without scope owners.
$a = function () {};
$b = new class {};
echo $a{0};
if ($foo) {
}
// Do not remove semicolon after match.
$c = match ($a) {
1 => true,
};
@@ -0,0 +1,27 @@
<!-- Tests with short open tag. -->
<input name="<? ; something_else(); ?>" />
<input name="<? something_else(); ; ?>" />
/*
* Test empty statement: no code between PHP open and close tag.
*/
<input name="<? something_else() ?>" /> <!-- OK. -->
<input name="<? something_else(); ?>" /> <!-- OK. -->
<input name="<? /* comment */ ?>" /> <!-- OK. -->
<input name="<? ?>" /> <!-- Bad. -->
<input name="<?
?>" /> <!-- Bad. -->
<!--
/*
* Test detecting & fixing a combination of the two checks.
*/
-->
<? ; ?>
<input name="<? ; ?>" /> <!-- Bad. -->
@@ -0,0 +1,23 @@
<!-- Tests with short open tag. -->
<input name="<?something_else(); ?>" />
<input name="<? something_else(); ?>" />
/*
* Test empty statement: no code between PHP open and close tag.
*/
<input name="<? something_else() ?>" /> <!-- OK. -->
<input name="<? something_else(); ?>" /> <!-- OK. -->
<input name="<? /* comment */ ?>" /> <!-- OK. -->
<input name="" /> <!-- Bad. -->
<input name="" /> <!-- Bad. -->
<!--
/*
* Test detecting & fixing a combination of the two checks.
*/
-->
<input name="" /> <!-- Bad. -->
@@ -0,0 +1,89 @@
<?php
for ($same = 0; $same < 20; $same++) {
for ($j = 0; $j < 5; $same += 2) {
for ($k = 0; $k > 3; $same++) {
}
}
}
for ($i = 0; $i < 20; $i++) {
for ($j = 0; $j < 5; $j += 2) {
for ($k = 0; $k > 3; $k++) {
}
}
}
for ($i = 0; $i < 20; $i++) {
for ($same = 0; $same < 5; $same += 2) {
for ($k = 0; $k > 3; $same++) {
}
}
}
for (; $i < 10; $i++) {
for ($j = 0;; $j++) {
if ($j > 5) {
break;
}
for (;; $k++) {
if ($k > 5) {
break;
}
}
}
}
for (; $same < 10; $same++) {
for ($j = 0;; $same++) {
if ($j > 5) {
break;
}
for (;; $same++) {
if ($k > 5) {
break;
}
}
}
}
for ($i = 0; $i < 20; $i++) :
for ($j = 0; $j < 5; $j += 2) :
endfor;
endfor;
for ($same = 0; $same < 20; $same++) :
for ($j = 0; $j < 5; $same += 2) :
endfor;
endfor;
// Sniff bails early when there is no incrementor in the third expression of the outer for loop.
for ($same = 0; $same < 10;) {
++$same;
for ($j = 0; $j < 5; $same++) {}
}
for ($i = 1, $same = 0; $i <= 10; $i++, $same++) {
for ($same = 0, $k = 0; $k < 5; $same++, $k++) {}
}
for ($i = 20; $i > 0; $i--) {
for ($j = 5; $j > 0; $j -= 2) {
for ($k = 3; $k > 0; $k--) {}
}
}
for ($same = 20; $same > 0; $same--) {
for ($j = 5; $j > 0; $same -= 2) {
for ($k = 3; $k > 0; $same--) {}
}
}
for ($i = 0; $i < 20; $i++);
for ($same = 0; $same < 20; $same++) {
for ($j = 0; $j < 20; $same++);
}
@@ -0,0 +1,8 @@
<?php
// Intentional parse error (inner for loop missing closing parenthesis).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
for ($i = 0; $i < 20; $i++) {
for ($i = 0; $i < 20; $i++
}
@@ -0,0 +1,6 @@
<?php
// Intentional parse error (missing for conditions).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
for
@@ -0,0 +1,8 @@
<?php
// Intentional parse error (inner for loop missing opening parenthesis).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
for ($i = 0; $i < 20; $i++) {
for
}
@@ -0,0 +1,13 @@
<?php
if (true) {
} else if (false) {
} elseif (true) {
}
if (file_exists(__FILE__) === true) {
}
@@ -0,0 +1,4 @@
<?php
// Intentional parse error. Live coding resilience.
if(true
@@ -0,0 +1,173 @@
<?php
class FooBar {
public function __construct($a, $b) {
parent::__construct($a, $b);
}
}
class BarFoo {
public function __construct($a, $b) {
parent::__construct($a, 'XML', $b);
}
}
class Foo {
public function export($a, $b = null) {
return parent::export($a, $b);
}
}
class Bar {
public function export($a, $b = null) {
return parent::export($a);
}
public function ignoreNoParent($a, $b) {
return $a + $b;
}
public function differentParentMethod($a, $b) {
return parent::anotherMethod($a, $b);
}
public function methodCallWithExpression($a, $b) {
return parent::methodCallWithExpression(($a + $b), ($b));
}
public function uselessMethodCallWithExpression($a, $b) {
return parent::uselessMethodCallWithExpression(($a), ($b));
}
public function contentAfterCallingParent() {
parent::contentAfterCallingParent();
return 1;
}
public function ignoreNoParentVoidMethod($a, $b) {
$c = $a + $b;
}
public function modifiesParentReturnValue($a, $b) {
return parent::modifiesParentReturnValue($a, $b) + $b;
}
public function uselessMethodCallTrailingComma($a) {
return parent::uselessMethodCallTrailingComma($a,);
}
public function differentParameterOrder($a, $b) {
return parent::differentParameterOrder($b, $a);
}
public function sameNumberDifferentParameters($a, $b) {
return parent::sameNumberDifferentParameters($this->prop[$a], $this->{$b});
}
public function differentCase() {
return parent::DIFFERENTcase();
}
public function differentCaseSameNonAnsiiCharáctêrs() {
// This should be flagged, only ASCII chars have changed case.
return parent::DIFFERENTcaseSameNonAnsiiCharáctêrs();
}
public function differentCaseDifferentNonAnsiiCharáctêrs() {
// This should not be flagged as non-ASCII chars have changed case, making this a different method name.
return parent::DIFFERENTcaseDifferentNonAnsiiCharÁctÊrs();
}
public function nestedFunctionShouldBailEarly() {
function nestedFunctionShouldBailEarly() {
// Invalid code needed to ensure an error is NOT triggered and the sniff bails early when handling nested function.
parent::nestedFunctionShouldBailEarly();
}
}
}
abstract class AbstractFoo {
abstract public function sniffShouldBailEarly();
public function uselessMethodInAbstractClass() {
parent::uselessMethodInAbstractClass();
}
public function usefulMethodInAbstractClass() {
$a = 1;
parent::usefulMethodInAbstractClass($a);
}
}
interface InterfaceFoo {
public function sniffShouldBailEarly();
}
trait TraitFoo {
abstract public function sniffShouldBailEarly();
public function usefulMethodInTrait() {
parent::usefulMethodInTrait();
return 1;
}
public function uselessMethodInTrait() {
return parent::uselessMethodInTrait();
}
}
enum EnumFoo {
public function sniffShouldBailEarly() {
// Invalid code needed to ensure an error is NOT triggered and the sniff bails early when handling an enum method.
parent::sniffShouldBailEarly();
}
}
function shouldBailEarly() {
// Invalid code needed to ensure an error is NOT triggered and the sniff bails early when handling a regular function.
parent::shouldBailEarly();
}
$anon = new class extends ParentClass {
public function uselessOverridingMethod() {
parent::uselessOverridingMethod();
}
public function usefulOverridingMethod() {
$a = 10;
parent::usefulOverridingMethod($a);
}
};
function foo() {
$anon = new class extends ParentClass {
public function uselessOverridingMethod() {
parent::uselessOverridingMethod();
}
};
}
class SniffShouldHandlePHPOpenCloseTagsCorrectly {
public function thisIsStillAUselessOverride($a, $b) {
return parent::thisIsStillAUselessOverride($a, $b) ?><?php
// Even with a comment here.
}
public function butNotWithANewLineBetweenThePHPTagsAsThenWeEchoOutTheNewLine($a, $b) {
parent::butNotWithANewLineBetweenThePHPTagsAsThenWeEchoOutTheNewLine($a, $b) ?>
<?php
}
public function embeddedHTMLAfterCallingParent() {
parent::embeddedHTMLAfterCallingParent() ?>
<div>HTML</div>
<?php
}
public function contentAfterUselessEmbedBlock() {
parent::contentAfterUselessEmbedBlock() ?><?php
return 1;
}
}
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing opening bracket). Testing that the sniff is *not* triggered
// in this case.
class FooBar {
public function __construct()
@@ -0,0 +1,10 @@
<?php
// Intentional parse error (missing double colon after parent keyword). Testing that the sniff is *not* triggered
// in this case.
class FooBar {
public function __construct() {
parent
}
}
@@ -0,0 +1,10 @@
<?php
// Intentional parse error (missing parent method opening parenthesis).
// Testing that the sniff is *not* triggered in this case.
class FooBar {
public function __construct() {
parent::__construct
}
}
@@ -0,0 +1,10 @@
<?php
// Intentional parse error (missing semicolon).
// Testing that the sniff is *not* triggered in this case.
class FooBar {
public function __construct() {
parent::__construct()
}
}
@@ -0,0 +1,10 @@
<?php
// Intentional parse error (missing closing parenthesis in parent method call).
// Testing that the sniff is *not* triggered in this case.
class FooBar {
public function __construct() {
parent::__construct(
}
}
@@ -0,0 +1,35 @@
if (something) print 'hello';
if (something) {
print 'hello';
} else print 'hi';
if (something) {
print 'hello';
} else if (something) print 'hi';
for (i; i > 0; i--) print 'hello';
while (something) print 'hello';
do {
i--;
} while (something);
do i++; while (i < 5);
SomeClass.prototype.switch = function() {
// do something
};
if ($("#myid").rotationDegrees()=='90')
$('.modal').css({'transform': 'rotate(90deg)'});
if ($("#myid").rotationDegrees()=='90')
$foo = {'transform': 'rotate(90deg)'};
if (something) {
alert('hello');
} else /* comment */ if (somethingElse) alert('hi');
@@ -0,0 +1,44 @@
if (something) { print 'hello';
}
if (something) {
print 'hello';
} else { print 'hi';
}
if (something) {
print 'hello';
} else if (something) { print 'hi';
}
for (i; i > 0; i--) { print 'hello';
}
while (something) { print 'hello';
}
do {
i--;
} while (something);
do { i++;
} while (i < 5);
SomeClass.prototype.switch = function() {
// do something
};
if ($("#myid").rotationDegrees()=='90') {
$('.modal').css({'transform': 'rotate(90deg)'});
}
if ($("#myid").rotationDegrees()=='90') {
$foo = {'transform': 'rotate(90deg)'};
}
if (something) {
alert('hello');
} else /* comment */ if (somethingElse) { alert('hi');
}
@@ -0,0 +1,5 @@
// Intentional parse error (missing closing parenthesis).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
do i++; while (i < 5
@@ -0,0 +1,5 @@
// Intentional parse error (missing opening parenthesis).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
do i++; while
@@ -0,0 +1,100 @@
<?php
$var = (int) $var2;
$var = (int)$var2;
$var = (int) $var2;
$var = (integer) $var2;
$var = (integer)$var2;
$var = (integer) $var2;
$var = (string) $var2;
$var = (string)$var2;
$var = (string) $var2;
$var = (float) $var2;
$var = (float)$var2;
$var = (float) $var2;
$var = (double) $var2;
$var = (double)$var2;
$var = (double) $var2;
$var = (real) $var2;
$var = (real)$var2;
$var = (real) $var2;
$var = (array) $var2;
$var = (array)$var2;
$var = (array) $var2;
$var = (bool) $var2;
$var = (bool)$var2;
$var = (bool) $var2;
$var = (boolean) $var2;
$var = (boolean)$var2;
$var = (boolean) $var2;
$var = (object) $var2;
$var = (object)$var2;
$var = (object) $var2;
$var = (unset) $var2;
$var = (unset)$var2;
$var = (unset) $var2;
$var = b"binary $foo";
$var = b"binary string";
$var = b'binary string';
$var = (binary) $string;
$var = (binary)$string;
$var = (boolean) /* comment */ $var2;
$var = (int)
$var2;
if ( (string) // phpcs:ignore Standard.Cat.SniffName -- for reasons.
$x === 'test'
) {}
// phpcs:set Generic.Formatting.SpaceAfterCast ignoreNewlines true
$var = (int)
$var1 + (bool) $var2;
if ( (string) // phpcs:ignore Standard.Cat.SniffName -- for reasons.
$x === 'test'
) {}
// phpcs:set Generic.Formatting.SpaceAfterCast ignoreNewlines false
// phpcs:set Generic.Formatting.SpaceAfterCast spacing 2
$var = (int) $var2;
$var = (string)$var2;
$var = (array) $var2;
$var = (unset) $var2;
$var = (boolean) /* comment */ $var2;
$var = (integer)
$var2;
// phpcs:set Generic.Formatting.SpaceAfterCast spacing 0
$var = (int) $var2;
$var = (string)$var2;
$var = (array) $var2;
$var = (unset) $var2;
$var = (boolean) /* comment */ $var2;
$var = (integer)
$var2;
// phpcs:set Generic.Formatting.SpaceAfterCast ignoreNewlines true
$var = (int)
$var1 + (bool) $var2;
// phpcs:set Generic.Formatting.SpaceAfterCast ignoreNewlines false
// phpcs:set Generic.Formatting.SpaceAfterCast spacing 1
$var = (boolean)/* comment */ $var2;
$var = ( int )$spacesInsideParenthesis;
$var = ( int )$tabsInsideParenthesis;
@@ -0,0 +1,97 @@
<?php
$var = (int) $var2;
$var = (int) $var2;
$var = (int) $var2;
$var = (integer) $var2;
$var = (integer) $var2;
$var = (integer) $var2;
$var = (string) $var2;
$var = (string) $var2;
$var = (string) $var2;
$var = (float) $var2;
$var = (float) $var2;
$var = (float) $var2;
$var = (double) $var2;
$var = (double) $var2;
$var = (double) $var2;
$var = (real) $var2;
$var = (real) $var2;
$var = (real) $var2;
$var = (array) $var2;
$var = (array) $var2;
$var = (array) $var2;
$var = (bool) $var2;
$var = (bool) $var2;
$var = (bool) $var2;
$var = (boolean) $var2;
$var = (boolean) $var2;
$var = (boolean) $var2;
$var = (object) $var2;
$var = (object) $var2;
$var = (object) $var2;
$var = (unset) $var2;
$var = (unset) $var2;
$var = (unset) $var2;
$var = b"binary $foo";
$var = b"binary string";
$var = b'binary string';
$var = (binary) $string;
$var = (binary) $string;
$var = (boolean) /* comment */ $var2;
$var = (int) $var2;
if ( (string) // phpcs:ignore Standard.Cat.SniffName -- for reasons.
$x === 'test'
) {}
// phpcs:set Generic.Formatting.SpaceAfterCast ignoreNewlines true
$var = (int)
$var1 + (bool) $var2;
if ( (string) // phpcs:ignore Standard.Cat.SniffName -- for reasons.
$x === 'test'
) {}
// phpcs:set Generic.Formatting.SpaceAfterCast ignoreNewlines false
// phpcs:set Generic.Formatting.SpaceAfterCast spacing 2
$var = (int) $var2;
$var = (string) $var2;
$var = (array) $var2;
$var = (unset) $var2;
$var = (boolean) /* comment */ $var2;
$var = (integer) $var2;
// phpcs:set Generic.Formatting.SpaceAfterCast spacing 0
$var = (int)$var2;
$var = (string)$var2;
$var = (array)$var2;
$var = (unset)$var2;
$var = (boolean) /* comment */ $var2;
$var = (integer)$var2;
// phpcs:set Generic.Formatting.SpaceAfterCast ignoreNewlines true
$var = (int)
$var1 + (bool)$var2;
// phpcs:set Generic.Formatting.SpaceAfterCast ignoreNewlines false
// phpcs:set Generic.Formatting.SpaceAfterCast spacing 1
$var = (boolean)/* comment */ $var2;
$var = ( int ) $spacesInsideParenthesis;
$var = ( int ) $tabsInsideParenthesis;
@@ -0,0 +1,86 @@
<?php
if (! $someVar || ! $x instanceOf stdClass) {}
if (!$someVar || !$x instanceOf stdClass) {}
if (! $someVar || ! $x instanceOf stdClass) {}
if (!foo() && (!$x || true)) {}
$var = !($x || $y);
$var = ! ($x || $y);
$var = ! /*comment*/ ($x || $y);
$baz = function () {
return ! $bar;
};
if ( !
($x || $y)
) {
return !$bar;
}
if ( ! // phpcs:ignore Standard.Cat.SniffName -- for reasons.
($x || $y)
) {}
// phpcs:set Generic.Formatting.SpaceAfterNot ignoreNewlines true
if ( !
($x || $y)
) {
return !$bar;
}
if ( ! // phpcs:ignore Standard.Cat.SniffName -- for reasons.
($x || $y)
) {}
// phpcs:set Generic.Formatting.SpaceAfterNot ignoreNewlines false
// phpcs:set Generic.Formatting.SpaceAfterNot spacing 2
if (! $someVar || ! $x instanceOf stdClass) {}
if (!$someVar || !$x instanceOf stdClass) {}
if (! $someVar || ! $x instanceOf stdClass) {}
if (!foo() && (! $x || true)) {}
$var = ! ($x || $y);
$var = ! ($x || $y);
$baz = function () {
return ! $bar;
};
if ( !
($x || $y)
) {
return !$bar;
}
// phpcs:set Generic.Formatting.SpaceAfterNot spacing 0
if (!$someVar || !$x instanceOf stdClass) {}
if (! $someVar || ! $x instanceOf stdClass) {}
if (! foo() && (!$x || true)) {}
$var = ! ($x || $y);
$var = ! /*comment*/ ($x || $y);
$baz = function () {
return ! $bar;
};
if ( !
($x || $y)
) {
return ! $bar;
}
if ( ! // phpcs:ignore Standard.Cat.SniffName -- for reasons.
($x || $y)
) {}
// phpcs:set Generic.Formatting.SpaceAfterNot ignoreNewlines true
if ( !
($x || $y)
) {
return ! $bar;
}
if ( ! // phpcs:ignore Standard.Cat.SniffName -- for reasons.
($x || $y)
) {}
// phpcs:set Generic.Formatting.SpaceAfterNot ignoreNewlines false
// phpcs:set Generic.Formatting.SpaceAfterNot spacing 1
@@ -0,0 +1,83 @@
<?php
if (! $someVar || ! $x instanceOf stdClass) {}
if (! $someVar || ! $x instanceOf stdClass) {}
if (! $someVar || ! $x instanceOf stdClass) {}
if (! foo() && (! $x || true)) {}
$var = ! ($x || $y);
$var = ! ($x || $y);
$var = ! /*comment*/ ($x || $y);
$baz = function () {
return ! $bar;
};
if ( ! ($x || $y)
) {
return ! $bar;
}
if ( ! // phpcs:ignore Standard.Cat.SniffName -- for reasons.
($x || $y)
) {}
// phpcs:set Generic.Formatting.SpaceAfterNot ignoreNewlines true
if ( !
($x || $y)
) {
return ! $bar;
}
if ( ! // phpcs:ignore Standard.Cat.SniffName -- for reasons.
($x || $y)
) {}
// phpcs:set Generic.Formatting.SpaceAfterNot ignoreNewlines false
// phpcs:set Generic.Formatting.SpaceAfterNot spacing 2
if (! $someVar || ! $x instanceOf stdClass) {}
if (! $someVar || ! $x instanceOf stdClass) {}
if (! $someVar || ! $x instanceOf stdClass) {}
if (! foo() && (! $x || true)) {}
$var = ! ($x || $y);
$var = ! ($x || $y);
$baz = function () {
return ! $bar;
};
if ( ! ($x || $y)
) {
return ! $bar;
}
// phpcs:set Generic.Formatting.SpaceAfterNot spacing 0
if (!$someVar || !$x instanceOf stdClass) {}
if (!$someVar || !$x instanceOf stdClass) {}
if (!foo() && (!$x || true)) {}
$var = !($x || $y);
$var = ! /*comment*/ ($x || $y);
$baz = function () {
return !$bar;
};
if ( !($x || $y)
) {
return !$bar;
}
if ( ! // phpcs:ignore Standard.Cat.SniffName -- for reasons.
($x || $y)
) {}
// phpcs:set Generic.Formatting.SpaceAfterNot ignoreNewlines true
if ( !
($x || $y)
) {
return !$bar;
}
if ( ! // phpcs:ignore Standard.Cat.SniffName -- for reasons.
($x || $y)
) {}
// phpcs:set Generic.Formatting.SpaceAfterNot ignoreNewlines false
// phpcs:set Generic.Formatting.SpaceAfterNot spacing 1
@@ -0,0 +1,7 @@
<?php
// Intentional parse error.
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
if (!
@@ -0,0 +1,66 @@
<?php
class myclass extends yourclass implements someint {
function myfunc($var) {
echo $var;
}
}
$myvar = true;
myfunc(&$myvar);
myfunc($myvar);
$this->myfunc(&$myvar);
$this->myfunc($myvar);
myclass::myfunc(&$myvar);
myclass::myfunc($myvar);
while(testfunc($var1, &$var2, $var3, &$var4) === false) {
}
sprintf("0%o", 0777 & $p);
$foo(&$myvar);
if (is_array($foo = &$this->bar())) {
}
Hooks::run( 'SecondaryDataUpdates', [ $title, $old, $recursive, $parserOutput, &$updates ] );
$foo = Bar(&$fooBar);
myfunc($myvar&$myvar);
myfunc($myvar[0]&$myvar);
myfunc(myclass::MY_CONST&$myvar);
myfunc(MY_CONST&$myvar);
efg( true == &$b );
efg( true === &$b );
foo($a, bar(&$b));
foo($a, array(&$b));
enum Foo {}
interface Foo {}
trait Foo {}
$instance = new $var($a);
$instance = new MyClass($a);
$instance = new $var(&$a);
$instance = new MyClass(&$a);
$anon = new class($a) {};
$anon = new class(&$a) {};
class Foo extends Bar {
function myMethod() {
$a = new static($var);
$b = new self($var);
$c = new parent($var);
$d = new static(&$var);
$e = new self(&$var);
$f = new parent(&$var);
}
}
@@ -0,0 +1,7 @@
<?php
// Intentional parse error.
// This should be the only test in this file.
// Testing that the sniff is *not* triggered when there are only empty tokens after a variable and nothing else.
$var
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing closing parenthesis).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
foo(
@@ -0,0 +1,199 @@
<?php
$result = myFunction();
$result = myFunction($arg1, $arg2);
$result = myFunction($arg1,$arg2);
$result = myFunction($arg1 , $arg2);
$result = myFunction($arg1 , $arg2);
$result = myFunction($arg1, $arg2, $arg3,$arg4, $arg5);
$result = myFunction($arg1, $arg2, $arg3, $arg4, $arg5);
$result = myFunction($arg1, $arg2 = array());
$result = myFunction($arg1 , $arg2 =array());
$result = myFunction($arg1 , $arg2= array());
$result = myFunction($arg1 , $arg2=array());
$result = myFunction($arg1,
$arg2 = array(),
$arg3,
$arg4,
$arg5);
throw new Exception("This is some massive string for a message",
$cause);
// Function definitions are ignored
function myFunction($arg1,$arg2)
{
}
function myFunction ($arg1,$arg2)
{
}
function myFunction($arg1=1,$arg2=2)
{
}
function myFunction($arg1 = 1,$arg2 = 2)
{
}
$key = array_search($this->getArray($one, $two,$three),$this->arrayMap);
$this->error($obj->getCode(),$obj->getMessage(),$obj->getFile(),$obj->getLine());
make_foo($string /*the string*/ , true /*test*/);
make_foo($string/*the string*/ , /*test*/ true);
make_foo($string /*the string*/, /*test*/ true);
class MyClass {
function myFunction() {
blah($foo, "{{$config['host']}}", "{$config}", "hi there{}{}{{{}{}{}}");
}
}
// Function definition, not function call, so should be ignored
function &myFunction($arg1=1,$arg2=2)
{
}
return array_udiff(
$foo,
$bar,
function($a, $b) {
$foo='bar';
return $foo;
}
);
var_dump(<<<FOO
foo
FOO
,
<<<BAR
bar
BAR
, <<<BAZ
baz
BAZ
,<<<'NOW'
now
NOW
, <<<'THEN'
then
THEN
);
if (in_array($arg1, ['foo','bar'])) {}
if (in_array($arg1, array('foo','bar'))) {}
$b = foo(
"1", // this is a comment
"2", // this is a comment
"3",// this is a comment
"4"
);
var_dump(
<<<TEXT
foo
TEXT
,
'bar'
);
unset($foo,$bar);
$closure($foo,$bar);
$var = $closure() + $closure($foo,$bar) + self::$closure($foo,$bar);
class Test
{
public static function baz($foo, $bar)
{
$a = new self($foo,$bar);
$b = new static($foo,$bar);
}
}
$obj->{$var}($foo,$bar);
(function ($a, $b) {
return function ($c, $d) use ($a, $b) {
echo $a, $b, $c, $d;
};
})('a','b')('c','d');
my_function_call(
'a'
/* Comment */
,'b'
, 'c' // Comment.
,'d'
,'e' // phpcs:ignore Standard.Category.Sniff -- for reasons.
, 'f'
);
$foobar = php73_function_call_trailing_comma(
$foo,
$bar,
);
$foobar = functionCallAnonClassParam(
new class() {
public $foo=1;
public function methodName($param='foo',$paramTwo='bar') {
$bar=false;
$foo = array(1,2,3);
}
},
$args=array(),
);
$result = myFunction(param1: $arg1, param2: $arg2);
$result = myFunction(param1: $arg1 , param2:$arg2);
$result = myFunction(param1: $arg1, param2:$arg2, param3: $arg3,param4:$arg4, param5:$arg5);
class Testing extends Bar
{
public static function baz($foo, $bar)
{
$a = new parent($foo, $bar);
$a = new parent($foo ,$bar);
}
}
// Ignore spacing after PHP 7.3+ trailing comma in single-line function calls to prevent fixer conflicts.
// This is something which should be decided by a sniff dealing with the function call parentheses.
$foo = new MyClass($obj, 'getMethod',);
$foo = new MyClass($obj, 'getMethod', );
$foo = new MyClass($obj, 'getMethod', );
$foo = new MyClass(
$obj,
'getMethod',
);
#[AttributeName(1, 2)]
#[AttributeName(1,2)]
$callable = myCallable(...);
// Skip over PHP 7.4 arrow functions.
// While any commas belonging to the code within the arrow function would always need to be within parentheses
// or within a short array, so there aren't any false positives, the sniff also does not need to examine these,
// so will be more efficient skipping over arrow functions.
$foobar = functionCallFnParamA(
fn ($foo,$bar) => [1,2,3],
$args,
);
$foobar = functionCallFnParamB(fn ($foo,$bar) => [1,2,3] ,$args);
$foobar = functionCallFnParamC($args, fn ($foo,$bar) => [1,2,3] , );
// Ignore spacing within PHP 8.0 match control structures, which may have their own rules.
$foobar = functionCallMatchParam(
match($foo) {
1,2,3 => 'something',4,5,6 => 'else',default => 'works'
} , // But check the spacing again once the match expression has finished.
$args
);
@@ -0,0 +1,199 @@
<?php
$result = myFunction();
$result = myFunction($arg1, $arg2);
$result = myFunction($arg1, $arg2);
$result = myFunction($arg1, $arg2);
$result = myFunction($arg1, $arg2);
$result = myFunction($arg1, $arg2, $arg3, $arg4, $arg5);
$result = myFunction($arg1, $arg2, $arg3, $arg4, $arg5);
$result = myFunction($arg1, $arg2 = array());
$result = myFunction($arg1, $arg2 =array());
$result = myFunction($arg1, $arg2= array());
$result = myFunction($arg1, $arg2=array());
$result = myFunction($arg1,
$arg2 = array(),
$arg3,
$arg4,
$arg5);
throw new Exception("This is some massive string for a message",
$cause);
// Function definitions are ignored
function myFunction($arg1,$arg2)
{
}
function myFunction ($arg1,$arg2)
{
}
function myFunction($arg1=1,$arg2=2)
{
}
function myFunction($arg1 = 1,$arg2 = 2)
{
}
$key = array_search($this->getArray($one, $two, $three), $this->arrayMap);
$this->error($obj->getCode(), $obj->getMessage(), $obj->getFile(), $obj->getLine());
make_foo($string /*the string*/, true /*test*/);
make_foo($string/*the string*/, /*test*/ true);
make_foo($string /*the string*/, /*test*/ true);
class MyClass {
function myFunction() {
blah($foo, "{{$config['host']}}", "{$config}", "hi there{}{}{{{}{}{}}");
}
}
// Function definition, not function call, so should be ignored
function &myFunction($arg1=1,$arg2=2)
{
}
return array_udiff(
$foo,
$bar,
function($a, $b) {
$foo='bar';
return $foo;
}
);
var_dump(<<<FOO
foo
FOO
,
<<<BAR
bar
BAR
, <<<BAZ
baz
BAZ
, <<<'NOW'
now
NOW
, <<<'THEN'
then
THEN
);
if (in_array($arg1, ['foo','bar'])) {}
if (in_array($arg1, array('foo','bar'))) {}
$b = foo(
"1", // this is a comment
"2", // this is a comment
"3", // this is a comment
"4"
);
var_dump(
<<<TEXT
foo
TEXT
,
'bar'
);
unset($foo, $bar);
$closure($foo, $bar);
$var = $closure() + $closure($foo, $bar) + self::$closure($foo, $bar);
class Test
{
public static function baz($foo, $bar)
{
$a = new self($foo, $bar);
$b = new static($foo, $bar);
}
}
$obj->{$var}($foo, $bar);
(function ($a, $b) {
return function ($c, $d) use ($a, $b) {
echo $a, $b, $c, $d;
};
})('a', 'b')('c', 'd');
my_function_call(
'a',
/* Comment */
'b',
'c', // Comment.
'd',
'e', // phpcs:ignore Standard.Category.Sniff -- for reasons.
'f'
);
$foobar = php73_function_call_trailing_comma(
$foo,
$bar,
);
$foobar = functionCallAnonClassParam(
new class() {
public $foo=1;
public function methodName($param='foo',$paramTwo='bar') {
$bar=false;
$foo = array(1,2,3);
}
},
$args=array(),
);
$result = myFunction(param1: $arg1, param2: $arg2);
$result = myFunction(param1: $arg1, param2:$arg2);
$result = myFunction(param1: $arg1, param2:$arg2, param3: $arg3, param4:$arg4, param5:$arg5);
class Testing extends Bar
{
public static function baz($foo, $bar)
{
$a = new parent($foo, $bar);
$a = new parent($foo, $bar);
}
}
// Ignore spacing after PHP 7.3+ trailing comma in single-line function calls to prevent fixer conflicts.
// This is something which should be decided by a sniff dealing with the function call parentheses.
$foo = new MyClass($obj, 'getMethod',);
$foo = new MyClass($obj, 'getMethod', );
$foo = new MyClass($obj, 'getMethod', );
$foo = new MyClass(
$obj,
'getMethod',
);
#[AttributeName(1, 2)]
#[AttributeName(1, 2)]
$callable = myCallable(...);
// Skip over PHP 7.4 arrow functions.
// While any commas belonging to the code within the arrow function would always need to be within parentheses
// or within a short array, so there aren't any false positives, the sniff also does not need to examine these,
// so will be more efficient skipping over arrow functions.
$foobar = functionCallFnParamA(
fn ($foo,$bar) => [1,2,3],
$args,
);
$foobar = functionCallFnParamB(fn ($foo,$bar) => [1,2,3], $args);
$foobar = functionCallFnParamC($args, fn ($foo,$bar) => [1,2,3], );
// Ignore spacing within PHP 8.0 match control structures, which may have their own rules.
$foobar = functionCallMatchParam(
match($foo) {
1,2,3 => 'something',4,5,6 => 'else',default => 'works'
}, // But check the spacing again once the match expression has finished.
$args
);
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing closing parenthesis).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
myFunction(
@@ -0,0 +1,232 @@
<?php
// Good.
function myFunction() {
}
// Brace should be on same line.
function myFunction()
{
}
// Too many spaces.
function myFunction() {
}
// Uses tab.
function myFunction() {
}
class myClass
{
// Good.
function myFunction() {
}
// Brace should be on same line.
function myFunction()
{
}
// Too many spaces.
function myFunction() {
}
// Uses tab.
function myFunction() {
}
}
/* Multi-line declarations */
// Good.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Brace should be on same line.
function myFunction($variable1, $variable2,
$variable3, $variable4)
{
}
// Too many spaces.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Uses tab.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
class myClass
{
// Good.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Brace should be on same line.
function myFunction($variable1, $variable2,
$variable3, $variable4)
{
}
// Too many spaces.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Uses tab.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
}
interface MyInterface
{
function myFunction();
}
function myFunction(
$arg1,
$arg2,
$arg3,
$arg4,
$arg5,
$arg6
)
{
}
function myFunction(
$arg1,
$arg2,
$arg3,
$arg4,
$arg5,
$arg6
) {
}
function myFunction() {}
function myFunction()
{}
// phpcs:set Generic.Functions.OpeningFunctionBraceKernighanRitchie checkClosures 1
$closureWithArgs = function ($arg1, $arg2){
// body
};
$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2){
// body
};
$test = function ($param) use ($result)
{
return null;
};
$test = function ($param) use ($result) : Something
{
return null;
};
$test = function ($param) use ($result): Something
{
return null;
};
foo(function ($bar) { ?>
<div><?php echo $bar; ?></div>
<?php });
// phpcs:set Generic.Functions.OpeningFunctionBraceKernighanRitchie checkClosures 0
$closureWithArgs = function ($arg1, $arg2){
// body
};
function myFunction() : Something
{
return null;
}
function myFunction() : Something // Break me
{
return null;
}
function myFunction(): Something {
return null;
}
function myFunction(): Something
{
return null;
}
function myFunction($bar) { ?>
<div><?php echo $bar; ?></div>
<?php }
function myFunction($a, $lot, $of, $params)
: array
{
return null;
}
function myFunction($a, $lot, $of, $params)
: array {
return null;
}
function myFunction($a, $lot, $of, $params) // comment
{
return null;
}
function myFunction($a, $lot, $of, $params)
: array // comment
{
return null;
}
function myFunction($a, $lot, $of, $params)
: array // phpcs:ignore Standard.Category.Sniff -- for reasons.
{
return null;
}
function myFunction($a, $lot, $of, $params)
: array { // phpcs:ignore Standard.Category.Sniff -- for reasons.
return null;
}
function myFunction() {}
function myFunction() {} // Too many spaces with an empty function.
function myFunction() {} // Too many spaces (tab) with an empty function.
// phpcs:set Generic.Functions.OpeningFunctionBraceKernighanRitchie checkFunctions 0
function shouldBeIgnored()
{}
// phpcs:set Generic.Functions.OpeningFunctionBraceKernighanRitchie checkFunctions 1
function dnfReturnType(): (Response&SuccessResponse)|AnotherResponse|string
{}
function commentAfterOpeningBrace() { // Some comment.
}
function variableAssignmentAfterOpeningBrace() { $a = 1;
}
abstract class MyClass {
abstract public function abstractMethod();
}
@@ -0,0 +1,222 @@
<?php
// Good.
function myFunction() {
}
// Brace should be on same line.
function myFunction() {
}
// Too many spaces.
function myFunction() {
}
// Uses tab.
function myFunction() {
}
class myClass
{
// Good.
function myFunction() {
}
// Brace should be on same line.
function myFunction() {
}
// Too many spaces.
function myFunction() {
}
// Uses tab.
function myFunction() {
}
}
/* Multi-line declarations */
// Good.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Brace should be on same line.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Too many spaces.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Uses tab.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
class myClass
{
// Good.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Brace should be on same line.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Too many spaces.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
// Uses tab.
function myFunction($variable1, $variable2,
$variable3, $variable4) {
}
}
interface MyInterface
{
function myFunction();
}
function myFunction(
$arg1,
$arg2,
$arg3,
$arg4,
$arg5,
$arg6
) {
}
function myFunction(
$arg1,
$arg2,
$arg3,
$arg4,
$arg5,
$arg6
) {
}
function myFunction() {}
function myFunction() {
}
// phpcs:set Generic.Functions.OpeningFunctionBraceKernighanRitchie checkClosures 1
$closureWithArgs = function ($arg1, $arg2) {
// body
};
$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
// body
};
$test = function ($param) use ($result) {
return null;
};
$test = function ($param) use ($result) : Something {
return null;
};
$test = function ($param) use ($result): Something {
return null;
};
foo(function ($bar) { ?>
<div><?php echo $bar; ?></div>
<?php });
// phpcs:set Generic.Functions.OpeningFunctionBraceKernighanRitchie checkClosures 0
$closureWithArgs = function ($arg1, $arg2){
// body
};
function myFunction() : Something {
return null;
}
function myFunction() : Something {
// Break me
return null;
}
function myFunction(): Something {
return null;
}
function myFunction(): Something {
return null;
}
function myFunction($bar) { ?>
<div><?php echo $bar; ?></div>
<?php }
function myFunction($a, $lot, $of, $params)
: array {
return null;
}
function myFunction($a, $lot, $of, $params)
: array {
return null;
}
function myFunction($a, $lot, $of, $params) {
// comment
return null;
}
function myFunction($a, $lot, $of, $params)
: array {
// comment
return null;
}
function myFunction($a, $lot, $of, $params)
: array { // phpcs:ignore Standard.Category.Sniff -- for reasons.
return null;
}
function myFunction($a, $lot, $of, $params)
: array { // phpcs:ignore Standard.Category.Sniff -- for reasons.
return null;
}
function myFunction() {}
function myFunction() {} // Too many spaces with an empty function.
function myFunction() {} // Too many spaces (tab) with an empty function.
// phpcs:set Generic.Functions.OpeningFunctionBraceKernighanRitchie checkFunctions 0
function shouldBeIgnored()
{}
// phpcs:set Generic.Functions.OpeningFunctionBraceKernighanRitchie checkFunctions 1
function dnfReturnType(): (Response&SuccessResponse)|AnotherResponse|string {
}
function commentAfterOpeningBrace() {
// Some comment.
}
function variableAssignmentAfterOpeningBrace() {
$a = 1;
}
abstract class MyClass {
abstract public function abstractMethod();
}
@@ -0,0 +1,19 @@
<?php
// Tests with tabs and the tabWidth config set to 4.
// Uses one tab.
function myFunction() {
}
// Uses three tabs.
function myFunction() {
}
// Uses one tab in a way that it translates to exactly one space with tab replacement.
function oneT() {
}
// Mixed tabs and spaces.
function mixed() {
}
@@ -0,0 +1,19 @@
<?php
// Tests with tabs and the tabWidth config set to 4.
// Uses one tab.
function myFunction() {
}
// Uses three tabs.
function myFunction() {
}
// Uses one tab in a way that it translates to exactly one space with tab replacement.
function oneT() {
}
// Mixed tabs and spaces.
function mixed() {
}
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing opening curly brace).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
function missingOpeningCurlyBrace()
@@ -0,0 +1,460 @@
<?php
function complexityOne() { }
function complexityFive()
{
if ($condition) {
}
switch ($condition) {
case '1':
break;
case '2':
break;
case '3':
break;
}
}
function complexityTen()
{
while ($condition === true) {
if ($condition) {
}
}
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityEleven()
{
while ($condition === true) {
if ($condition) {
} elseif ($cond) {
}
}
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
default:
break;
}
foreach ($array as $element) {}
}
function complexityTwenty()
{
while ($condition === true) {
if ($condition) {
} else if ($cond) {
}
}
switch ($condition) {
case '1':
do {
if ($condition) {
} else if ($cond) {
}
} while ($cond);
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
switch ($cond) {
case '1':
break;
case '2':
break;
}
break;
case '4':
do {
if ($condition) {
if ($cond) {
} else if ($con) {
}
}
} while ($cond);
break;
default:
if ($condition) {
}
break;
}
}
function complexityTwentyOne()
{
while ($condition === true) {
do {
if ($condition) {
} else if ($cond) {
}
} while ($cond);
}
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '4':
do {
if ($condition) {
if ($cond) {
} else if ($con) {
}
}
} while ($cond);
break;
default:
if ($condition) {
} else if ($cond) {
}
break;
}
try {
for ($i = 0; $i < 10; $i++) {
if ($i % 2) {
doSomething();
}
}
} catch (Exception $e) {
}
}
function complexityTenWithTernaries()
{
$value1 = (empty($condition1)) ? $value1A : $value1B;
$value2 = (empty($condition2)) ? $value2A : $value2B;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityElevenWithTernaries()
{
$value1 = (empty($condition1)) ? $value1A : $value1B;
$value2 = (empty($condition2)) ? $value2A : $value2B;
$value3 = (empty($condition3)) ? $value3A : $value3B;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityTenWithNestedTernaries()
{
$value1 = true ? $value1A : false ? $value1B : $value1C;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityElevenWithNestedTernaries()
{
$value1 = (empty($condition1)) ? $value1A : $value1B;
$value2 = true ? $value2A : false ? $value2B : $value2C;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityTenWithNullCoalescence()
{
$value1 = $value1A ?? $value1B;
$value2 = $value2A ?? $value2B;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityElevenWithNullCoalescence()
{
$value1 = $value1A ?? $value1B;
$value2 = $value2A ?? $value2B;
$value3 = $value3A ?? $value3B;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityTenWithNestedNullCoalescence()
{
$value1 = $value1A ?? $value1B ?? $value1C;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityElevenWithNestedNullCoalescence()
{
$value1 = $value1A ?? $value1B;
$value2 = $value2A ?? $value2B ?? $value2C;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityTenWithNullCoalescenceAssignment()
{
$value1 ??= $default1;
$value2 ??= $default2;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityElevenWithNullCoalescenceAssignment()
{
$value1 ??= $default1;
$value2 ??= $default2;
$value3 ??= $default3;
switch ($condition) {
case '1':
if ($condition) {
} else if ($cond) {
}
break;
case '2':
while ($cond) {
echo 'hi';
}
break;
case '3':
break;
default:
break;
}
}
function complexityFiveWithMatch()
{
return match(strtolower(substr($monthName, 0, 3))){
'apr', 'jun', 'sep', 'nov' => 30,
'jan', 'mar', 'may', 'jul', 'aug', 'oct', 'dec' => 31,
'feb' => is_leap_year($year) ? 29 : 28,
default => throw new InvalidArgumentException("Invalid month"),
}
}
function complexityFourteenWithMatch()
{
return match(strtolower(substr($monthName, 0, 3))) {
'jan' => 31,
'feb' => is_leap_year($year) ? 29 : 28,
'mar' => 31,
'apr' => 30,
'may' => 31,
'jun' => 30,
'jul' => 31,
'aug' => 31,
'sep' => 30,
'oct' => 31,
'nov' => 30,
'dec' => 31,
default => throw new InvalidArgumentException("Invalid month"),
};
}
function complexitySevenWithNullSafeOperator()
{
$foo = $object1->getX()?->getY()?->getZ();
$bar = $object2->getX()?->getY()?->getZ();
$baz = $object3->getX()?->getY()?->getZ();
}
function complexityElevenWithNullSafeOperator()
{
$foo = $object1->getX()?->getY()?->getZ();
$bar = $object2->getX()?->getY()?->getZ();
$baz = $object3->getX()?->getY()?->getZ();
$bacon = $object4->getX()?->getY()?->getZ();
$bits = $object5->getX()?->getY()?->getZ();
}
abstract class AbstractClass {
abstract public function sniffShouldIgnoreAbstractMethods();
}
interface MyInterface {
public function sniffShouldIgnoreInterfaceMethods();
}
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing opening curly bracket).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
function sniffShouldBailMissingScopeOpener()
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing closing curly bracket).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
function sniffShouldBailMissingScopeCloser() {
@@ -0,0 +1,108 @@
<?php
function nestingOne()
{
if ($condition) {
echo 'hi';
}
}
function nestingFive()
{
if ($condition) {
echo 'hi';
switch ($condition)
{
case '1':
if ($condition === '1') {
if ($cond) {
echo 'hi';
}
}
break;
}
}
}
function nestingSix()
{
if ($condition) {
} else {
switch ($condition) {
case '1':
if ($condition === '1') {
} elseif ($condition === '2') {
do {
foreach ($conds as $cond) {
echo 'hi';
}
} while ($cond > 5);
}
break;
}
}
}
function nestingTen()
{
if ($condition) {
echo 'hi';
switch ($condition)
{
case '1':
if ($condition === '1') {
if ($cond) {
switch ($cond) {
case '1':
if ($cond === '1') {
foreach ($conds as $cond) {
if ($cond === 'hi') {
echo 'hi';
}
}
}
break;
}
}
}
break;
}
}
}
function nestingEleven()
{
if ($condition) {
echo 'hi';
switch ($condition)
{
case '1':
if ($condition === '1') {
if ($cond) {
try {
if ( $cond === '1' ) {
for ( $i = 0; $i < 10; $i ++ ) {
while ($i < 5) {
if ( $cond === 'hi' ) {
match ( $cond ) {
'hi' => 'something',
};
}
}
}
}
} catch (Exception $e) {}
}
}
break;
}
}
}
abstract class AbstractClass {
abstract public function sniffShouldIgnoreAbstractMethods();
}
interface MyInterface {
public function sniffShouldIgnoreInterfaceMethods();
}
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing opening curly bracket).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
function sniffShouldBailMissingScopeOpener()
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing closing curly bracket).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
function sniffShouldBailMissingScopeCloser() {
@@ -0,0 +1,45 @@
<?php
abstract class IncorrectName {} // Error.
abstract class AbstractCorrectName {}
abstract class IncorrectNameAbstract {} // Error.
abstract
/*comment*/
class
InvalidNameabstract
extends
BarClass {} // Error.
abstract class /*comment*/ IncorrectAbstractName {} // Error.
// Anonymous classes can't be declared as abstract (and don't have a name anyhow).
$anon = new class {};
// Make sure that if the class is not abstract, the sniff does not check the name.
class AbstractClassName {}
// Class name is always checked, doesn't matter if the class is declared conditionally.
if (!class_exists('AbstractClassCorrectName')) {
abstract class AbstractClassCorrectName {}
}
if (!class_exists('ClassAbstractIncorrectName')) {
abstract class ClassAbstractIncorrectName implements FooInterface {} // Error.
}
$var = 'abstract class TextStringsAreDisregarded';
class NotAnAbstractClassSoNoPrefixRequired {}
abstract class abstractOkCaseOfPrefixIsNotEnforced {}
final class FinalClassShouldNotTriggerWarning {}
readonly class ReadonlyClassShouldNotTriggerWarning {}
abstract readonly class AbstractReadonlyClassWithPrefixShouldNotTriggerWarning {}
abstract readonly class ReadonlyAbstractClassShouldTriggerWarningWhenPrefixIsMissingA {} // Error.
readonly abstract class ReadonlyAbstractClassShouldTriggerWarningWhenPrefixIsMissingB {} // Error.
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (no class name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
abstract class
@@ -0,0 +1,204 @@
<?php
abstract class My_Class {
public function __construct() {}
public function My_Class() {}
public function _My_Class() {}
public function getSomeValue() {}
public function parseMyDSN() {}
public function get_some_value() {}
public function GetSomeValue() {}
public function getSomeValue_Again() {}
protected function getSomeValue() {}
protected function parseMyDSN() {}
protected function get_some_value() {}
private function _getSomeValue() {}
private function parseMyDSN() {}
private function _get_some_value() {}
function getSomeValue() {}
function parseMyDSN() {}
function get_some_value() {}
}//end class
function getSomeValue() {}
function parseMyDSN() {}
function get_some_value() {}
/* Test for magic functions */
class Magic_Test {
function __construct() {}
function __destruct() {}
function __call($name, $args) {}
static function __callStatic($name, $args) {}
function __get($name) {}
function __set($name, $value) {}
function __isset($name) {}
function __unset($name) {}
function __sleep() {}
function __wakeup() {}
function __toString() {}
function __set_state() {}
function __clone() {}
function __autoload() {}
function __invoke() {}
function __myFunction() {}
function __my_function() {}
}
function __construct() {}
function __destruct() {}
function __call() {}
function __callStatic() {}
function __get() {}
function __set() {}
function __isset() {}
function __unset() {}
function __sleep() {}
function __wakeup() {}
function __toString() {}
function __set_state() {}
function __clone() {}
function __autoload($class) {}
function __invoke() {}
function __myFunction() {}
function __my_function() {}
class Closure_Test {
function test() {
$foo = function() { echo 'foo'; };
}
}
function test() {
$foo = function() { echo 'foo'; };
}
/* @codingStandardsIgnoreStart */
class MyClass
{
/* @codingStandardsIgnoreEnd */
public function __construct() {}
}
trait Foo
{
function __call($name, $args) {}
}
class Magic_Case_Test {
function __Construct() {}
function __isSet($name) {}
function __tostring() {}
}
function __autoLoad($class) {}
class Foo extends \SoapClient
{
public function __soapCall(
$functionName,
$arguments,
$options = array(),
$inputHeaders = null,
&$outputHeaders = array()
) {
// body
}
}
function __debugInfo() {}
class Foo {
function __debugInfo() {}
}
function ___tripleUnderscore() {} // Ok.
class triple {
public function ___tripleUnderscore() {} // Ok.
}
/* Magic methods in anonymous classes. */
$a = new class {
function __construct() {}
function __destruct() {}
function __call($name, $args) {}
static function __callStatic($name, $args) {}
function __get($name) {}
function __set($name, $value) {}
function __isset($name) {}
function __unset($name) {}
function __sleep() {}
function __wakeup() {}
function __toString() {}
function __set_state() {}
function __clone() {}
function __autoload() {}
function __invoke() {}
function __myFunction() {}
function __my_function() {}
};
class FooBar extends \SoapClient {
public function __getCookies() {}
}
class Nested {
public function getAnonymousClass() {
return new class() {
public function nested_function() {}
function __something() {}
};
}
}
abstract class My_Class {
public function my_class() {}
public function _MY_CLASS() {}
}
enum Suit: string implements Colorful, CardGame {
// Magic methods.
function __call($name, $args) {}
static function __callStatic($name, $args) {}
function __invoke() {}
// Valid Method Name.
public function getSomeValue() {}
// Double underscore non-magic methods not allowed.
function __myFunction() {}
function __my_function() {}
// Non-camelcase.
public function parseMyDSN() {}
public function get_some_value() {}
}
interface MyInterface {
public function getSomeValue();
public function get_some_value();
}
class MyClass {
// phpcs:set Generic.NamingConventions.CamelCapsFunctionName strict false
function strictFOrmatDIsabled() {} // Ok.
// phpcs:set Generic.NamingConventions.CamelCapsFunctionName strict true
function strictFOrmatIsENabled() {} // Not ok.
}
// phpcs:set Generic.NamingConventions.CamelCapsFunctionName strict false
function strictFOrmatDIsabled() {} // Ok.
// phpcs:set Generic.NamingConventions.CamelCapsFunctionName strict true
function strictFOrmatIsENabled() {} // Not ok.
@@ -0,0 +1,9 @@
<?php
// Intentional parse error (missing method name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
class My_Class {
public function {}
}
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing function name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
function
@@ -0,0 +1,13 @@
<?php
interface SomeNameInterface {}
interface MissingInterfaceSuffix {} // Error.
interface CaseOfSuffixIsNotEnforced_interFACE {}
interface
/*comment*/
InterfaceAnotherInvalidName
extends
AnotherInterface, \Countable {} // Error.
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (no interface name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
interface
@@ -0,0 +1,11 @@
<?php
trait MissingTraitSuffix {} // Error.
trait GoodTrait {}
trait SuffixCaseIsNotEnforced_tRaIt {}
trait
/*comment*/
AnotherInvalidTraitName {} // Error.
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (no trait name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
trait
@@ -0,0 +1,91 @@
<?php
use Exception as My_Exception, foo\bar, baz;
namespace foo;
namespace foo\bar;
namespace bar\foo\baz;
define('VALID_NAME', true);
DEFINE('invalidName', true);
define("VALID_NAME", true);
define("invalidName", true);
define('bar\foo\baz\VALID_NAME_WITH_NAMESPACE', true);
define('bar\foo\baz\invalidNameWithNamespace', true);
define("bar\foo\baz\VALID_NAME_WITH_NAMESPACE", true);
define("bar\foo\baz\invalidNameWithNamespace", true);
class TestClass extends MyClass implements MyInterface, YourInterface
{
const const1 = 'hello';
const CONST2 = 'hello';
}
$foo->define('bar');
$foo->getBar()->define('foo');
Foo::define('bar');
class ClassConstBowOutTest {
const /* comment */ abc = 1;
const // phpcs:ignore Standard.Category.Sniff
some_constant = 2;
}
$foo->getBar()?->define('foo');
// PHP 8.3 introduces typed constants.
class TypedConstants {
const MyClass MYCONST = new MyClass;
const int VALID_NAME = 0;
final public const INT invalid_name = 0;
const FALSE false = false; // Yes, false can be used as a constant name, don't ask.
final protected const array ARRAY = array(); // Same goes for array.
}
define /* comment */ ( /* comment */ 'CommentsInUnconventionalPlaces', 'value' );
define
// comment
(
// phpcs:ignore Stnd.Cat.SniffName -- for reasons.
'CommentsInUnconventionalPlaces',
'value'
);
$foo-> /* comment */ define('bar');
$foo?->
// phpcs:ignore Stnd.Cat.SniffName -- for reasons.
define('bar');
const DEFINE = 'value';
#[Define('some param')]
class MyClass {}
#[
AttributeA,
define('some param')
]
class MyClass {}
const MixedCase = 1;
define('lower_case_name', 'value');
define($var, 'sniff should bow out');
define(constantName(), 'sniff should bow out');
define($obj->constantName(), 'sniff should bow out');
define(MyClass::constantName(), 'sniff should bow out');
define(condition() ? 'name1' : 'name2', 'sniff should bow out');
$callable = define(...);
// Valid if outside the global namespace. Sniff should bow out.
function define($param) {}
class MyClass {
public function define($param) {}
}
$a = ($cond) ? DEFINE : SOMETHING_ELSE;
$object = new Define('value');
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing constant name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
define(
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing opening parenthesis).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
define
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (missing constant name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
const =
@@ -0,0 +1,9 @@
<?php
// Intentional parse error (missing class constant value).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
class TypedConstants {
const MISSING_VALUE;
}
@@ -0,0 +1,6 @@
// Although not the focus of this test, this is an intentional parse error when short_open_tag is on.
// This should be the only test in this file.
// Test that the sniff bails when short_open_tag is off and there is a token other than
// T_INLINE_HTML after the short open tag and before the close tag.
<?<?php
@@ -0,0 +1,153 @@
<?php
// True
function myFunction($arg1, $arg2=true)
{
}
function myFunction($arg1, $arg2=TRUE)
{
}
function myFunction($arg1, $arg2=True)
{
}
if ($variable === true) { }
if ($variable === TRUE) { }
if ($variable === True) { }
// False
function myFunction($arg1, $arg2=false)
{
}
function myFunction($arg1, $arg2=FALSE)
{
}
function myFunction($arg1, $arg2=False)
{
}
if ($variable === false) { }
if ($variable === FALSE) { }
if ($variable === False) { }
// Null
function myFunction($arg1, $arg2=null)
{
}
function myFunction($arg1, $arg2=NULL)
{
}
function myFunction($arg1, $arg2=Null)
{
}
if ($variable === null) { }
if ($variable === NULL) { }
if ($variable === Null) { }
$x = new stdClass();
$x->NULL = 7;
use Zend\Log\Writer\NULL as NullWriter;
new \Zend\Log\Writer\NULL();
namespace False;
class True extends Null implements False {}
use True\Something;
use Something\True;
class MyClass
{
public function myFunction()
{
$var = array('foo' => new True());
}
}
$x = $f?FALSE:true;
$x = $f? FALSE:true;
class MyClass
{
// Spice things up a little.
const TRUE = false;
}
var_dump(MyClass::TRUE);
function tRUE() {}
$input->getFilterChain()->attachByName('Null', ['type' => Null::TYPE_STRING]);
// Issue #3332 - ignore type declarations, but not default values.
class TypedThings {
const MYCONST = FALSE;
public int|FALSE $int = FALSE;
public Type|NULL $int = new MyObj(NULL);
private function typed(int|FALSE $param = NULL, Type|NULL $obj = new MyObj(FALSE)) : string|FALSE|NULL
{
if (TRUE === FALSE) {
return NULL;
}
}
}
$cl = function (int|FALSE $param = NULL, Type|NULL $obj = new MyObj(FALSE)) : string|FALSE|NULL {};
// Adding some extra tests to safeguard that function declarations which don't create scope are handled correctly.
interface InterfaceMethodsWithReturnTypeNoScopeOpener {
private function typed($param = TRUE) : string|FALSE|NULL;
}
abstract class ClassMethodsWithReturnTypeNoScopeOpener {
abstract public function typed($param = FALSE) : TRUE;
}
// Additional tests to safeguard improved property type skip logic.
readonly class Properties {
use SomeTrait {
sayHello as private myPrivateHello;
}
public Type|FALSE|NULL $propertyA = array(
'itemA' => TRUE,
'itemB' => FALSE,
'itemC' => NULL,
), $propertyB = FALSE;
protected \FullyQualified&Partially\Qualified&namespace\Relative $propertyC;
var ?TRUE $propertyD;
static array|callable|FALSE|self|parent $propertyE = TRUE;
private
// phpcs:ignore Stnd.Cat.Sniff -- for reasons.
TRUE /*comment*/
$propertyF = TRUE;
public function __construct(
public FALSE|NULL $promotedPropA,
readonly callable|TRUE $promotedPropB,
) {
static $var;
echo static::class;
static::foo();
$var = $var instanceof static;
$obj = new static();
}
public static function foo(): static|self|FALSE {
$callable = static function() {};
}
}
// PHP 8.3 introduces typed constants.
class TypedConstants {
const MyClass|NULL|TRUE|FALSE MYCONST = FALSE;
}
// Global constants can not be typed.
const MYCONST = TRUE;
@@ -0,0 +1,153 @@
<?php
// True
function myFunction($arg1, $arg2=true)
{
}
function myFunction($arg1, $arg2=true)
{
}
function myFunction($arg1, $arg2=true)
{
}
if ($variable === true) { }
if ($variable === true) { }
if ($variable === true) { }
// False
function myFunction($arg1, $arg2=false)
{
}
function myFunction($arg1, $arg2=false)
{
}
function myFunction($arg1, $arg2=false)
{
}
if ($variable === false) { }
if ($variable === false) { }
if ($variable === false) { }
// Null
function myFunction($arg1, $arg2=null)
{
}
function myFunction($arg1, $arg2=null)
{
}
function myFunction($arg1, $arg2=null)
{
}
if ($variable === null) { }
if ($variable === null) { }
if ($variable === null) { }
$x = new stdClass();
$x->NULL = 7;
use Zend\Log\Writer\NULL as NullWriter;
new \Zend\Log\Writer\NULL();
namespace False;
class True extends Null implements False {}
use True\Something;
use Something\True;
class MyClass
{
public function myFunction()
{
$var = array('foo' => new True());
}
}
$x = $f?false:true;
$x = $f? false:true;
class MyClass
{
// Spice things up a little.
const TRUE = false;
}
var_dump(MyClass::TRUE);
function tRUE() {}
$input->getFilterChain()->attachByName('Null', ['type' => Null::TYPE_STRING]);
// Issue #3332 - ignore type declarations, but not default values.
class TypedThings {
const MYCONST = false;
public int|FALSE $int = false;
public Type|NULL $int = new MyObj(null);
private function typed(int|FALSE $param = null, Type|NULL $obj = new MyObj(false)) : string|FALSE|NULL
{
if (true === false) {
return null;
}
}
}
$cl = function (int|FALSE $param = null, Type|NULL $obj = new MyObj(false)) : string|FALSE|NULL {};
// Adding some extra tests to safeguard that function declarations which don't create scope are handled correctly.
interface InterfaceMethodsWithReturnTypeNoScopeOpener {
private function typed($param = true) : string|FALSE|NULL;
}
abstract class ClassMethodsWithReturnTypeNoScopeOpener {
abstract public function typed($param = false) : TRUE;
}
// Additional tests to safeguard improved property type skip logic.
readonly class Properties {
use SomeTrait {
sayHello as private myPrivateHello;
}
public Type|FALSE|NULL $propertyA = array(
'itemA' => true,
'itemB' => false,
'itemC' => null,
), $propertyB = false;
protected \FullyQualified&Partially\Qualified&namespace\Relative $propertyC;
var ?TRUE $propertyD;
static array|callable|FALSE|self|parent $propertyE = true;
private
// phpcs:ignore Stnd.Cat.Sniff -- for reasons.
TRUE /*comment*/
$propertyF = true;
public function __construct(
public FALSE|NULL $promotedPropA,
readonly callable|TRUE $promotedPropB,
) {
static $var;
echo static::class;
static::foo();
$var = $var instanceof static;
$obj = new static();
}
public static function foo(): static|self|FALSE {
$callable = static function() {};
}
}
// PHP 8.3 introduces typed constants.
class TypedConstants {
const MyClass|NULL|TRUE|FALSE MYCONST = false;
}
// Global constants can not be typed.
const MYCONST = true;
@@ -0,0 +1,4 @@
<?php
// Intentional parse error. Testing that the sniff is *not* triggered in this case.
function UnclosedCurly (): FALSE {
@@ -0,0 +1,108 @@
<?php
/*
* Test file 1 and 2 mirror each other, with file 1 containing non-indented cross-version compatible heredoc/nowdoc syntax,
* while the code samples in file 2 use PHP 7.3+ flexible heredoc/nowdoc syntax.
*
* These two files should be kept in sync!
*/
$nowdoc = <<<'EOD'
some text
EOD;
$heredoc = <<<END
some $foo text
END;
$heredoc = <<<"END"
some {$foo[0]} text
END;
$heredoc = <<<END
{$foo?->bar}
END;
$heredoc = <<< "END"
some ${beers::softdrink}
END;
$heredoc = <<< END
{${$object->getName()}} text
END;
$heredoc = <<<"END"
some {${getName()}}
END;
$heredoc = <<<END
${substr('laruence', 0, 2)}
END;
$heredoc = <<<"END"
some {$foo['bar']->baz()()}
END;
$heredoc = <<<END
{$obj->values[3]->name} text
END;
$heredoc = <<<"END"
some ${$bar}
END;
$heredoc = <<<END
${foo->bar} text
END;
$heredoc = <<<"END"
${foo["${bar}"]} text
END;
$heredoc = <<<END
some ${foo["${bar[\'baz\']}"]}
END;
$heredoc = <<<"END"
${foo->{${'a'}}} text
END;
$heredoc = <<<END
some {$foo->{$baz[1]}}
END;
$heredoc = <<<END
some text
{${beers::$ale}}
some text
END;
$heredoc = <<<"END"
$people->john's wife greeted $people->robert.
END;
$heredoc = <<<END
Let's make sure it also works with this: {$arr[foo][3]}
END;
$heredoc = <<<END
Testing ${foo["${bar
['baz']
}"]} and more testing
END;
$heredoc = <<<"END"
Testing {${foo["${bar
['baz']
}"]}} and more testing
END;
$heredoc = <<<END
some text
END;
$heredoc = <<< "END"
some text
some \$text
some text
END;
@@ -0,0 +1,108 @@
<?php
/*
* Test file 1 and 2 mirror each other, with file 1 containing non-indented cross-version compatible heredoc/nowdoc syntax,
* while the code samples in file 2 use PHP 7.3+ flexible heredoc/nowdoc syntax.
*
* These two files should be kept in sync!
*/
$nowdoc = <<<'EOD'
some text
EOD;
$heredoc = <<<END
some $foo text
END;
$heredoc = <<<"END"
some {$foo[0]} text
END;
$heredoc = <<<END
{$foo?->bar}
END;
$heredoc = <<< "END"
some ${beers::softdrink}
END;
$heredoc = <<< END
{${$object->getName()}} text
END;
$heredoc = <<<"END"
some {${getName()}}
END;
$heredoc = <<<END
${substr('laruence', 0, 2)}
END;
$heredoc = <<<"END"
some {$foo['bar']->baz()()}
END;
$heredoc = <<<END
{$obj->values[3]->name} text
END;
$heredoc = <<<"END"
some ${$bar}
END;
$heredoc = <<<END
${foo->bar} text
END;
$heredoc = <<<"END"
${foo["${bar}"]} text
END;
$heredoc = <<<END
some ${foo["${bar[\'baz\']}"]}
END;
$heredoc = <<<"END"
${foo->{${'a'}}} text
END;
$heredoc = <<<END
some {$foo->{$baz[1]}}
END;
$heredoc = <<<END
some text
{${beers::$ale}}
some text
END;
$heredoc = <<<"END"
$people->john's wife greeted $people->robert.
END;
$heredoc = <<<END
Let's make sure it also works with this: {$arr[foo][3]}
END;
$heredoc = <<<END
Testing ${foo["${bar
['baz']
}"]} and more testing
END;
$heredoc = <<<"END"
Testing {${foo["${bar
['baz']
}"]}} and more testing
END;
$heredoc = <<<'END'
some text
END;
$heredoc = <<< 'END'
some text
some \$text
some text
END;
@@ -0,0 +1,108 @@
<?php
/*
* Test file 1 and 2 mirror each other, with file 1 containing non-indented cross-version compatible heredoc/nowdoc syntax,
* while the code samples in file 2 use PHP 7.3+ flexible heredoc/nowdoc syntax.
*
* These two files should be kept in sync!
*/
$nowdoc = <<<'EOD'
some text
EOD;
$heredoc = <<<END
some $foo text
END;
$heredoc = <<<"END"
some {$foo[0]} text
END;
$heredoc = <<<END
{$foo?->bar}
END;
$heredoc = <<< "END"
some ${beers::softdrink}
END;
$heredoc = <<< END
{${$object->getName()}} text
END;
$heredoc = <<<"END"
some {${getName()}}
END;
$heredoc = <<<END
${substr('laruence', 0, 2)}
END;
$heredoc = <<<"END"
some {$foo['bar']->baz()()}
END;
$heredoc = <<<END
{$obj->values[3]->name} text
END;
$heredoc = <<<"END"
some ${$bar}
END;
$heredoc = <<<END
${foo->bar} text
END;
$heredoc = <<<"END"
${foo["${bar}"]} text
END;
$heredoc = <<<END
some ${foo["${bar[\'baz\']}"]}
END;
$heredoc = <<<"END"
${foo->{${'a'}}} text
END;
$heredoc = <<<END
some {$foo->{$baz[1]}}
END;
$heredoc = <<<END
some text
{${beers::$ale}}
some text
END;
$heredoc = <<<"END"
$people->john's wife greeted $people->robert.
END;
$heredoc = <<<END
Let's make sure it also works with this: {$arr[foo][3]}
END;
$heredoc = <<<END
Testing ${foo["${bar
['baz']
}"]} and more testing
END;
$heredoc = <<<"END"
Testing {${foo["${bar
['baz']
}"]}} and more testing
END;
$heredoc = <<<END
some text
END;
$heredoc = <<< "END"
some text
some \$text
some text
END;
@@ -0,0 +1,108 @@
<?php
/*
* Test file 1 and 2 mirror each other, with file 1 containing non-indented cross-version compatible heredoc/nowdoc syntax,
* while the code samples in file 2 use PHP 7.3+ flexible heredoc/nowdoc syntax.
*
* These two files should be kept in sync!
*/
$nowdoc = <<<'EOD'
some text
EOD;
$heredoc = <<<END
some $foo text
END;
$heredoc = <<<"END"
some {$foo[0]} text
END;
$heredoc = <<<END
{$foo?->bar}
END;
$heredoc = <<< "END"
some ${beers::softdrink}
END;
$heredoc = <<< END
{${$object->getName()}} text
END;
$heredoc = <<<"END"
some {${getName()}}
END;
$heredoc = <<<END
${substr('laruence', 0, 2)}
END;
$heredoc = <<<"END"
some {$foo['bar']->baz()()}
END;
$heredoc = <<<END
{$obj->values[3]->name} text
END;
$heredoc = <<<"END"
some ${$bar}
END;
$heredoc = <<<END
${foo->bar} text
END;
$heredoc = <<<"END"
${foo["${bar}"]} text
END;
$heredoc = <<<END
some ${foo["${bar[\'baz\']}"]}
END;
$heredoc = <<<"END"
${foo->{${'a'}}} text
END;
$heredoc = <<<END
some {$foo->{$baz[1]}}
END;
$heredoc = <<<END
some text
{${beers::$ale}}
some text
END;
$heredoc = <<<"END"
$people->john's wife greeted $people->robert.
END;
$heredoc = <<<END
Let's make sure it also works with this: {$arr[foo][3]}
END;
$heredoc = <<<END
Testing ${foo["${bar
['baz']
}"]} and more testing
END;
$heredoc = <<<"END"
Testing {${foo["${bar
['baz']
}"]}} and more testing
END;
$heredoc = <<<'END'
some text
END;
$heredoc = <<< 'END'
some text
some \$text
some text
END;
@@ -0,0 +1,6 @@
<?php
// Intentional parse error. Making sure that the sniff does not act on unfinished heredocs during live coding.
$heredoc = <<<EOD
Some text
Some txt
@@ -0,0 +1,74 @@
<?php
/**
* Unit test class for the UnnecessaryHeredoc sniff.
*
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
* @copyright 2024 PHPCSStandards and contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Standards\Generic\Tests\Strings;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
/**
* Unit test class for the UnnecessaryHeredoc sniff.
*
* @covers \PHP_CodeSniffer\Standards\Generic\Sniffs\Strings\UnnecessaryHeredocSniff
*/
final class UnnecessaryHeredocUnitTest extends AbstractSniffUnitTest
{
/**
* Returns the lines where errors should occur.
*
* The key of the array should represent the line number and the value
* should represent the number of errors that should occur on that line.
*
* @return array<int, int>
*/
public function getErrorList()
{
return [];
}//end getErrorList()
/**
* Returns the lines where warnings should occur.
*
* The key of the array should represent the line number and the value
* should represent the number of warnings that should occur on that line.
*
* @param string $testFile The name of the file being tested.
*
* @return array<int, int>
*/
public function getWarningList($testFile='')
{
$warnings = [
100 => 1,
104 => 1,
];
switch ($testFile) {
case 'UnnecessaryHeredocUnitTest.1.inc':
return $warnings;
case 'UnnecessaryHeredocUnitTest.2.inc':
if (PHP_VERSION_ID >= 70300) {
return $warnings;
}
// PHP 7.2 or lower: PHP version which doesn't support flexible heredocs/nowdocs yet.
return [];
default:
return [];
}
}//end getWarningList()
}//end class
@@ -0,0 +1,34 @@
<?php
$x = 'My '.'string';
$x = 'My '. 1234;
$x = 'My '.$y.' test';
echo $data['my'.'index'];
echo $data['my'. 4];
echo $data['my'.$x];
echo $data[$x.$y.'My'.'String'];
$code = '$actions = array();'."\n";
$code = "$actions = array();"."\n";
// No errors for these because they are needed in some cases.
$code = ' ?'.'>';
$code = '<'.'?php ';
$string = 'This is a really long string. '
. 'It is being used for errors. '
. 'The message is not translated.';
$shouldBail = 1 + 1;
$shouldNotTrigger = 'My' . /* comment */ 'string';
$shouldNotTrigger = 'My' /* comment */ . 'string';
// phpcs:set Generic.Strings.UnnecessaryStringConcat allowMultiline true
$string = 'Multiline strings are allowed '
. 'when setting is enabled.';
// phpcs:set Generic.Strings.UnnecessaryStringConcat allowMultiline false
// phpcs:set Generic.Strings.UnnecessaryStringConcat error false
$throwWarning = 'My' . 'string';
// phpcs:set Generic.Strings.UnnecessaryStringConcat error true
@@ -0,0 +1,7 @@
<?php
// Intentional parse error (only empty tokens after T_STRING_CONCAT).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
$parseError = 'String' .
@@ -0,0 +1,13 @@
<?php
$heredoc = <<<"END"
a
b
c
END;
$nowdoc = <<<'END'
a
b
c
END;
@@ -0,0 +1,25 @@
<?php
$heredoc = <<<EOD
some text
EOD;
$nowdoc = <<<'EOD'
some text
EOD;
$heredoc = <<< END
some text
END;
$nowdoc = <<< 'END'
some text
END;
$heredoc = <<< "END"
some text
END;
$nowdoc = <<< 'END'
some text
END;
@@ -0,0 +1,25 @@
<?php
$heredoc = <<<EOD
some text
EOD;
$nowdoc = <<<'EOD'
some text
EOD;
$heredoc = <<<END
some text
END;
$nowdoc = <<<'END'
some text
END;
$heredoc = <<<"END"
some text
END;
$nowdoc = <<<'END'
some text
END;
@@ -0,0 +1,58 @@
<?php
/**
* Unit test class for the HereNowdocIdentifierSpacing sniff.
*
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
* @copyright 2024 PHPCSStandards and contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Standards\Generic\Tests\WhiteSpace;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
/**
* Unit test class for the HereNowdocIdentifierSpacing sniff.
*
* @covers \PHP_CodeSniffer\Standards\Generic\Sniffs\WhiteSpace\HereNowdocIdentifierSpacingSniff
*/
final class HereNowdocIdentifierSpacingUnitTest extends AbstractSniffUnitTest
{
/**
* Returns the lines where errors should occur.
*
* The key of the array should represent the line number and the value
* should represent the number of errors that should occur on that line.
*
* @return array<int, int>
*/
public function getErrorList()
{
return [
11 => 1,
15 => 1,
19 => 1,
23 => 1,
];
}//end getErrorList()
/**
* Returns the lines where warnings should occur.
*
* The key of the array should represent the line number and the value
* should represent the number of warnings that should occur on that line.
*
* @return array<int, int>
*/
public function getWarningList()
{
return [];
}//end getWarningList()
}//end class
@@ -0,0 +1,78 @@
<?php
function foo( &...$spread ) {
bar( ...$spread );
bar(
[ ...$foo ],
...array_values($keyedArray)
);
}
function bar( & ... $spread ) {
bar(...
$spread
);
bar(
[... $foo ],.../*comment*/array_values($keyedArray)
);
}
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter ignoreNewlines true
bar(...
$spread
);
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter ignoreNewlines false
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter spacing 1
function foo( &... $spread ) {
bar( ... $spread );
bar(
[ ... $foo ],
... array_values($keyedArray)
);
}
function bar( & ...$spread ) {
bar(...
$spread
);
bar(
[... $foo ],.../*comment*/array_values($keyedArray)
);
}
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter spacing 2
function foo( &... $spread ) {
bar( ... $spread );
bar(
[ ... $foo ],
... array_values($keyedArray)
);
}
function bar( & ... $spread ) {
bar(...
$spread
);
bar(
[... $foo ],.../*comment*/array_values($keyedArray)
);
}
// Ignore PHP 8.1 first class callable declarations.
$map = array_map(strtolower(...), $map);
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter spacing 0
// Ignore PHP 8.1 first class callable declarations.
$map = array_map(strtolower( ... ), $map);
bar(... /*comment*/$array);
@@ -0,0 +1,73 @@
<?php
function foo( &...$spread ) {
bar( ...$spread );
bar(
[ ...$foo ],
...array_values($keyedArray)
);
}
function bar( & ...$spread ) {
bar(...$spread
);
bar(
[...$foo ],.../*comment*/array_values($keyedArray)
);
}
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter ignoreNewlines true
bar(...
$spread
);
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter ignoreNewlines false
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter spacing 1
function foo( &... $spread ) {
bar( ... $spread );
bar(
[ ... $foo ],
... array_values($keyedArray)
);
}
function bar( & ... $spread ) {
bar(... $spread
);
bar(
[... $foo ],.../*comment*/array_values($keyedArray)
);
}
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter spacing 2
function foo( &... $spread ) {
bar( ... $spread );
bar(
[ ... $foo ],
... array_values($keyedArray)
);
}
function bar( & ... $spread ) {
bar(... $spread
);
bar(
[... $foo ],.../*comment*/array_values($keyedArray)
);
}
// Ignore PHP 8.1 first class callable declarations.
$map = array_map(strtolower(...), $map);
// phpcs:set Generic.WhiteSpace.SpreadOperatorSpacingAfter spacing 0
// Ignore PHP 8.1 first class callable declarations.
$map = array_map(strtolower( ... ), $map);
bar(... /*comment*/$array);
@@ -0,0 +1,4 @@
<?php
// Intentional parse error. Testing that the sniff is *not* triggered in this case.
function bar( ...
@@ -0,0 +1,490 @@
<?php
function someFunctionWithAVeryLongName($firstParameter='something',
$secondParameter='booooo', $third=null, $fourthParameter=false,
$fifthParameter=123.12, $sixthParam=true
){
}
function someFunctionWithAVeryLongName2($firstParameter='something',
$secondParameter='booooo', $third=null, $fourthParameter=false,
$fifthParameter=123.12, $sixthParam=true
) {
}
function blah() {
}
function blah()
{
}
abstract class MyClass
{
public function someFunctionWithAVeryLongName($firstParameter='something',
$secondParameter='booooo', $third=null, $fourthParameter=false,
$fifthParameter=123.12, $sixthParam=true
) /** w00t */ {
}
public function someFunctionWithAVeryLongName2(
$firstParameter='something', $secondParameter='booooo', $third=null
) {
}
protected abstract function processTokenWithinScope(
PHP_CodeSniffer_File $phpcsFile,
$stackPtr,
$currScope
);
protected abstract function processToken(
PHP_CodeSniffer_File $phpcsFile,
$stackPtr,
$currScope);
}
function getInstalledStandards(
$includeGeneric=false,
$standardsDir=''
)
{
}
function &testFunction($arg1,
$arg2,
) {
}
function testFunction($arg1,
$arg2) {
}
function validateUrl(
$url,
$requireScheme=TRUE,
array $allowedSchemes=array(
'http',
'https',
),
array $notAllowedSchemes=array('ftp', 'sftp')
) {
}
function validateUrlShort(
$url,
$requireScheme=TRUE,
array $allowedSchemes=[
'http',
'https',
],
array $notAllowedSchemes=['ftp', 'sftp']
) {
}
$noArgs_longVars = function () use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_longVars = function (
$longArgument,
$muchLongerArgument)use(
$muchLongerVar3) {
// body
};
function test()
{
$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
}
function
myFunction()
{
}
function
myFunction()
{
}
use function foo\bar;
use
function bar\baz;
namespace {
use function Name\Space\f;
f();
}
$var = function() {return true;};
$var = function() {return true;
};
function blah(){return true;
}
$closureWithArgsAndVars = function($arg1, $arg2) use ($var1, $var2){
// body
};
function
blah
()
{
// body
}
$b = function &() {
echo "hello";
};
function foo(
$param1,
$param2,
$param3
) : SomeClass {
}
function foo(
$param1,
$param2,
$param3
): SomeClass {
}
function foo(
$param1,
$param2,
$param3
): SomeClass // Comment here
{
}
function foo(
$param1,
$param2,
$param3
) : SomeClass {
}
function foo(
$var
)
{
// body
}
function foo(
$var
)
/* hello */ {
// body
}
function foo(
$var
)
{ echo 'hi';
// body
}
function foo(
$var
)
/* hello */ { echo 'hi';
// body
}
$a = function () {
function foo ()
{}
abstract class Foo {
function bar ()
{
}
abstract function baz () ;
abstract function qux () : void ;
}
interface Foo {
function bar () ;
function baz (
$longArgument,
$longerArgument,
$muchLongerArgument
) ;
function qux (
$longArgument,
$longerArgument,
$muchLongerArgument
) : void ;
}
trait Foo {
function bar ()
{
}
abstract function baz ()
;
}
if(true) {
abstract class Foo {
function bar ()
{
}
abstract function baz () ;
abstract function qux () : void ;
}
interface Foo {
function bar () ;
function baz (
$longArgument,
$longerArgument,
$muchLongerArgument
) ;
function qux (
$longArgument,
$longerArgument,
$muchLongerArgument
) : void ;
}
trait Foo {
function bar ()
{
}
abstract function baz ()
;
}
}
class ConstructorPropertyPromotionSingleLineDocblockIndentOK
{
public function __construct(
/** @var string */
public string $public,
/** @var string */
private string $private,
) {
}
}
class ConstructorPropertyPromotionMultiLineDocblockAndAttributeIndentOK
{
public function __construct(
/**
* @var string
* @Assert\NotBlank()
*/
public string $public,
/**
* @var string
* @Assert\NotBlank()
*/
#[NotBlank]
private string $private,
) {
}
}
class ConstructorPropertyPromotionSingleLineDocblockIncorrectIndent
{
public function __construct(
/** @var string */
public string $public,
/** @var string */
private string $private,
) {
}
}
class ConstructorPropertyPromotionMultiLineDocblockAndAttributeIncorrectIndent
{
public function __construct(
/**
* @var string
* @Assert\NotBlank()
*/
public string $public,
/**
* @var string
* @Assert\NotBlank()
*/
#[NotBlank]
private string $private,
) {
}
}
class ConstructorPropertyPromotionMultiLineAttributesOK
{
public function __construct(
#[ORM\ManyToOne(
Something: true,
SomethingElse: 'text',
)]
#[Groups([
'ArrayEntry',
'Another.ArrayEntry',
])]
#[MoreGroups(
[
'ArrayEntry',
'Another.ArrayEntry',
]
)]
private Type $property
) {
// Do something.
}
}
class ConstructorPropertyPromotionMultiLineAttributesIncorrectIndent
{
public function __construct(
#[ORM\ManyToOne(
Something: true,
SomethingElse: 'text',
)]
#[Groups([
'ArrayEntry',
'Another.ArrayEntry',
])]
#[MoreGroups(
[
'ArrayEntry',
'Another.ArrayEntry',
]
)]
private Type $property
) {
// Do something.
}
}
// PHP 8.1: new in initializers means that class instantiations with parameters can occur in a function declaration.
function usingNewInInitializersCallParamsIndented(
int $paramA,
string $paramB,
object $paramC = new SomeClass(
new InjectedDependencyA(),
new InjectedDependencyB
)
) {}
function usingNewInInitializersCallParamsNotIndented(
int $paramA,
string $paramB,
object $paramC = new SomeClass(
new InjectedDependencyA,
new InjectedDependencyB()
)
) {}
function usingNewInInitializersCallParamsIncorrectlyIndentedShouldNotBeFlaggedNorFixed(
int $paramA,
string $paramB,
object $paramC = new SomeClass(
new InjectedDependencyA(), new InjectedDependencyB()
)
) {}
class UsingNewInInitializers {
public function doSomething(
object $paramA,
stdClass $paramB = new stdClass(),
Exception $paramC = new Exception(
new ExceptionMessage(),
new ExceptionCode(),
),
) {
}
public function callParamsIncorrectlyIndentedShouldNotBeFlaggedNorFixed(
Exception $param = new Exception(
new ExceptionMessage(),
new ExceptionCode(),
),
) {
}
}
// Issue #3736 - prevent the fixer creating a parse error by removing the function close brace.
class Test
{
public function __construct(
protected int $id
)
{}
}
// Prevent fixer conflict with itself.
function foo(
$param1,
)
: \SomeClass
{
}
function foo(
$param1,
$param2
) : // comment.
\Package\Sub\SomeClass {}
@@ -0,0 +1,487 @@
<?php
function someFunctionWithAVeryLongName($firstParameter='something',
$secondParameter='booooo', $third=null, $fourthParameter=false,
$fifthParameter=123.12, $sixthParam=true
) {
}
function someFunctionWithAVeryLongName2($firstParameter='something',
$secondParameter='booooo', $third=null, $fourthParameter=false,
$fifthParameter=123.12, $sixthParam=true
) {
}
function blah()
{
}
function blah()
{
}
abstract class MyClass
{
public function someFunctionWithAVeryLongName($firstParameter='something',
$secondParameter='booooo', $third=null, $fourthParameter=false,
$fifthParameter=123.12, $sixthParam=true
) /** w00t */ {
}
public function someFunctionWithAVeryLongName2(
$firstParameter='something', $secondParameter='booooo', $third=null
) {
}
protected abstract function processTokenWithinScope(
PHP_CodeSniffer_File $phpcsFile,
$stackPtr,
$currScope
);
protected abstract function processToken(
PHP_CodeSniffer_File $phpcsFile,
$stackPtr,
$currScope
);
}
function getInstalledStandards(
$includeGeneric=false,
$standardsDir=''
) {
}
function &testFunction($arg1,
$arg2,
) {
}
function testFunction($arg1,
$arg2
) {
}
function validateUrl(
$url,
$requireScheme=TRUE,
array $allowedSchemes=array(
'http',
'https',
),
array $notAllowedSchemes=array('ftp', 'sftp')
) {
}
function validateUrlShort(
$url,
$requireScheme=TRUE,
array $allowedSchemes=[
'http',
'https',
],
array $notAllowedSchemes=['ftp', 'sftp']
) {
}
$noArgs_longVars = function () use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_longVars = function (
$longArgument,
$muchLongerArgument
) use (
$muchLongerVar3
) {
// body
};
function test()
{
$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
}
function myFunction()
{
}
function myFunction()
{
}
use function foo\bar;
use
function bar\baz;
namespace {
use function Name\Space\f;
f();
}
$var = function () {
return true;};
$var = function () {
return true;
};
function blah()
{
return true;
}
$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
// body
};
function blah()
{
// body
}
$b = function &() {
echo "hello";
};
function foo(
$param1,
$param2,
$param3
) : SomeClass {
}
function foo(
$param1,
$param2,
$param3
): SomeClass {
}
function foo(
$param1,
$param2,
$param3
): SomeClass { // Comment here
}
function foo(
$param1,
$param2,
$param3
) : SomeClass {
}
function foo(
$var
) {
// body
}
function foo(
$var
) {
/* hello */
// body
}
function foo(
$var
) {
echo 'hi';
// body
}
function foo(
$var
) {
/* hello */ echo 'hi';
// body
}
$a = function () {
function foo()
{}
abstract class Foo {
function bar()
{
}
abstract function baz();
abstract function qux() : void;
}
interface Foo {
function bar();
function baz(
$longArgument,
$longerArgument,
$muchLongerArgument
);
function qux(
$longArgument,
$longerArgument,
$muchLongerArgument
) : void;
}
trait Foo {
function bar()
{
}
abstract function baz();
}
if(true) {
abstract class Foo {
function bar()
{
}
abstract function baz();
abstract function qux() : void;
}
interface Foo {
function bar();
function baz(
$longArgument,
$longerArgument,
$muchLongerArgument
);
function qux(
$longArgument,
$longerArgument,
$muchLongerArgument
) : void;
}
trait Foo {
function bar()
{
}
abstract function baz();
}
}
class ConstructorPropertyPromotionSingleLineDocblockIndentOK
{
public function __construct(
/** @var string */
public string $public,
/** @var string */
private string $private,
) {
}
}
class ConstructorPropertyPromotionMultiLineDocblockAndAttributeIndentOK
{
public function __construct(
/**
* @var string
* @Assert\NotBlank()
*/
public string $public,
/**
* @var string
* @Assert\NotBlank()
*/
#[NotBlank]
private string $private,
) {
}
}
class ConstructorPropertyPromotionSingleLineDocblockIncorrectIndent
{
public function __construct(
/** @var string */
public string $public,
/** @var string */
private string $private,
) {
}
}
class ConstructorPropertyPromotionMultiLineDocblockAndAttributeIncorrectIndent
{
public function __construct(
/**
* @var string
* @Assert\NotBlank()
*/
public string $public,
/**
* @var string
* @Assert\NotBlank()
*/
#[NotBlank]
private string $private,
) {
}
}
class ConstructorPropertyPromotionMultiLineAttributesOK
{
public function __construct(
#[ORM\ManyToOne(
Something: true,
SomethingElse: 'text',
)]
#[Groups([
'ArrayEntry',
'Another.ArrayEntry',
])]
#[MoreGroups(
[
'ArrayEntry',
'Another.ArrayEntry',
]
)]
private Type $property
) {
// Do something.
}
}
class ConstructorPropertyPromotionMultiLineAttributesIncorrectIndent
{
public function __construct(
#[ORM\ManyToOne(
Something: true,
SomethingElse: 'text',
)]
#[Groups([
'ArrayEntry',
'Another.ArrayEntry',
])]
#[MoreGroups(
[
'ArrayEntry',
'Another.ArrayEntry',
]
)]
private Type $property
) {
// Do something.
}
}
// PHP 8.1: new in initializers means that class instantiations with parameters can occur in a function declaration.
function usingNewInInitializersCallParamsIndented(
int $paramA,
string $paramB,
object $paramC = new SomeClass(
new InjectedDependencyA(),
new InjectedDependencyB
)
) {}
function usingNewInInitializersCallParamsNotIndented(
int $paramA,
string $paramB,
object $paramC = new SomeClass(
new InjectedDependencyA,
new InjectedDependencyB()
)
) {}
function usingNewInInitializersCallParamsIncorrectlyIndentedShouldNotBeFlaggedNorFixed(
int $paramA,
string $paramB,
object $paramC = new SomeClass(
new InjectedDependencyA(), new InjectedDependencyB()
)
) {}
class UsingNewInInitializers {
public function doSomething(
object $paramA,
stdClass $paramB = new stdClass(),
Exception $paramC = new Exception(
new ExceptionMessage(),
new ExceptionCode(),
),
) {
}
public function callParamsIncorrectlyIndentedShouldNotBeFlaggedNorFixed(
Exception $param = new Exception(
new ExceptionMessage(),
new ExceptionCode(),
),
) {
}
}
// Issue #3736 - prevent the fixer creating a parse error by removing the function close brace.
class Test
{
public function __construct(
protected int $id
) {
}
}
// Prevent fixer conflict with itself.
function foo(
$param1,
)
: \SomeClass {
}
function foo(
$param1,
$param2
) : // comment.
\Package\Sub\SomeClass {}
@@ -0,0 +1,7 @@
<?php
// Intentional parse error/live coding test.
// This must be the only test in this file.
// Safeguarding that the sniff does not throw a PHP notice for this test.
function liveCoding()
@@ -0,0 +1,116 @@
<?php
// No args.
function myFunction()
{
}
// No default args.
function myFunction($arg1)
{
}
// Valid
function myFunction($arg1, $arg2='hello')
{
}
// Valid with lots of args
function myFunction($arg1, $arg2, $arg3, $arg4='hello', $arg5=array(), $arg6='hello')
{
}
// Valid type hints
function myFunction(array $arg1, array $arg2=array())
{
}
// Invalid
function myFunction($arg2='hello', $arg1)
{
}
// Invalid with lots of args
function myFunction($arg1, $arg2, $arg3, $arg4='hello', $arg5, $arg6='hello')
{
}
// Invalid type hints
function myFunction(array $arg2=array(), array $arg1)
{
}
class myClass
{
// No args.
function myFunction()
{
}
// No default args.
function myFunction($arg1)
{
}
// Valid
function myFunction($arg1, $arg2='hello')
{
}
// Valid with lots of args
function myFunction($arg1, $arg2, $arg3, $arg4='hello', $arg5=array(), $arg6='hello')
{
}
// Valid type hints
function myFunction(array $arg1, array $arg2=array())
{
}
// Invalid
function myFunction($arg2='hello', $arg1)
{
}
// Invalid with lots of args
function myFunction($arg1, $arg2, $arg3, $arg4='hello', $arg5, $arg6='hello')
{
}
// Invalid type hints
function myFunction(array $arg2=array(), array $arg1)
{
}
}
function myFunc($req, $opt=null, ...$params) {}
// Type hinting with NULL
function foo(Foo $foo = null, $bar) {}
function foo(Foo $foo, $bar) {}
function foo(Foo $foo = null, $bar = true, $baz) {}
function foo($baz, Foo $foo = null, $bar = true) {}
function foo($baz, $bar = true, Foo $foo = null) {}
// Valid closure
$closure = function ($arg1, $arg2='hello') {};
// Invalid closure
$closure = function(array $arg2=array(), array $arg1) {}
$fn = fn($a = [], $b) => $a[] = $b;
class OnlyConstructorPropertyPromotion {
public function __construct(
public string $name = '',
protected $bar
) {}
}
class ConstructorPropertyPromotionMixedWithNormalParams {
public function __construct(
public string $name = '',
?int $optionalParam = 0,
mixed $requiredParam,
) {}
}
@@ -0,0 +1,7 @@
<?php
// Intentional syntax error.
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.
function
@@ -0,0 +1,314 @@
<?php
class Test
{
function __construct()
{
$this->hello(); // error here
}
function hello() // error here
{ // no error here as brackets can be put anywhere in the pear standard
echo 'hello';
}
function hello2()
{
if (TRUE) { // error here
echo 'hello'; // no error here as its more than 4 spaces.
} else {
echo 'bye'; // error here
}
while (TRUE) {
echo 'hello'; // error here
}
do { // error here
echo 'hello'; // error here
} while (TRUE);
}
function hello3()
{
switch ($hello) {
case 'hello':
break;
}
}
}
?>
<pre>
</head>
<body>
<?php
if ($form->validate()) {
$safe = $form->getSubmitValues();
}
?>
</pre>
<?php
class Test2
{
function __construct()
{
// $this->open(); // error here
}
public function open()
{
// Some inline stuff that shouldn't error
if (TRUE) echo 'hello';
foreach ($tokens as $token) echo $token;
}
/**
* This is a comment 1.
* This is a comment 2.
* This is a comment 3.
* This is a comment 4.
*/
public function close()
{
// All ok.
if (TRUE) {
if (TRUE) {
} else if (FALSE) {
foreach ($tokens as $token) {
switch ($token) {
case '1':
case '2':
if (true) {
if (false) {
if (false) {
if (false) {
echo 'hello';
}
}
}
}
break;
case '5':
break;
}
do {
while (true) {
foreach ($tokens as $token) {
for ($i = 0; $i < $token; $i++) {
echo 'hello';
}
}
}
} while (true);
}
}
}
}
/*
This is another c style comment 1.
This is another c style comment 2.
This is another c style comment 3.
This is another c style comment 4.
This is another c style comment 5.
*/
/*
*
*
*
*/
/**
*/
/*
This comment has a newline in it.
*/
public function read()
{
echo 'hello';
// no errors below.
$array = array(
'this',
'that' => array(
'hello',
'hello again' => array(
'hello',
),
),
);
}
}
abstract class Test3
{
public function parse()
{
foreach ($t as $ndx => $token) {
if (is_array($token)) {
echo 'here';
} else {
$ts[] = array("token" => $token, "value" => '');
$last = count($ts) - 1;
switch ($token) {
case '(':
if ($last >= 3 &&
$ts[0]['token'] != T_CLASS &&
$ts[$last - 2]['token'] == T_OBJECT_OPERATOR &&
$ts[$last - 3]['token'] == T_VARIABLE ) {
if (true) {
echo 'hello';
}
}
array_push($braces, $token);
break;
}
}
}
}
}
function test()
{
$o = <<<EOF
this is some text
this is some text
this is some text
this is some text
this is some text
this is some text
EOF;
return $o;
}
if ($a === true || $a === true || $a === true || $a === true ||
$a === true || $a === true || $a === true || $a === true) {
echo 'hello';
}
if ($true) {
/* First comment line
*
* Comment test here
* Comment test here
*
*/
/* First comment line
*
* Comment test here
* Comment test here
*
this si something */
}
function test()
{
/* taken from http://de3.php.net/manual/en/reserved.php */
# $m[] = 'declare';
/* taken from http://de3.php.net/manual/en/reserved.php */
# $m[] = 'declare';
}
foreach ($elements as $element) {
if ($something) {
// Do IF.
} else if ($somethingElse) {
// Do ELSE.
}
}
if ($condition) {
echo "This is a long
string that spans $numLines lines
without indenting.
";
}
if ($condition) {
echo 'This is a long
string that spans multiple lines
with indenting.
';
}
if ($condition) {
echo 'This is a long
string that spans multiple lines
with indenting.';
}
switch ($foo) {
case 1:
switch ($bar) {
default:
echo $string{1};
}
break;
}
function temp($foo, $bar) {
switch ($foo) {
case 1:
switch ($bar) {
default:
return $foo;
}
break;
}
}
switch ($foo) {
case 1:
switch ($bar) {
default:
if ($something) {
echo $string{1};
} else if ($else) {
switch ($else) {
default:
}
}
}
break;
}
switch ($name) {
case "1":
case "2":
case "3":
return true;
}
switch ($name) {
case "1":
case "2":
case "3":
default :
return true;
}
// Don't check the first token in the closure.
$array = array();
array_map(
function($x)
{
return trim($x);
},
$array
);
@@ -0,0 +1,79 @@
<?php
if ($a ===$b) {
$foo = $bar ??$a?? $b;
} elseif ($a> $b) {
$variable =$foo ? 'foo' :'bar';
$variable.='text'.'text';
}
$foo+= $a&$b;
$foo = $a|$b;
$foo =$a^$b;
$foo = ~$a;
$foo *=$a<<$b;
$foo = $a>>$b;
function foo(&$a,& $b) {}
$foo = $a and$b;
$foo = $a or $b;
$foo = $a xor$b;
$foo = !$a;
$foo = $a&&$b;
$foo = $a||$b;
$foo = $a instanceof Foo;
$foo = $a instanceof$b;
$foo .= 'hi'
.= 'there';
$foo .= 'hi'
.= 'there';
$foo .= 'hi' // comment
.= 'there';
$foo/*comment*/=/*comment*/$a/*comment*/and/*comment*/$b;
$foo .=//comment
'string' .=/*comment*/
'string';
$foo = $foo ?: 'bar';
$foo = $foo?:'bar';
try {
} catch (ExceptionType1|ExceptionType2 $e) {
}
if (strpos($tokenContent, 'b"') === 0 && substr($tokenContent, -1) === '"') {}
$oldConstructorPos = +1;
return -$content;
function name($a = -1) {}
$a =& $ref;
$a = [ 'a' => &$something ];
$fn = fn(array &$one) => 1;
$fn = fn(array & $one) => 1;
$fn = static fn(DateTime $a, DateTime $b): int => -($a->getTimestamp() <=> $b->getTimestamp());
function issue3267(string|int ...$values) {}
function setDefault(#[ImportValue(
constraints: [
[
Assert\Type::class,
['type' => 'bool'],
],
]
)] ?bool $value = null): void
{
// Do something
}
declare(strict_types=1);

Some files were not shown because too many files have changed in this diff Show More