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.
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.
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.
P粉5746952152023-07-24 09:30:10
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.
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.
<?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
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.
Each new function declaration introduces a new scope, it's that simple.
function foo() { $foo = 'bar'; $bar = function () { // no access to $foo $baz = 'baz'; }; // no access to $baz }
$foo = 'foo'; class Bar { public function baz() { // no access to $foo $baz = 'baz'; } } // 无法访问 $baz。
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...
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);
$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.
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.