Skip to content

Instantly share code, notes, and snippets.

@adamzero1
Created August 2, 2023 07:57
Show Gist options
  • Save adamzero1/835bf6a5dfcd1c68156edd04ea5a241a to your computer and use it in GitHub Desktop.
Save adamzero1/835bf6a5dfcd1c68156edd04ea5a241a to your computer and use it in GitHub Desktop.
Custom code sniff to check second argument passed to print_r

Disallow print_r direct output

Description

This code sniff will error when print_r is detected and is outputting directly.

<?php

print_r(
    $this->toArray(),
    true
);
print_r($this->toArray());
print_r('aaaaaa');
print_r('aaaaa', false);
print_r([], true);
$object->print_r($aaaa);

Will product the following output

----------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 3 LINES
----------------------------------------------------------------------
 7 | ERROR | Using "print_r" is prohibited
 8 | ERROR | Using "print_r" is prohibited
 9 | ERROR | Using "print_r" is prohibited
----------------------------------------------------------------------
<?php
namespace PHP_CodeSniffer\Standards\Mdoq\Sniffs\Functions;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Files\File;
class DisallowPrintRSniff implements Sniff
{
public const METHOD_NAME = 'print_r';
/**
* Returns the token types that this sniff is interested in.
* see vendor/squizlabs/php_codesniffer/src/Util/Tokens.php
* @return array(int)
*/
public function register()
{
return [
T_STRING,
];
}
/**
* Processes this sniff, when one of its tokens is encountered.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The current file being checked.
* @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 ($tokens[$stackPtr]['content'] == self::METHOD_NAME
&& !$this->isObjectMethodCall($tokens, $stackPtr)
&& !$this->outputIsReturned($tokens, $stackPtr)
) {
$error = 'Using "'.self::METHOD_NAME.'" is prohibited';
$data = array(trim($tokens[$stackPtr]['content']));
$phpcsFile->addError($error, $stackPtr, 'Found', $data);
}
}
/**
* return true if $this->print_r(blaha)
* or $object->print_r(foooo)
*/
protected function isObjectMethodCall($tokens, $ptr)
{
return isset($tokens[($ptr - 1)]) && $tokens[($ptr - 1)]['code'] == T_OBJECT_OPERATOR;
}
/**
* return true, if the second argument is true
*/
protected function outputIsReturned($tokens, $ptr)
{
$arguments = $this->getArgruments($tokens, $ptr);
return isset($arguments[1], $arguments[1][0])
&& $arguments[1][0]['code'] == T_TRUE;
}
protected function getArgruments($tokens, $ptr)
{
$depth = 0;
$arguments = [];
$argumentIndex = 0;
for($x = $ptr; $x < count($tokens); $x++){
if($depth === 0){
if($tokens[$x]['code'] == T_OPEN_PARENTHESIS){
$depth++;
$arguments[$argumentIndex] = [];
}
}elseif($depth == 1){
switch($tokens[$x]['code']){
case T_COMMA:
$argumentIndex++;
break;
case T_WHITESPACE:
break;
case T_CLOSE_PARENTHESIS:
$depth--;
break 2;
case T_OPEN_PARENTHESIS:
$depth++;
default:
$arguments[$argumentIndex][] = $tokens[$x];
}
}else{
switch($tokens[$x]['code']){
case T_WHITESPACE:
break;
case T_OPEN_PARENTHESIS:
$depth++;
case T_CLOSE_PARENTHESIS:
$depth--;
default:
$arguments[$argumentIndex][] = $tokens[$x];
}
}
}
return $arguments;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment