tags:

views:

23

answers:

2

I'm looking for a regular expression that will accurately identify any PHP call time pass by references in source code in order to aid migration to PHP 5.3.

Currently, I have [^=&]\s*&\s*\$, but this doesn't filter out assignment cases ($var = &$othervar;).

This regexp should be compatible with eclipse (sorry, not sure what flavor of regexp eclipse parses).

Edit: This one is a little bit closer (although a bit of a hack): (?<!([&=]\s{0,15}))&\s*\$

+1  A: 

You can't get those with regex. Use the Tokenizer instead. You will need to look for '&' where the next '(' to the left (resolve brackets while walking there) is preceded by T_STRING but not by T_FUNCTION.

$tokens = new TokenStream($source);
foreach ($tokens as $i => $token) {
    if ($token->is(T_AMP)) {
        while ($i--) {
            if ($tokens[$i]->is(T_CLOSE_ROUND, T_CLOSE_SQUARE, T_CLOSE_CURLY)) {
                $i = $tokens->complementaryBracket($i);
            } elseif ($tokens[$i]->is(T_OPEN_ROUND)) {
                if ((($tokens[--$i]->is(T_WHITESPACE) && $tokens[--$i]->is(T_STRING))
                     || $tokens[$i]->is(T_STRING))
                    && !$tokens[--$i]->is(T_WHITESPACE)
                    && !$tokens[--$i]->is(T_FUNCTION)
                ) {
                    throw new Exception('Call-time pass by reference');
                }
                break;
            }
        }
    }
}

This utilizes my TokenStream wrapper. With the native output it will get quite a bit harder ;)

nikic
If utilizing negative lookahead assertions, I think it might be possible. If no one can give a reasonable regexp, tokenization just might win :-(
Kenaniah
@ircmaxell: If the `'('` is preceded by `T_STRING` it cannot be preceded by `T_ARRAY` ;)
nikic
@Kenaniah: The problem is that you will need to resolve recursive brackets, strings and loads of other language constructs. This can't be done by regex.
nikic
+3  A: 

You can use phpcs for this. It has a rule to detect Call Time Pass by References:

Ensures that variables are not passed by reference when calling a function.

There is also a plugin to integrate phpcs into Eclipse

Gordon
Thanks for the link, Gordon, but I'm really looking for a regexp. This codebase has literally hundreds of source files.
Kenaniah
+1: A pre-built solution is best... @Kenaniah: `phpcs` is a scanner made to scan literally hundreds of source files and output a report of what it found. So it sounds to me exactly like what you're looking for...
ircmaxell
I'll give it a shot since there's an eclipse plugin for it.
Kenaniah