| Bug #27406 | php_check_syntax executes code | ||||
|---|---|---|---|---|---|
| Submitted: | 26 Feb 2004 11:00am UTC | Modified: | 29 Apr 2005 1:40am UTC | ||
| From: | thomas at stauntons dot org | Assigned to: | iliaa | ||
| Status: | Wont fix | Category: | *General Issues | ||
| Version: | 5.* | OS: | * | ||
| Votes: | 203 | Avg. Score: | 1.6 ± 1.4 | Reproduced: | 22 of 26 (84.6%) |
| Same Version: | 12 (54.5%) | Same OS: | 16 (72.7%) | ||
[26 Feb 2004 3:18pm UTC] sniper@php.net
Ilia, maybe this function wasn't such a good idea after all? Here's the first misuse of it already..
[13 Apr 2004 1:12pm UTC] sniper@php.net
Don't misuse the function.
[8 Aug 2004 6:59pm UTC] phpbug at bigredspark dot com
Bogus? Could someone document this function so we know what the "proper"
usage is? Is this funtion meant to load the file into the current scope
as it's syntax is checked? If so, please say so in the documentation.
Otherwise, I have another bug report to file.
original.php
<?php
$bool = php_check_syntax('checkme.php');
foo();
$bar = new Bar;
$bar->foo();
?>
checkme.php
<?php
function foo()
{ echo "checkme::foo\n"; }
class Bar {
function foo()
{ echo "checkme::bar::foo\n"; }
}
?>
results in
checkme::foo
checkme::bar::foo
for example, when my assumption of how the function works should have
the code results in undefined function and class errors.
[9 Aug 2004 5:10am UTC] philip@php.net
So should this function actually execute the code (like an include()) or should it be a simple lint check (identical to php -l). The doc team assumed the later. Please advise with specific information on how this should be documented or if this is indeed a bug, say so. http://cvs.php.net/co.php/phpdoc/en/reference/misc/functions/php-check-s yntax.xml
[26 Aug 2004 6:20pm UTC] philip@php.net
Tested latest CVS on a Win32 machine, same problem. Here's a very
simple test:
randominclude.php
<?php
function foobar() {
echo "HI";
}
?>
checksyntax.php
<?php
if (php_check_syntax('randominclude.php')) {
echo "passed";
foobar();
}
?>
Calling checksyntax.php via Module/CLI/CGI results in:
passedHI
As opposed to:
passed
Fatal error: Call to undefined function foobar() in ...
[16 Sep 2004 6:19pm UTC] didou at keliglia dot com
"So should this function actually execute the code (like an include()) or should it be a simple lint check (identical to php -l)" It should do only a lint check, otherway we don't need this function as we already have include.. Anyway, we should really change the docs philip.
[20 Sep 2004 9:36pm UTC] philip@php.net
How should the docs be changed? This misfeature hasn't been dealt with yet...maybe we should just remove the docs :)
[21 Sep 2004 4:03pm UTC] de_bruut at hotmail dot com
"How should the docs be changed? This misfeature hasn't been dealt with yet...maybe we should just remove the docs :)" What misfeature? IMO a function that can check the syntax of a PHP file before it's included has real benefits for development and testing (as it can be used to avoid parse and fatal errors etc). And the documentation of php_check_syntax perfectly describes such a function. The only problem here is the fact that php_check_syntax not only checks the code, but executes it as well. I'd say that this is unexpected, undesirable behavior (a bug). The documentation is just fine the way it is now...
[7 Oct 2004 4:07pm UTC] junk at thinkof dot net
My vote is for this function, and for updating the docs. Also the
comments in the php.net manual should be updated, as this isn't really a
bug.
Simply saying that the function is being misused, or saying this is bug
is not a good thing. People just need to understand its usage.
The simplest way I can see of updating the doc, is including a more
useful example. Perhaps mentioning possible usages (checking the syntax
of a file for it's first load into a caching engine for example).
<?php
$error_message = "";
$filename = "./tests.php";
//Check out $filename
if(!php_check_syntax($filename, $error_message)) {
//Display an error message, the code is bad
printf("Errors were found in the file %s:\n\n%s\n", $filename,
$error_message);
} else {
//Execute the valid code
include_once ($filename);
}
?>
[22 Oct 2004 11:37pm UTC] dan dot ostrowski at gmail dot com
The person above posted this:
----------------------
<?php
$error_message = "";
$filename = "./tests.php";
//Check out $filename
if(!php_check_syntax($filename, $error_message)) {
//Display an error message, the code is bad
printf("Errors were found in the file %s:\n\n%s\n",
$filename,
$error_message);
} else {
//Execute the valid code
include_once ($filename);
}
-------------------------
To use in the docs. The problem is this code is INCORRECT.
The function php_check_syntax( ) INCLUDES THE FILE in php
5.0.2
This means you get redeclare errors if you try to check the
syntax and then include the file.
The example code SHOULD be:
-----------------
<?php
$filename = '/path/to/somefile.php';
$err = (string) null;
if( !php_check_syntax( $filename, $err ) ) {
print "Syntax Error!"
die( );
}
// proceed, because at this point the file is included
// or script is dead.
-----------------------------
[11 Nov 2004 11:34pm UTC] jimmy dot lantz at gmail dot com
Couldnt there be an optional bool for including the function? Like bool php_check_syntax ( string file_name [, string &error_message][, bool just_lint]) That is if 3rd var is true it behaves like php -l from CLI? That way we that just wants to validate PHP code without including/running it? Preferrably in a totally secured way...
[10 Dec 2004 5:39pm UTC] philip@php.net
See also: http://bugs.php.net/27728
[14 Dec 2004 12:30am UTC] andi@php.net
I see it's assigned to Ilia so I'm not changing the status. Personally I would put this on very low priority for resolving. Whoever added the lint functionality probably did it for the command-line PHP in order to be able to quickly check a large amount of source code. I don't see this as a mainstream feature of PHP and would avoid hacking on getting it right as to not intefere with the normal execution of PHP (although it's quite possible).
[25 Jan 2005 7:56pm UTC] philip@php.net
It's like include() except it won't output the "checked" file (like if the "checked" file has an echo, it won't echo it). Aside from the obvious that's the only difference I notice but haven't tested it thoroughly. Sounds like this bug will never be fixed so I guess we should just document the current behavior.
[25 Jan 2005 8:12pm UTC] derick@php.net
fix assign to
[29 Jan 2005 4:35am UTC] wylie at geekasylum dot org
There seems to be a lot of discussion on whether this is a bug or a misuse. Here is something else to consider: de_bruut mentioned above that a syntax check function as described in the documentation of this function would be useful for development and testing, and I agree, but it also has other uses. I am about to write a code repository website where users can submit snippets (no smaller than complete functions) and it would be great to be able to check the syntax of the uploaded code on the fly and reject or accept it right there while the submitter is still online. This be one less admin check to do before the code was accepted to the site. Checking uploaded code snippets from the public is a huge security rick if the syntax checker includes or executes the code, but a simple lint check would be a huge boon to developers and code geeks like myself. In my case, it would be fantastic if we could optionally syntax check a string rather than a disk file as the code on my site would be stored in a database (and I imagine many other repositories would do the same). In the case of this bug a decision needs to be made as to whether the code or the documentation expresses the true value of this function, and one or other (ie: the code or the docco) needs to be fixed. This bug has been open almost a year and it seems that decision still has not been made. If the documentation is correct and the function is a simple lint checker, people can then include() any code that checks as valid if they desire to, (some dont) but if the syntax checker includes the code itself, then people like myself cant use it at all as the code to be checked has no relation to the running website (and should never be included).
[9 Feb 2005 9:42pm UTC] du at bestwaytech dot com
There is one other difference between include and php_check_syntax that
should be noted in the manual. Aside from supressing output buffer, it
only includes functions and classes, it does not set or affect global
variables, the way include() would.
If you have "test.php"
$myvar = 1;
echo $myvar;
function myfunction() {}
class myclass {}
include ("test.php") will set $myvar, print $myvar and set myfunction &
myclass
php_check_syntax("test.php") will ONLY include myfunction & myclass
[23 Feb 2005 5:32pm UTC] de_bruut at hotmail dot com
Couple of points: 1. there are already half a dozen functions that include files or execute strings 2. there's no other function that allows you to check the validity of a piece of php code 3. right now, php_check_syntax does more than its name implies (it includes the file) 4. there are several situations where a 'clean' lint check of php code is useful (snippet submissions, UNIT TESTS(!), ...) 5. in general, functions should do only one thing, not two only slightly related things, and one of them badly I would love to see php_check_syntax implemented as its name implies: a lint check for a STRING. Not a file (see Wylie's comment), because there are enough functions to read a file or stream into a string. If someone wants to include the file afterwards, they only need to add a single line of code, or they can write their own two-line function. This even leaves them the choice between include() and include_once(), something which php_check_syntax does not do at this point. Did I mention the potential value of php_check_syntax for >> UNIT TESTS << yet? php_check_syntax would allow us to check the syntax of a file (string) as the first of a group of tests for that file/class, and thus avoiding a potential fatal error, which could interrupt an entire set of tests on multiple files. Thus, a syntax check could make quite a number of very serious PHP developers very happy. Not much point if php_check_syntax immediately includes the file (string) though...
[3 Mar 2005 8:30am UTC] phpbugs at majiclab dot com
I would have to agree with most of the other posters, that the
php_check_syntax() function as it stands right now does MORE than its
name implies. I feel that a true php_check_syntax() function that
STRICTLY checks the syntax of a file or string and returns TRUE/FALSE
and has reference to an error message is the best. In fact, I would
also like to see the possibility of having an additional reference
variable for the line number of an error.
I am developing a fairly advanced framework that does compile certain
aspects of a web site dynamically. At first glance, I tried to
implement this function to check the syntax of the file both before
saving it and even before including it in the future. However, I ran
into some confusing messages about my classes being redefined and I
couldn't understand until I read the docs closer.
The simple fact is that the REAL functionality of this function is the
syntax checking, NOT the including. Any PHP programmer with more than 5
minutes of experience can probably include an external file. So adding
that particular aspect of the functionality to php_check_syntax() seems
useless. The code I have in my system goes a little like this:
<?php
...
function includeafile($sFile, $bOnce = FALSE)
{
if (file_exists($sFile)) {
if (!@php_check_syntax($sFile, $sMessage)) {
error_handler("File '$sFile' has a syntax error: $sMessage",
__LINE__, __FILE__);
} else {
... // go on including the file, etc.
}
}
return FALSE;
}
?>
Now, I started getting errors all of a sudden saying that a class in the
file being included is being redeclared. I thought that odd since I set
$bOnce = TRUE, so it shouldn't ever be included more than once. I think
ideally I should be able to do this:
<?php
...
function includeafile($sFile, $bOnce = FALSE)
{
if (file_exists($sFile)) {
if (!@php_check_syntax($sFile, $sMessage, $iLine)) {
error_handler("File '$sFile' has a syntax error: $sMessage",
$iLine, $sFile);
} else {
... // go on including the file, etc.
// it should not raise redeclaring errors
}
}
return FALSE;
}
?>
Basically, it should:
1. Not include the file at all, just strictly do a lint check.
2. It would be nice to be able to get the line number of the file (for
debugging purposes).
At the lowest level, this function should be able to run like described
by many others:
<?php
if (php_check_syntax($file, $message)) {
include $file;
} else {
error("Syntax Error: '$message'");
}
?>
It should be up to the PHP programmer to include the file...
[7 Mar 2005 10:59pm UTC] linus at mccabe dot nu
Another important use for this function would be when using eval()'s to test the code before eval'ing it. In this case a string would be the only option and declaring functions would definately not work... Since this function isn't experimental any more, I assume it cant be altered to do this, but a new one would need to be implemented?
[26 Mar 2005 2:43am UTC] patrick at 5etdemi dot com
If the file that is syntax checked has includes, the includes won't be executed. That means as soon as you use php_check_syntax on such a file, you won't be able to include it and you won't be able to use it either because it's included files are MIA. That makes the function pretty useless for any practical purposes.
[29 Apr 2005 1:40am UTC] sniper@php.net
This was fixed by removing the function altogether.
It was nice idea but not one that could ever work reliably/be stable.
Use something like 'system("php -l foo.php");' to check the syntax..

Description: ------------ I am writing a class that will include another file containing a class that needs to implement a specific interface. When calling php_check_syntax on the file its behavious differs depending on whether or not the class implements my interface. If the file implements my interface the class will not show up in get_declared_classes() and an include() of the file will work, but if the class doesn't implement my interface the class will be in get_declared_classes() and the include will fail with 'cannot redeclareclass' Reproduce code: --------------- in Main.php <?php interface MustImplement {} if (!php_check_syntax('includeme.php')) die('Bad Syntax\n'); else include('includeme.php'); ?> in includeme.php (Case 1) <?php class AClass implements MustImplement {} ?> in includeme.php (Case 2) <?php class AClass {} ?> Expected result: ---------------- Case 1 of includeme.php will work OK, php_syntax_check will succeed and include will load the file OK, AClass will be available. Case 2 will fail, php_syntax_check will work but include will fail with 'cannot redeclare class' & Illegal Instruction Actual result: -------------- Just as Above.