Req #67817 [Nab]: RFE: permit repeat declaration of the same function to skip rather than fail

From: Date: Sat, 09 Aug 2014 23:59:43 +0000
Subject: Req #67817 [Nab]: RFE: permit repeat declaration of the same function to skip rather than fail
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-187058@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=67817&edit=1

 ID:                 67817
 Updated by:         requinix@php.net
 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:

That's a problem of architecture: you've clearly written your pages so that they cannot
all be executed at once, but that's exactly what you're trying to do with them.
The standard practice of putting classes and functions in separate files, away from the
"presentation" files, would save you from this problem.


Previous Comments:
------------------------------------------------------------------------
[2014-08-09 23:17:28] php at richardneill dot org

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.

------------------------------------------------------------------------
[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


Thread (5 messages)

« previous php.bugs (#187058) next »