2

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

9
  • 1
    What about posting curl requests to those online syntax checkers? I don't know the sites, so I'm not sure if its possible, but you could observer the network requests and see if you can emulate it with cURL Commented Nov 4, 2015 at 19:50
  • Can you clarify "valid"? Does that mean free of both compile time and run time errors? Or works as expected? Commented Nov 4, 2015 at 19:56
  • All I can find is the same as you did. I checked a REST service, but that one also takes a file. Writing (and deleting) a file is quite a trivial task - so I am curious, why don't you want to write to a file to use php_check_syntax? Commented Nov 4, 2015 at 19:56
  • 1
    @HPierce, I updated my question to explain... The php-parser or phc seem like good options. Commented Nov 5, 2015 at 16:20
  • 1
    @Jakar I understand that checking string would be way nicer, and writing to and deleting a file and stuff is just a silly redundant job. Depending on how many times you want to check that code, writing to a file does not easily affect performance. If I were you I start doing the write to file thing right away before trying anything else, but thats me :) Commented Nov 5, 2015 at 17:36

3 Answers 3

7

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;
}
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.