Reed
Reed

Reputation: 14984

Check if a string is valid PHP code

I want to do:

$str = "<? echo 'abcd'; ?>";
if (is_valid_php($str)){
   echo "{$str} is valid";
} else {
   echo "{$str} is not valid PHP code";
}

Is there a simple way to do the is_valid_php check?

All I can find is online php syntax checkers and command-line ways to check syntax, or php_check_syntax which only works for a file, and I don't want to have to write to a file to check if the string is valid.

I'd rather not use system()/exec() or eval()

Related Question - It's old, so I'm hoping there's something new

Other Related Question - all the options (as far as I could tell) either are no longer supported or use command line or have to check files (not strings)

I don't need a full-fledged compiler or anything. I literally only need to know if the string is valid PHP code.

EDIT: By valid php code, I mean that it can be executed, has no compiler/syntax errors, and should contain only PHP code. It could have runtime errors and still be valid, like $y = 33/0;. And it should contain only PHP... Such as, <div>stuff</div><? echo "str"; ?> would be invalid, but <? echo "str"; ?> and echo "$str"; would be valid

Upvotes: 2

Views: 5689

Answers (3)

dave
dave

Reputation: 64727

You could pipe the string to php -l and call it using shell_exec:

$str1 = "<?php echo 'hello world';";
$str2 = "<?php echo 'hello world'";
echo isValidPHP($str1) ? "Valid" : "Invalid"; //Valid
echo isValidPHP($str2) ? "Valid" : "Invalid"; //Inalid

function isValidPHP($str) {
    return trim(shell_exec("echo " . escapeshellarg($str) . " | php -l")) == "No syntax errors detected in -";
}

Just had another idea... this time using eval but safely:

test_code.php

$code = "return; " . $_GET['code'];
//eval is safe here because it won't do anything
//since the first thing we do is return
//but we still get parse errors if it's not valid
//If that happens, it will crash the whole script, 
//so we need it to be in a separate request
eval($code); 
return "1";

elsewhere in your code:

echo isValidPHP("<?php echo \"It works!\";");

function isValidPHP($code) {
    $valid = file_get_contents("http://www.yoursite.com/test_code.php?" . http_build_query(['code' => $code]));
    return !!$valid;
}

Upvotes: 7

miken32
miken32

Reputation: 42753

Off the top of my head, this is easiest.

$str = "<? echo 'abcd'; ?>";
file_put_contents("/some/temp/path", $str);
exec("php -l /some/temp/path", $output, $result);
if ($result == 0){
   echo "{$str} is valid";
} else {
   echo "{$str} is not valid PHP code";
}
unlink("/some/temp/path");

The reason I didn't use php_check_syntax is because:

  1. it's deprecated
  2. it actually executes the code

Upvotes: 1

Armin Braun
Armin Braun

Reputation: 3683

Edit: Just saw that you want to rather refrain from using exec(). I think this is going to be very hard without it though, php removed the check_syntax function for a reason. Maybe ( and I really am just guessing here when it comes to the effort you want to invest ) running the php -l in a container ( docker pretty much these days ) and passing the code via a http call to the docker daemon ( just a run command against the standard php cli would do it here ). Then you could use something like below code example without worries ( provided you don't give any permissions to your container obv ).

You could use exec and the php commandline like this:

$ret = exec( 'echo "<?php echo \"bla\";" | php -l 2> /dev/null' );

echo strpos( $ret, 'Errors parsing' ) !== false ? "\nerror" : "\nno error";

$ret = exec( 'echo "<?php eccho \"bla\";" | php -l 2> /dev/null' );

echo strpos( $ret, 'Errors parsing' ) !== false ? "\nerror" : "\nno error";

which returns:

no error
error

No file needed thanks to piping the output. Also using the redirection to dev null we get no unwanted output elsewhere. Still surely a little dirty, but the shortest I can come up with.

Upvotes: 1

Related Questions