Source for file CallTimePassByReferenceSniff.php
Documentation is available at CallTimePassByReferenceSniff.php
* Ensures that variables are not passed by reference when calling a function.
* @author Florian Grandel <jerico.dev@gmail.com>
* @copyright 2009-2014 Florian Grandel
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
namespace PHP_CodeSniffer\Standards\Generic\Sniffs\Functions;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Util\Tokens;
class CallTimePassByReferenceSniff implements Sniff
* Returns an array of tokens this test wants to listen for.
public function 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.
public function process (File $phpcsFile, $stackPtr)
$tokens = $phpcsFile->getTokens ();
$prev = $phpcsFile->findPrevious ($findTokens, ($stackPtr - 1 ), null , true );
// Skip tokens that are the names of functions or classes
// within their definitions. For example: function myFunction...
// "myFunction" is T_STRING but we should skip because it is not a
// function or method *call*.
$prevCode = $tokens[$prev]['code'];
if ($prevCode === T_FUNCTION || $prevCode === T_CLASS ) {
// If the next non-whitespace token after the function or method call
// is not an opening parenthesis then it cant really be a *call*.
$functionName = $stackPtr;
$openBracket = $phpcsFile->findNext (
if (isset ($tokens[$openBracket]['parenthesis_closer']) === false ) {
$closeBracket = $tokens[$openBracket]['parenthesis_closer'];
$nextSeparator = $openBracket;
while (($nextSeparator = $phpcsFile->findNext ($find, ($nextSeparator + 1 ), $closeBracket)) !== false ) {
if (isset ($tokens[$nextSeparator]['nested_parenthesis']) === false ) {
$nextSeparator = $tokens[$nextSeparator]['bracket_closer'];
// Make sure the variable belongs directly to this function call
// and is not inside a nested function call or array.
$brackets = $tokens[$nextSeparator]['nested_parenthesis'];
if ($lastBracket !== $closeBracket) {
// Checking this: $value = my_function(...[*]$arg...).
$tokenBefore = $phpcsFile->findPrevious (
// Checking this: $value = my_function(...[*]&$arg...).
$tokenBefore = $phpcsFile->findPrevious (
// We have to exclude all uses of T_BITWISE_AND that are not
// references. We use a blacklist approach as we prefer false
// positives to not identifying a pass-by-reference call at all.
$tokenCode = $tokens[$tokenBefore]['code'];
if ($tokenCode === T_VARIABLE
|| $tokenCode === T_LNUMBER
|| isset (Tokens ::$assignmentTokens[$tokenCode]) === true
// T_BITWISE_AND represents a pass-by-reference.
$error = 'Call-time pass-by-reference calls are prohibited';
$phpcsFile->addError ($error, $tokenBefore, 'NotAllowed');
Documentation generated on Mon, 11 Mar 2019 15:27:16 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|