Edit report at https://bugs.php.net/bug.php?id=67817&edit=1
ID: 67817
Comment by: php at richardneill dot org
Reported by: php at richardneill dot org
Summary: RFE: permit repeat declaration of the same function
to skip rather than fail
Status: Not a bug
Type: Feature/Change Request
Package: Scripting Engine problem
PHP Version: 5.5.15
Block user comment: N
Private report: N
New Comment:
Thanks for your comment; I did already know about require_once(). Sorry if my test case was too
simple; there are many better reasons for doing this, notably if the files to be included (or their
children) contain a mix of functions and other code, in which case we only want to define the
functions once, but we need to invoke the rest of the code every time.
Here is a real example. I have a (complicated) website written in PHP, with multiple users. Each
page is dynamically generated, according to both the query-string and the credentials saved in
$_SESSION.
A user wants to export his data, essentially crawling part of the site, while logged in. Thus, we
have something like the following (simplified) in export.php:
function capture_html ($page, $get){
$_GET = $get; $_POST=array();
//but, we explicitly want to keep $_SESSION
ob_start();
include ($page);
$html = ob_get_contents();
ob_end_clean;
return ($html);
}
//iterate over multiple sets of pages and files:
file_put_contents("1.html",capture_html("details.php", array("id"
=> "5") ));
file_put_contents("2.html",capture_html("details.php", array("id"
=> "6") ));
file_put_contents("3.html",capture_html("messages.php",array("id"
=> "532")));
...
//and now zip the archive and offer the .zip to the user.
This is admittedly ugly in terms of recursion. The problem arises when the same $page is captured
twice with different parameters: all the functions which normally don't clash then conflict
with themselves. In this example, repeated use of file_get_contents($url) would be no good, because
the view of ($url) would be for a non-loggedin user.
I hope that makes sense.
Previous Comments:
------------------------------------------------------------------------
[2014-08-09 22:00:48] pajoye@php.net
That's why include/require_once exists.
------------------------------------------------------------------------
[2014-08-09 21:07:27] php at richardneill dot org
Description:
------------
At the moment, PHP will not let us re-declare an existing function, but instead has the error:
"Cannot redeclare FUNCNAME() (previously declared in FILE:LINE)"
That's fine, and I understand why, unlike, say bash, we can't/shouldn't be able to
change a function definition.
However, it's rather a pain if you end up with multiple indirectly include()d files some of
which get included more than once, and you forgot to wrap every single function definition with:
if (!function_exists("FUNCNAME")){
function FUNCNAME(...){
...
}}
My request is that, rather than throwing an error the second time, if PHP is encountering the *same*
function in the *same* file, it should simply ignore the duplicate definition (and throw an
E_NOTICE).
This ought to be easy to implement (since PHP already knows the filename/line-num of the original
definition at the time it reaches the duplicate), and the parser need merely ignore the duplicate.
It should also not violate the principle of least-surprise, because if the function is identical,
then even if it were re-defined, the programmer would expect it to do the same thing. So I believe
this is an easy and uncontroversial win for the common case.
Thank you for your consideration.
Test script:
---------------
----- begin file inner.php ---
<?php
function a(){
echo "A\n";
}
a();
?>
------ end file --------------
----- begin file main.php ---
<?php
include ("inner.php");
include ("inner.php");
?>
------ end file --------------
Expected result:
----------------
This should print:
A
A
Actual result:
--------------
A
PHP Fatal error: Cannot redeclare a() (previously declared in inner.php.3) in inner.php on line 4
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=67817&edit=1