-
-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ PHP 7.4: New NewPHPOpenTagEOF sniff
> `<?php` at the end of the file (without trailing newline) will now be interpreted as an opening PHP tag. > Previously it was interpreted either as `<? php` and resulted in a syntax error (with short_open_tag=1) or was interpreted as a literal `<?php` string (with short_open_tag=0). Refs: * https://github.com/php/php-src/blob/30de357fa14480468132bbc22a272aeb91789ba8/UPGRADING#L37-L40 * php/php-src@c9acc90#diff-7748eb3bfdd3bf962553f6f9f2723c45 ## Implementation notes: This sniff will not work on PHP 5.3 in combination with PHPCS < 2.6.0 with `short_open_tag=On` due to a tokenizer bug in PHPCS itself in those older versions. Related: 835 The sniff needs different code to detect the issue depending on whether or not `short_open_tag`s is enabled on the system running the sniffs. By default, the Travis images have `short_open_tag=Off`. To make sure that both situations are unit tested, two of the existing builds will now change the PHP ini config of the Travis image to ensure that the sniff is also tested with `short_open_tag=On`.
- Loading branch information
Showing
10 changed files
with
422 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
PHPCompatibility/Sniffs/Miscellaneous/NewPHPOpenTagEOFSniff.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
<?php | ||
/** | ||
* PHPCompatibility, an external standard for PHP_CodeSniffer. | ||
* | ||
* @package PHPCompatibility | ||
* @copyright 2012-2019 PHPCompatibility Contributors | ||
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3 | ||
* @link https://github.com/PHPCompatibility/PHPCompatibility | ||
*/ | ||
|
||
namespace PHPCompatibility\Sniffs\Miscellaneous; | ||
|
||
use PHPCompatibility\Sniff; | ||
use PHP_CodeSniffer_File as File; | ||
|
||
/** | ||
* PHP 7.4 now supports stand-alone PHP tags at the end of a file (without new line). | ||
* | ||
* > `<?php` at the end of the file (without trailing newline) will now be | ||
* > interpreted as an opening PHP tag. Previously it was interpreted either as | ||
* > `<? php` and resulted in a syntax error (with short_open_tag=1) or was | ||
* > interpreted as a literal `<?php` string (with short_open_tag=0). | ||
* | ||
* @internal Due to an issue with the Tokenizer, this sniff will not work correctly | ||
* on PHP 5.3 in combination with PHPCS < 2.6.0 when short_open_tag is `On`. | ||
* As this is causing "Undefined offset" notices, there is nothing we can | ||
* do to work-around this. | ||
* | ||
* @link https://github.com/php/php-src/blob/30de357fa14480468132bbc22a272aeb91789ba8/UPGRADING#L37-L40 | ||
* | ||
* PHP version 7.4 | ||
* | ||
* @since 9.2.0 | ||
*/ | ||
class NewPHPOpenTagEOFSniff extends Sniff | ||
{ | ||
|
||
/** | ||
* Whether or not short open tags is enabled on the install running the sniffs. | ||
* | ||
* @var bool | ||
*/ | ||
protected $shortOpenTags; | ||
|
||
|
||
/** | ||
* Returns an array of tokens this test wants to listen for. | ||
* | ||
* @return array | ||
*/ | ||
public function register() | ||
{ | ||
$targets = array( | ||
\T_OPEN_TAG_WITH_ECHO, | ||
); | ||
|
||
$this->shortOpenTags = (bool) ini_get('short_open_tag'); | ||
if ($this->shortOpenTags === false) { | ||
$targets[] = \T_INLINE_HTML; | ||
} else { | ||
$targets[] = \T_STRING; | ||
} | ||
|
||
if (version_compare(\PHP_VERSION_ID, '70399', '>')) { | ||
$targets[] = \T_OPEN_TAG; | ||
} | ||
|
||
return $targets; | ||
} | ||
|
||
|
||
/** | ||
* Processes this test, when one of its tokens is encountered. | ||
* | ||
* @param \PHP_CodeSniffer_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) | ||
{ | ||
if ($this->supportsBelow('7.3') === false) { | ||
return; | ||
} | ||
|
||
if ($stackPtr !== ($phpcsFile->numTokens - 1)) { | ||
// We're only interested in the last token in the file. | ||
return; | ||
} | ||
|
||
$tokens = $phpcsFile->getTokens(); | ||
$contents = $tokens[$stackPtr]['content']; | ||
$error = false; | ||
|
||
switch ($tokens[$stackPtr]['code']) { | ||
case \T_INLINE_HTML: | ||
// PHP < 7.4 with short open tags off. | ||
if ($contents === '<?php') { | ||
$error = true; | ||
} elseif ($contents === '<?=') { | ||
// Also cover short open echo tags in PHP 5.3 with short open tags off. | ||
$error = true; | ||
} | ||
break; | ||
|
||
case \T_STRING: | ||
// PHP < 7.4 with short open tags on. | ||
if ($contents === 'php' | ||
&& $tokens[($stackPtr - 1)]['code'] === \T_OPEN_TAG | ||
&& $tokens[($stackPtr - 1)]['content'] === '<?' | ||
) { | ||
$error = true; | ||
} | ||
break; | ||
|
||
case \T_OPEN_TAG_WITH_ECHO: | ||
// PHP 5.4+. | ||
if (rtrim($contents) === '<?=') { | ||
$error = true; | ||
} | ||
break; | ||
|
||
case \T_OPEN_TAG: | ||
// PHP 7.4+. | ||
if ($contents === '<?php') { | ||
$error = true; | ||
} | ||
break; | ||
} | ||
|
||
if ($error === true) { | ||
$phpcsFile->addError( | ||
'A PHP open tag at the end of a file, without trailing newline, was not supported in PHP 7.3 or earlier and would result in a syntax error or be interpreted as a literal string', | ||
$stackPtr, | ||
'Found' | ||
); | ||
} | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
PHPCompatibility/Tests/Miscellaneous/NewPHPOpenTagEOFUnitTest.1.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<?php |
6 changes: 6 additions & 0 deletions
6
PHPCompatibility/Tests/Miscellaneous/NewPHPOpenTagEOFUnitTest.2.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?php | ||
|
||
echo 'a'; | ||
?> | ||
|
||
<?php |
6 changes: 6 additions & 0 deletions
6
PHPCompatibility/Tests/Miscellaneous/NewPHPOpenTagEOFUnitTest.3.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?php | ||
|
||
echo 'a'; | ||
?> | ||
|
||
<?= |
1 change: 1 addition & 0 deletions
1
PHPCompatibility/Tests/Miscellaneous/NewPHPOpenTagEOFUnitTest.4.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<?php |
13 changes: 13 additions & 0 deletions
13
PHPCompatibility/Tests/Miscellaneous/NewPHPOpenTagEOFUnitTest.5.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
echo 'a'; | ||
?> | ||
|
||
<div>Some HTML</div> | ||
|
||
<?php | ||
// Some more PHP. | ||
echo 'something else'; | ||
|
||
?> | ||
<?php |
4 changes: 4 additions & 0 deletions
4
PHPCompatibility/Tests/Miscellaneous/NewPHPOpenTagEOFUnitTest.6.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?php | ||
|
||
echo 'a'; | ||
?><?php |
6 changes: 6 additions & 0 deletions
6
PHPCompatibility/Tests/Miscellaneous/NewPHPOpenTagEOFUnitTest.7.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?php | ||
|
||
echo 'a'; | ||
?> | ||
|
||
<?= |
Oops, something went wrong.