php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #76797 Ability to access php compiler (deprecated create_function)
Submitted: 2018-08-26 21:00 UTC Modified: 2018-11-13 21:21 UTC
From: mageia at mokraemer dot de Assigned:
Status: Wont fix Package: *General Issues
PHP Version: 7.2.9 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2018-08-26 21:00 UTC] mageia at mokraemer dot de
Description:
------------
In previous versions it was possible to access the php compiler via create_function to make syntax checks on (generated) sources. Since this function is deprecated, there is no function to check php files for syntax errors in php.

Unsing this function is a hack, I know. But using include,... will cause php to call the shutdown function. What I want, is just parsing of the file, and receiving an error object which shows me if and where errors are.

Test script:
---------------
$code='<?php my php script with errors;?>';
$var = create_function('', '?>' . preg_replace(['|use [\w,\s\\\\]*;|'], '', $code) . '<?php ');
if(empty($var) && ( $error = error_get_last() )){
  echo 'compile error. Details:';
  print_r($error);
}


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-08-26 22:47 UTC] requinix@php.net
-Status: Open +Status: Wont fix
 [2018-08-26 22:47 UTC] requinix@php.net
I'm going to step up and say wontfix on this.

The main problem here is that PHP isn't designed to work in a way where it can syntactically validate code and not allow that code to impact the runtime as well. There are assorted performance enhancements and features that assume code being inspected is supposed to be (potentially) executed. For example, class and function definitions are normally hoisted and that happens before any code is executed.

Refactoring PHP to support another interstitial layer where code is validated before anything gets interpreted seems to me like a lot of effort for little gain. Consider that you can already `php -l` a file, plus there are third-party libraries out there that are made to do this.

While it's definitely not a good suggestion, note that create_function is basically just a wrapper around eval()ing a function definition so if you don't mind ignoring common sense then there's not much to stop you from doing
  eval('function() { ?>' . preg_replace(['|use [\w,\s\\\\]*;|'], '', $code) . '<?php };');

If you feel strongly about adding something that can be accessed from PHP code, check out the RFC process.
  https://wiki.php.net/rfc
(though the mailing lists are down...)
 [2018-10-16 23:16 UTC] mageia at mokraemer dot de
is there any advice on how to check syntax inside php?

For user contributed code, I really want to check the syntax before using the code.
 [2018-10-16 23:39 UTC] mageia at mokraemer dot de
sorry, I didn't see your comment.
You're right, eval solves my problem.
 [2018-11-13 17:03 UTC] mageia at mokraemer dot de
I thought eval solves the problem, but it is not. The changed behaviour of eval "Before PHP 7, in this case eval() returned FALSE and execution of the following code continued normally. It is not possible to catch a parse error in eval() using set_error_handler()."
makes it impossible to check for syntax errors and handle them apropriate!
 [2018-11-13 17:09 UTC] requinix@php.net
> makes it impossible to check for syntax errors and handle them apropriate!
Thank you for reading the documentation, but while the sentence you identified does explain that you can no longer handle parse errors with set_error_handler(), the sentence immediately before it told you the new behavior:

> As of PHP 7, if there is a parse error in the evaluated code, eval() throws a
> ParseError exception.
 [2018-11-13 17:29 UTC] spam2 at rhsoft dot net
this is simply not true because with try-catch you have everything you need without the drawback of mangle with the error handler
 [2018-11-13 18:21 UTC] mageia at mokraemer dot de
Test-Script:
<?php

function shutdown(){
	echo 'shutdown';
}

register_shutdown_function('shutdown');
$code = '?;';

try{
	$var = eval('function() { ?>' . preg_replace(['|use [\w,\s\\\\]*;|'], '', $code) . ' <?php } ?>');
} catch (Exception $e){
	echo 'exception catched';
	print_r($e);
}


$php -v
PHP 7.2.11 (cli) 

$php test.php 
shutdown


=> I get no exception to catch!
 [2018-11-13 18:27 UTC] spam2 at rhsoft dot net
because your code is simply wrong

catch(Throwable $e)
{ 
}
 [2018-11-13 18:29 UTC] mageia at mokraemer dot de
same output for
Throwable
 [2018-11-13 18:46 UTC] spam2 at rhsoft dot net
it works, period, refactor and simplify your code, you can catch parse errors as any other exception, starzing with PHP7 "Throwable"catches *anything* and if that don't happen you have other problems - this is a bugtracker and not a support forum


---------------------------

[harry@srv-rhsoft:/downloads]$ php test.php
exception catchedParseError Object
(
    [message:protected] => syntax error, unexpected end of file
    [string:Error:private] =>
    [code:protected] => 0
    [file:protected] => /mnt/data/downloads/test.php(4) : eval()'d code
    [line:protected] => 1
    [trace:Error:private] => Array
        (
        )

    [previous:Error:private] =>
)

---------------------------

[harry@srv-rhsoft:/downloads]$ cat test.php
<?php
try
{
 $var = eval('nonsense');
}
catch (Throwable $e)
{
 echo 'exception catched';
 print_r($e);
}
 [2018-11-13 19:14 UTC] mageia at mokraemer dot de
sorry, found my mistake in the testcode :(

Throwable was the solution I didn't see.

Thanks for pointing it out, sorry to bother you.
 [2018-11-13 21:07 UTC] spam2 at rhsoft dot net
don't get me wrong but "Throwable was the solution I didn't see" is a strange response after "same output for Throwable"
 [2018-11-13 21:21 UTC] mageia at mokraemer dot de
I wanted to say "Throwable" solved it. 

But I didn't recognize it as a solution, since I'd simplified my code and by doing this there was no error that could be catched. And finally the shutdown function was correctly executed, since the program ends. In real code this does not happen. I was mixing up real code and demo code.

Still thank you for your time.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 19:01:33 2024 UTC