Home  >  Q&A  >  body text

Reference: What is variable scope, which variables can be accessed from where, and what is an "undefined variable" error?

<p><br /></p><blockquote> <p>Note: This is a reference question for dealing with variable scope in PHP. Please close any of the many questions fitting this pattern as a duplicate of this one.</p> </blockquote> <p>What does variable scope mean in PHP? Can variables in one .php file be accessed in another file? Why do I sometimes get an "undefined variable" error message?</p>
P粉018653751P粉018653751476 days ago551

reply all(2)I'll reply

  • P粉786432579

    P粉7864325792023-07-24 11:19:34

    Although variables defined within a function scope cannot be accessed from the outside, this does not mean that their values ​​cannot be used after the function completes. PHP has a well-known static keyword, which is widely used to define static methods and properties in object-oriented PHP, but you need to remember that the static keyword can also be used to define static variables inside a function.

    Static variables are different from ordinary variables defined within the function scope. They do not lose their value when the program execution leaves the scope. Let us consider the following example using static variables:

    function countSheep($num) {
     static $counter = 0;
     $counter += $num;
     echo "$counter sheep jumped over fence";
    }
    
    countSheep(1);
    countSheep(2);
    countSheep(3);

    result:

    1 sheep jumped over fence
    3 sheep jumped over fence
    6 sheep jumped over fence

    If we do not use the static keyword to define the $counter variable, the value output each time will be the same as the $num parameter passed to the function. Using the static keyword allows you to build this simple counter without the need for additional solutions.

    Purpose of static variables

    1. Used to store values ​​between consecutive function calls.
    2. Store values ​​between recursive calls when there is no way (or purpose) to pass them as arguments.
    3. Used for caching values ​​that are usually best retrieved only once. For example, the result of reading an immutable file on the server.

    Static variables only exist in local function scope. It cannot be accessed outside the function in which it is defined. Therefore, you can ensure that its value remains unchanged until the next call to the function.

    Static variables can only be defined as scalars or scalar expressions (since PHP 5.6). Assigning other values ​​to it is bound to result in an error, at least at the time of this writing. However, you can do this in the next line of code:

    function countSheep($num) {
      static $counter = 0;
      $counter += sqrt($num);//imagine we need to take root of our sheep each time
      echo "$counter sheep jumped over fence";
    }

    result:

    2 sheep jumped over fence
    5 sheep jumped over fence
    9 sheep jumped over fence

    Static functions are a "sharing" mechanism between object methods of the same class. It can be easily understood by looking at the following examples:

    class SomeClass {
      public function foo() {
        static $x = 0;
        echo ++$x;
      }
    }
    
    $object1 = new SomeClass;
    $object2 = new SomeClass;
    
    $object1->foo(); // 1
    $object2->foo(); // 2 oops, $object2 uses the same static $x as $object1
    $object1->foo(); // 3 now $object1 increments $x
    $object2->foo(); // 4 and now his twin brother

    This only works for objects of the same class. If the objects are from different classes (even if they extend each other), static variables will behave as expected.

    Are static variables the only way to maintain values ​​between function calls?

    Another way to maintain values ​​between function calls is to use closures. Closures were introduced in PHP 5.3. Simply put, they allow you to restrict access to a certain set of variables to another anonymous function within the scope of the function, which will be the only way to access those variables. Within closures, variables can emulate (more or less successfully) the concepts of "class constants" (if they are passed to the closure by value) or "private properties" (if passed by reference) in object-oriented programming.

    In fact, the latter allows the use of closures instead of static variables. Which method to use is completely up to the developer's decision, but it is worth mentioning that static variables are very useful when dealing with recursion and deserve the developer's attention.

    reply
    0
  • P粉574695215

    P粉5746952152023-07-24 09:30:10

    What is variable scope

    Variables have a limited "scope", or "where they can be accessed". Just because you wrote $foo = 'bar'; once somewhere in your application doesn't mean you can reference $foo anywhere else in your application. The variable $foo is valid within a specific scope and can only be accessed by code within the same scope.

    How to define scope in PHP?

    Very simple: PHP has function scope. This is the only scope delimiter that exists in PHP. Variables inside a function can only be used within that function. Variables outside a function can be used anywhere outside the function, but cannot be used inside any function. This means there is a special scope in PHP: the global scope. Variables declared outside any function are in the global scope.

    For example:

    <?php
    
    $foo = 'bar';
    
    function myFunc() {
        $baz = 42;
    }

    $foo is in the global scope, $baz is in a local scope inside myFunc . Only code inside myFunc has access to $baz. Only code outside myFunc has access to $foo .Neither has access to the other:

    <?php
    
    $foo = 'bar';
    
    function myFunc() {
        $baz = 42;
    
        echo $foo;  // doesn't work
        echo $baz;  // works
    }
    
    echo $foo;  // works
    echo $baz;  // doesn't work

    Scopes and included files

    File boundaries do not separate scopes.

    a.php

    <?php
    
    $foo = 'bar';

    b.php

    <?php
    
    include 'a.php';
    
    echo $foo;  // works!

    The rules that apply to included code are the same as those that apply to any other code: only functions can separate scopes. In terms of scope, you can think of include files as copy and paste code.

    c.php

    <?php
    
    function myFunc() {
        include 'a.php';
    
        echo $foo;  // works
    }
    
    myFunc();
    
    echo $foo;  // doesn't work!

    In the above example, a.php is contained inside myFunc, and any variables in a.php only have local function scope. Just because they appear to be globally scoped in a.php doesn't mean they actually are, it really depends on the context in which that code is included/executed.

    Regarding functions and classes inside functions, how to deal with another situation?

    Each new function declaration introduces a new scope, it's that simple.

    (Anonymous) function inside a function.

    function foo() {
        $foo = 'bar';
    
        $bar = function () {
            // no access to $foo
            $baz = 'baz';
        };
    
        // no access to $baz
    }

    kind

    $foo = 'foo';
    
    class Bar {
    
        public function baz() {
            // no access to $foo
            $baz = 'baz';
        }
    
    }
    
    // 无法访问 $baz。

    What is the use of scope?

    Dealing with scoping issues may seem annoying, but limited variable scopes are critical to writing complex applications! If every variable you declare in your application is accessible from anywhere, you won't be able to track changes to the variable. You can only give variables a limited number of sensible names, and you may want to use the variable "$name" in more than one place. If you can only have one unique variable name in your application, you will have to use a very complex naming scheme to ensure the uniqueness of the variables and to ensure that you don't change the wrong variable from the wrong piece of code.

    as follows:

    function foo() {
        echo $bar;
    }

    What does the above function do if there is no scope? Where does $bar come from? What status does it have? Is it initialized? Do you need to check every time? This is not maintainable. This leads to...

    Crossing scope boundaries

    The correct way: passing in and out variables

    function foo($bar) {
        echo $bar;
        return 42;
    }

    The variable $bar is explicitly passed into the scope as a function parameter. Just by looking at this function, it's clear where the values ​​it uses come from. Then, it explicitly returns a value. The caller can be sure which variables the function will use and where the return value comes from:

    $baz   = 'baz';
    $blarg = foo($baz);

    Expand the scope of variables into anonymous functions

    $foo = 'bar';
    
    $baz = function () use ($foo) {
        echo $foo;
    };
    
    $baz();

    Anonymous functions explicitly include the $foo variable from its surrounding scope. Note that this is not the same as global scope.

    Wrong way: global

    As mentioned before, the global scope is special, and functions can explicitly import variables from the global scope:

    $foo = 'bar';
    
    function baz() {
        global $foo;
        echo $foo;
        $foo = 'baz';
    }

    This function uses and modifies the global variable $foo. Do not do this! (Unless you really really really know what you're doing, and even then: don't do it!)

    The caller who calls this function can only see this:

    baz(); // outputs "bar"
    unset($foo);
    baz(); // no output, WTF?!
    baz(); // outputs "baz", WTF?!?!!

    There is no indication that this function has any side effects, but in fact it does. This can easily turn into a messy situation when some functions are constantly modifying and depending on some global state. You want the function to be stateless, operating only on its inputs and returning defined outputs, regardless of how many times you call it.

    Avoid using the global scope under any circumstances if possible; in particular, variables should not be "extracted" from the global scope into the local scope.

    reply
    0
  • Cancelreply