|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63156 using if ( expression ) requires functions to be declared before calls
Submitted: 2012-09-24 19:56 UTC Modified: 2012-09-25 16:27 UTC
From: herb at bobbingwide dot com Assigned:
Status: Duplicate Package: *Programming Data Structures
PHP Version: 5.3.17 OS: Windows XP
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: herb at bobbingwide dot com
New email:
PHP Version: OS:


 [2012-09-24 19:56 UTC] herb at bobbingwide dot com
When enclosing code between if ( expression ) { and } it appears that versions 
of PHP up to and including 5.3.17 require functions to be declared before they 
are used. I first noticed the problem when I tried to wrap a whole PHP source 
file like this
if ( !defined( 'CONSTANT' )) { 
define( 'CONSTANT', true ); 
// whole file here
} // end defined

I reduced the problem to the simplest; replacing !defined( 'CONSTANT') with true 
and got the same unexpected results. The code did not work unless the (top 
level) functions were declared before they were used. 
I found the problem on PHP 5.3.5 where the code produced a Fatal error: Call to 
undefined function. I have since reproduced the Fatal error on PHP 5.3.16 and 

If you remove the 'if test' (lines 2 and 7) the code works fine.
If you put the call to the function after the declaration that also works. 
This code, where the call to b() is before the declaration of function b, also 
if ( true ) {
  function a() {  
    echo "a" . PHP_EOL;
  function b() {
      echo "b" . PHP_EOL;

Test script:
if ( true ) {
  function a() {
    echo "a" . PHP_EOL;

Expected result:

Actual result:
Fatal error: Call to undefined function a() in C:\apache\htdocs\wordpress\wp-con
tent\plugins\play\defined.php on line 3


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2012-09-25 02:40 UTC]
it is good manner always declare function/class before using it.
 [2012-09-25 05:13 UTC]
Top level declaration are available after compiling, but conditional declaration
can only be available after executed. (since PHP itself didn't do optimization, 
i`f(true) {doSomething();}` is not equal to `doSomething();` exactly )

the same rules for class declarations.

This could be classified as a documentation problem.
 [2012-09-25 09:46 UTC]
-Status: Open +Status: Duplicate
 [2012-09-25 09:46 UTC]
dup to #17055
 [2012-09-25 11:33 UTC] herb at bobbingwide dot com
I accept that this is a duplicate of #17055.

And since derick said, in response to #17055, "I don't see any fast 
implementation of this.", 10 years ago (May 2002), I'm inclined to agree that 
this will have to be dealt with as a documentation problem.

However, in my particular scenario the original response to the problem... "The 
only way to prevent this is to move out the function declaration out of the 
branch and in the main scope of the script." is not acceptable since the whole 
point of the encapsulating code was to prevent the functions from being multiply 

So I believe the documentation should provide a clear explanation of the parsing 
and interpretation processes involved.
 [2012-09-25 12:22 UTC]
hmm, it's not the only way,  since you can get it works well by declare it 
before reference to it:
if ( true ) {
  function a() {
    echo "a" . PHP_EOL;
 [2012-09-25 14:11 UTC] herb at bobbingwide dot com
laruence... agreed. That's how I solved it, as documented in my original report.
I was just commenting on the original response in #17055.
It was the unexpected behaviour that threw me more than anything.
 [2012-09-25 14:12 UTC]
@herb: You are using a conditional function definitions, in which case PHP *can't* know which function will be used, at least not in the general case. Function hoisting only works with "top-level" function declarations.

This is also documented on See in particular those two lines:

> Functions need not be defined before they are referenced, *except* when a function is conditionally defined as shown in the two examples below.

> When a function is defined in a conditional manner such as the two examples shown. Its definition must be processed *prior* to being called.

A very simple solution to your particular problem (which at the same time will yield cleaner code) is to abort early if the constant is defined:

if (defined('CONSTANT')) {
// the rest of the file here
 [2012-09-25 16:27 UTC] herb at bobbingwide dot com
@nicic thanks for the link to the documentation. 
I hadn't realised I could use return... having previously failed to get a 
working solution with exit :-)  
I'll most likely change my code to something like this.
 if ( defined( 'CONSTANT' )) return;
 define( 'CONSTANT', true );
 function a() {
   echo "a" . PHP_EOL;

Then I don't have to worry about the final } at the end of the file
So should #17055 be marked as Closed now, rather than Suspended?
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Jul 15 03:01:28 2024 UTC