5

I know that by using eval($code_to_check); we can check if this value equals FALSE and if so, we can stop execution of the script. However, the problem I'm facing is that I am unable to define a function, because it gets called twice... it gets processed with the eval() check to be sure there are no syntax errors and than processes the function again, but shows an error that states that it can NOT REDECLARE this function, as it is already being declared in the eval'd function. How can I make it so that we don't declare things in the EVAL'd function, or perhaps, we can undeclare everything that was declared in the eval() function before we actually do call it...

Anyways, here is what I'm working with so far... Could use some help, cause I am getting a "CAN NOT REDECLARE FUNCTION" when $content (which is php code) has a function within it.

// PHP Syntax errors?
if (!@eval('return true;' . $content))
{
    // Error found in PHP somewhere.  Call error function and return out of here!
    call_user_func_array($code_error['function'], $code_error['params']);
    return;
}
else
{
    ob_start();

    eval($content);
    $code = ob_get_contents();
    ob_end_clean();
}

Can anyone please help me here? Thanks guys, you are all so very helpful here! You all deserve a GOLD MEDAL, but I believe the Olympics are now over and this isn't quite a sport yet...


Ok, I am attempting my own answer here, and wondering if this will still catch errors and allow for functions to be created at the same time without calling these functions twice. Is this a proper way of doing this?? Can anyone see any possible problems in this code? I am echoing the $eval_code if no syntax errors detected... is this fine to do?

$eval_code = @eval($content);
// PHP Syntax errors?
if ($eval_code === FALSE)
{
    call_user_func_array($code_error['function'], $code_error['params']);
    return;
}
else
{
    ob_start();
    echo $eval_code;
    $code = ob_get_contents();
    ob_end_clean();
}
6
  • 5
    You could run the commandline php interpreter in "lint" mode, to check the syntax after you stored your snippet in a temporary file. For example exec("php -l checkfile.php.txt"); could return No syntax errors detected in ... Commented Aug 14, 2012 at 1:32
  • No, I am typing code via PHP into a text area, and want it to affect pages on my site. Sometimes, I create a function: function doSomething($blah), but in doing this it executes it twice... Really just need to run eval once here... perhaps if I set a php variable to the eval() function??? Commented Aug 14, 2012 at 1:33
  • 1
    eval isn't meant for just code checking. It runs it right away. You might as well skip that validation step then. Security-wise it's redundant anyway. There are userland PHP parsers though, if you want to assert code correctness before executing user-supplied code. (The latter being the questionable part.) Commented Aug 14, 2012 at 1:40
  • 1
    Have you tried token_get_all()? That should warn about any syntax errors. Commented Aug 14, 2012 at 1:42
  • 1
    @ Jack - How to use token_get_all() to check for syntax errors?? Confused... Commented Aug 14, 2012 at 1:45

4 Answers 4

4
$checkResult = exec('echo \'<?php ' . escapeshellarg($code_to_check) . '\' | php -l >/dev/null 2>&1; echo $?');
if ($checkResult != 0) {
    throw new \RuntimeException("Invalid php");
} else {
   $result = eval($code_to_check);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Why you write \RuntimeException with a `\` in front of it? That looks like an error...
Thanks for the good answer. You should use escapeshellarg on $code_to_check, otherwise the code will fail if there are any single quotes in the php to check.
ps: did you know PHP once had a function php_check_syntax()? It was removed in 5.0.5 because it was buggy github.com/php/php-src/commit/…
if $code contains new-line character, the exec function will return unexpected error code result. So i do $code = str_replace(PHP_EOL, '', $code); to remove all new-line characters in the code before checking
1

You can also use a new but very popular and stable tool PHPStan for these kinds of checks.

Here you can read a short and simple tutorial, how to use it.

Comments

0

If you check PHP Documentation for eval(), this is the description:

eval — Evaluate a string as PHP code

However, PHP Documentation, itself says that eval is a dangerous construct: Caution

The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.

So, be careful when using eval, very careful. Now back to your question.

I think what you need here is a tool that can help you with Syntax checking to detect violations of a defined coding standard. I use ESLint to check violations in Javascript code. For PHP I use both PHPStorm and Sublime Text, and I use PHP Lint and PHPCS. Instead doing eval, I suggest you use one of these OR combination of these tools to achieve you objective.

If you are using Jetbrains PHPStorm, you can find these plugins here:

If you prefer to use Sublime, here are the plugins for you:

My point is, a good combination of these tools should be enough to ensure sanity of your code.

-Thanks

Comments

0

I found a way of checking the syntax of all my php files at once in my test automation. You can use it if your php files contain only functions and data (without performing any unwanted actions when included without parameters).

I get a list of my php files and I generate one html page with one IFrame for each php file. I have my custom PHP error handler putting all errors to the database, so it is enough to include the file in the IFrame. If there is an error (including syntax errors), it gets logged.

main.php<br/>
<iframe id='frm_main.php' src='test_automation.php?CMD=CheckSyntaxPHP&PHP_FILE=main.php'>main.php</iframe><br/><br/>
second.php<br/>
<iframe id='frm_second.php' src='test_automation.php?CMD=CheckSyntaxPHP&PHP_FILE=second.php'>second.php</iframe><br/><br/>

test_automation.php on command CMD=CheckSyntaxPHP just checks the extension and existence of the file and includes the requested php file.

I use the same principle for checking the syntax of all my javascript files - an IFrame for each JS file. CMD=CheckSyntaxJS creates an html file with two blocks of javascript:

The first block of javascript defines only a javascript errorhandler sending all the errors to my web, which would log them to the database. (It must be in a separate block so that a syntax error in your JS does not prevent the errorhandler from calling.)

The second block block of javascript contains text loaded from the currently checked JS file.

<html>
<head>
<script type='text/javascript'>
function MyOwn_OnError(msg, url, lineNo, columnNo, error)
{ // do your error handling here, show or log the error
  var sError="Error: "+error+" in "+url; // build your own error message
  sError=encodeURIComponent(sError);
  var oReq = new XMLHttpRequest();
  if (bShowToUser) // define the handlers showing success if necessary
    { oReq.addEventListener("load", MyOwn_OnError_TransferComplete);
      oReq.addEventListener("error", MyOwn_OnError_TransferFailed);
      oReq.addEventListener("abort", MyOwn_OnError_TransferCanceled);
    }
  oReq.open("GET", "https://www.yourwebpage.com/ErrorHandlerJS?ErrMsg="+sError);
  oReq.send();
// and show something about sending the error to the user in the html page if needed
}
window.onerror=MyOwn_OnError;
</script>
<script type='text/javascript'>
// and here is the content of your javascript file
</script>
</head>
<body>
</body>
</html>

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.