search

Home  >  Q&A  >  body text

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


NOTE: This is a reference question dealing with variable scope in PHP. Please close any of the many questions that fit this pattern as duplicates of this question.

What is "variable scope" in PHP? Can variables in one .php file be accessed in another .php file? Why do I sometimes get an "undefined variable" error?

P粉023650014P粉023650014403 days ago620

reply all(2)I'll reply

  • P粉311563823

    P粉3115638232023-10-20 10:03:09

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

    What is a "static variable"?

    Static variables are different from ordinary variables defined in function scope. Static variables will not lose their value when 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 define $counter without static, then the value echoed each time will be the same as the $num parameter passed to the function. This simple counter can be built using static without additional workarounds.

    Static variable use case

    1. Store the value between subsequent calls to the function.
    2. Store values ​​between recursive calls when there is no way (or no way) Purpose) passing them as parameters.
    3. Caching is usually best done by retrieving values ​​once. for For example, the result of reading an immutable file on the server.

    Skill

    Static variables only exist in local function scope. it can't be Accessed outside the function in which it is defined. so you can Make sure it will keep its value until the next call This function.

    Static variables can only be defined as scalars or scalars Expressions (since PHP 5.6). inevitably assign other values ​​to it Which results in failure, at least as of this writing. However, you can do this on 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 somewhat "shared" between the object's methods Classmates. It’s easy to understand by looking at the following example:

    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 applies to objects of the same class. Static variables will behave as expected if the objects are from different classes (or even extend each other).

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

    Another way to preserve values ​​between function calls is to use closures. Closures were introduced in PHP 5.3. In short, they allow you to restrict access to a certain set of variables within a function's scope to another anonymous function, which will be the only way to access them. Being inside a closure variable may emulate (more or less successfully) OOP concepts such as "class constants" (if they are passed by value in the closure) or "private properties" (if passed by reference) in structured programming .

    The latter actually allows the use of closures instead of static variables. It's always up to the developer to decide what to use, but it should be mentioned that static variables are definitely useful when using recursion and deserve developer attention.

    reply
    0
  • P粉895187266

    P粉8951872662023-10-20 09:03:53

    What is "variable scope"?

    The "scope" or "where they can be accessed" of variables is limited. Just because you wrote $foo = 'bar'; once somewhere somewhere in your application, doesn't mean you can reference $ from foo >Elsewhere within the application. The variable $foo has a certain scope, within which it is valid, and only code within the same scope can access the variable.

    How to define scope in PHP?

    Very simple: PHP has

    function scope. This is the only range delimiter present in PHP. Variables inside a function are only available inside that function. Variables outside a function can be used anywhere outside the function, but cannot be used inside any function. This means that there is a special scope in PHP: the global scope. Any variable declared outside any function is in this global scope.

    Example:

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

    $foo is in the global scope and $baz is in the local scope of myFunc. Only code within myFunc can access $baz. Only code outside myFunc can access $foo. Neither party can access 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
    Scope and included files

    File boundaries

    Not separated

    Range:

    a.php

    <?php
    
    $foo = 'bar';
    b.php

    <?php
    
    include 'a.php';
    
    echo $foo;  // works!
    The rules that apply to include

    code are the same as those that apply to any other code: separate scopes for

    functions only. For scope purposes, you might consider including files like copy and paste code: c.php

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

    is contained within

    myFunc, and any variables in a.php only have local function scope. Just because they appear to be in global scope within a.php doesn't necessarily mean that they are, it really depends on the context in which the code is contained/executed. What about functions and functions in classes? Each new

    function

    declaration introduces a new scope, simple as that.

    Function within (anonymous) function

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

    $foo = 'foo';
    
    class Bar {
    
        public function baz() {
            // no access to $foo
            $baz = 'baz';
        }
    
    }
    
    // no access to $baz

    What is the use of scope?

    Dealing with scoping issues may seem annoying, but

    limited variable scope is critical to writing complex applications!

    If every variable you declare is available from anywhere else within your application, then you'll be stepping through everything on your variables with no real way to keep track of what changed what. You are limited in the sensible names you can give your variables, and you may want to use the variable "

    $name

    " in more than one place. If you can only use this unique variable name once in your application, then you have to employ a very complex naming scheme to ensure that your variables are unique and that you don't change the wrong variable from the wrong piece of code. observe:

    function foo() {
        echo $bar;
    }
    What does the above function do if there is no scope? < /p>$bar

    Where does it come from? What status does it have? Is it even initialized? Do I need to check it every time? This is not maintainable. Which brings us to...

    Crossing range boundaries

    The correct way: passing in and out variables

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

    Variables$barexplicitly enters this range as function parameters. Just looking at this function, it's clear where the values ​​it uses come from. It then explicitly returns a value. The caller has confidence that it knows which variables the function will use and where its return value comes from:

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

    Extend the scope of variables to anonymous functions

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

    Anonymous functions explicitly include $foo in their surrounding scope. Note that this is not the same as global scope.

    Wrong way: Global

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

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

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

    What the caller of this function sees is 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 it does. This can easily become confusing because some functions are constantly modifying and require some global state. You want your functions to be stateless, acting only on their inputs and returning defined outputs, no matter how many times you call them.

    You should avoid using the global scope in any way if possible; most certainly, you should not "pull" variables from the global scope to the local scope.

    reply
    0
  • Cancelreply