#1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    Iran
    Posts
    149
    Rep Power
    139

    Question A question about the scope of a required file within a function scope


    Hi,

    Code:
    OS: Linux Fedora Core 17 (X86_64)
    PHP Version: 5.4.17
    Apache version: Apache 2.0 Handler
    I was reading the online documentation about include/require files in a calling PHP script

    http://www.php.net/manual/en/function.include.php

    In this chapter we can read the following:
    If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function.
    The problem is, that I'm not sure to understand the above underlined quote. What I make of this is that let's say, we have 2 files: file1.php and file2.php. If file1.php is required within a function of file2.php, then every declaration of file1.php is visible only inside that function and nowhere else in file2.

    Now, based on my understanding (which as I said, I'm not sure to have understood the above mentioned quote of the documentation correctly) I made the following test with two PHP test scripts (for the purpose of this test, both files were created at the same directory on the server):

    file1.php
    php Code:
    <?php
        echo "Running: " . __FILE__ . "<br>";
     
        function getSum($p_intVal1, $p_intVal2)
        {
            return ($p_intVal1 + $p_intVal2);
        }

    And the second file which will require the above file

    file2.php
    php Code:
    <?php
        function testFun($p_n1, $p_n2)
        {
            require("file1.php");
            return getSum($p_n1, $p_n2);
        }
     
        echo "Running: " . __FILE__ . "<br>";
        echo testFun(1500, 500) . "<br>";
        echo getSum(400, 40);
    The output is
    Code:
    Running: /var/www/html/file2.php
    Running: /var/www/html/file1.php
    2000
    440
    What I don't understand is the last line: 440. This is the result of a direct function call (getSum) which is defined in file1.php. Now according to the documentation that file was required only inside a local function and therefore within a function scope. As a result I don't understand how it is possible to call it elsewhere in file1.php?

    Could someone kindly make some clarification?

    Thanks in advance,

    Comments on this post

    • Jacques1 agrees : Excellent problem description.
    Regards,
    Dariyoosh
  2. #2
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Hi,

    this behaves exactly as if you literally copied and pasted the content of file1.php into file2.php, so it's not really related to including files.

    Function declarations are always global, no matter where you write them down:

    PHP Code:
    <?php

    function outer() {
        function 
    inner() {
            echo 
    'inner<br />';
        }    
        echo 
    'outer<br />';
    }

    outer();    // this also defines inner()
    inner();
    You'll see the effect of the "local include" when you use variables.


    By the way, kudos for one of the best problem description I've seen in a while. If every question was so exact, we could all save a lot of time.

    Comments on this post

    • dariyoosh agrees : Very nice description, thanks a lot!
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  4. #3
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    Iran
    Posts
    149
    Rep Power
    139
    Hello there,

    Originally Posted by Jacques1
    Function declarations are always global, no matter where you write them down
    Thank you very much for your attention to my problem and your help. This was the key information. Thanks to your description I understand the issue now.

    After reading your comment I also checked the documentation for the functions and as you mentioned in fact no matter where and how you define your functions, they are always global.

    http://www.php.net/manual/en/functions.user-defined.php
    All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa.
    However, I have to say that this behaviour (I mean the fact that how the scope of variables and functions is maintained in PHP) seems to me (as a person who is learning the language) a bit strange and even error-prone ( = the developer has much more to take care about what he/she is doing comparing to other classic highly typed languages).
    Originally Posted by Jacques1
    You'll see the effect of the "local include" when you use variables.
    Exactly, and this is how I modified the above mentioned test to see this in practice:

    file1.php
    php Code:
    <?php
        $size = 80000;

    file2.php (which will require the above file)
    php Code:
    <?php
        function testFun()
        {
            require("file1.php");
            echo $size;
        }
     
        testFun();
        echo $size;
    And the output is
    Code:
    80000
    Notice: Undefined variable: size in /var/www/html/file2.php on line 9
    And the second line indicated that required variables inside a function are visible only in that function, so we get the expected output.

    Once again, thank you very much for your time and your help.
    Regards,
    Dariyoosh
  6. #4
  7. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    However, I have to say that this behaviour ... seems to me ... a bit strange and even error-prone
    Yes.

    PHP lends its self very well to being abused. To write clean PHP code needs external resources/references.

    I code up everything into objects and use autoload/spl_autoload (lazy loading) so I only have includes in two files - the "index" file (which includes the autoload function) and the file defining the autoload function.
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  8. #5
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    I can see how you might expect function definitions to be local, but from a technical point of view, it simply wouldn't make a lot of sense.

    In languages like JavaScript, every function is a closure, which means it captures the variables in the scope where it's defined. For those languages, it's perfectly fine to have "local functions" and use them as some kind of temporary helper function with access to all local variables of the parent function. But functions in PHP are just plain function without any access to the surrounding scope. Using them in a local context wouldn't be very useful -- and I've never seen anyone apply this programming style to PHP, actually.

    So I see no mistake on PHP's part here. It does exactly what you'd expect from its specific programming concept which is different from JavaScript, Pascal or whatever.

    In fact, PHP does support closures since 5.3, and they are indeed local:

    PHP Code:
    <?php

    function outer() {
        
    $x 123;
        
    // closure with access to $x
        
    $inner = function () use (&$x) {
            echo 
    $x;
        };
        
    $inner();
    }

    outer();
    $inner();    // error
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  10. #6
  11. Web Developer/Musician
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Nov 2004
    Location
    Tennessee Mountains
    Posts
    2,408
    Rep Power
    1031
    PHP 5.3 includes genuine annonymous functions and lambdas. Haven't had the ocassion to use them but they will work properly inside a function body. Otherwise the scope will be global as described.
  12. #7
  13. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Originally Posted by Hammer65
    PHP 5.3 includes genuine annonymous functions and lambdas.
    Have a look at the reply right above yours.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  14. #8
  15. Web Developer/Musician
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Nov 2004
    Location
    Tennessee Mountains
    Posts
    2,408
    Rep Power
    1031
    Originally Posted by Jacques1
    Have a look at the reply right above yours.
    Sorry yes missed that post.

IMN logo majestic logo threadwatch logo seochat tools logo