参考:什么是变量范围,哪些变量可从何处访问以及什么是“未定义变量"?错误? [英] Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?

查看:87
本文介绍了参考:什么是变量范围,哪些变量可从何处访问以及什么是“未定义变量"?错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:这是在PHP中处理变量范围的参考问题.请关闭所有适合此模式的问题,以作为该问题的重复.

什么是PHP中的变量范围"?一个.php文件中的变量可以在另一个文件中访问吗?为什么有时会出现未定义变量" 错误?

解决方案

什么是变量范围"?

变量具有有限的范围"或可从其访问的位置".仅仅因为您在应用程序中的 somewhere 中曾经写过$foo = 'bar';并不意味着您可以从应用程序内的 everywhere 中引用$foo.变量$foo在一定范围内有效,并且只有相同范围内的代码才能访问该变量.

如何在PHP中定义作用域?

非常简单:PHP具有功能范围.那是PHP中存在的唯一一种范围分隔符.函数内部的变量仅在该函数内部可用.函数外部的变量在函数外部的任何位置可用,但在任何函数内部均不可用.这意味着PHP中有一个特殊的作用域: global 作用域.在任何函数外部声明的任何变量都在此全局范围内.

示例:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;
}

$foo global 范围内,$bazmyFunc内的 local 范围内.只有myFunc中的代码可以访问$baz.只有代码外部 myFunc有权访问$foo.双方都无法访问对方:

<?php

$foo = 'bar';

function myFunc() {
    $baz = 42;

    echo $foo;  // doesn't work
    echo $baz;  // works
}

echo $foo;  // works
echo $baz;  // doesn't work

范围和包含的文件

文件边界不分开范围:

a.php

<?php

$foo = 'bar';

b.php

<?php

include 'a.php';

echo $foo;  // works!

相同的规则适用于include d代码,与适用于任何其他代码的规则相同:仅function单独的范围.出于范围的目的,您可能会考虑包括诸如复制和粘贴代码之类的文件:

c.php

<?php

function myFunc() {
    include 'a.php';

    echo $foo;  // works
}

myFunc();

echo $foo;  // doesn't work!

在上面的示例中,a.php被包含在myFunc中,a.php中的任何变量仅具有局部函数作用域.仅仅因为它们在a.php中出现在全局范围内并不一定意味着它们存在,实际上取决于它们包含/执行代码的上下文.

函数和类中的函数呢?

每个新的function声明都引入了一个新的作用域,就是这么简单.

(函数内部的)匿名函数

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';
    }

}

// no access to $baz

示波器有什么用?

处理范围问题似乎很烦人,但是有限的变量范围对于编写复杂的应用程序必不可少!如果声明的每个变量在应用程序中的其他任何地方都可用,那么您将分步进行没有真正的方法来跟踪变量的变化.您可以给变量赋予许多明智的名称,您可能希望在多个位置使用变量"$name".如果您只能在应用程序中使用一次唯一的变量名,则必须采用真正复杂的命名方案,以确保变量是唯一的,并且不会从错误的代码段中更改错误的变量. /p>

观察:

function foo() {
    echo $bar;
}

如果没有作用域,那么上面的函数会做什么? $bar来自哪里?它处于什么状态?它甚至被初始化了吗?每次都要检查吗?这是无法维持的.这带我们去...

跨越范围边界

正确的方法:传入和传出变量

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

变量$bar作为函数参数明确地进入此范围.仅查看此函数,就可以清楚知道其使用值的来源.然后,它明确返回一个值.调用者有信心知道该函数将使用哪些变量以及其返回值来自何处:

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

将变量的范围扩展到匿名函数中

$foo = 'bar';

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

$baz();

匿名函数从其周围范围显式包括$foo.请注意,这与 global 范围不同.

错误的方式:global

如前所述,全局范围有些特殊,函数可以从中显式导入变量:

$foo = 'bar';

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

此函数使用并修改全局变量$foo. 请勿这样做! (除非您真的真的真的知道自己在做什么,即使这样:不要!)

此函数的所有调用者看到的是:

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

没有迹象表明此功能有任何副作用,但确实有.由于某些函数不断修改并要求某些全局状态,因此这很容易成为一团糟.您希望函数无状态,仅对它们的输入起作用并返回定义的输出,无论您多次调用它们.

您应尽可能避免以任何方式使用全局范围;最肯定的是,您不应该将变量从全局范围拉"到局部范围.

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.

What is "variable scope" in PHP? Are variables from one .php file accessible in another? Why do I sometimes get "undefined variable" errors?

解决方案

What is "variable scope"?

Variables have a limited "scope", or "places from which they are accessible". Just because you wrote $foo = 'bar'; once somewhere in your application doesn't mean you can refer to $foo from everywhere else inside the application. The variable $foo has a certain scope within which it is valid and only code in the same scope has access to the variable.

How is a scope defined in PHP?

Very simple: PHP has function scope. That's the only kind of scope separator that exists in PHP. Variables inside a function are only available inside that function. Variables outside of functions are available anywhere outside of functions, but not inside any function. This means there's one special scope in PHP: the global scope. Any variable declared outside of any function is within this global scope.

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

Scope and included files

File boundaries do not separate scope:

a.php

<?php

$foo = 'bar';

b.php

<?php

include 'a.php';

echo $foo;  // works!

The same rules apply to included code as applies to any other code: only functions separate scope. For the purpose of scope, you may think of including files like copy and pasting code:

c.php

<?php

function myFunc() {
    include 'a.php';

    echo $foo;  // works
}

myFunc();

echo $foo;  // doesn't work!

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

What about functions inside functions and classes?

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

(anonymous) functions inside functions

function foo() {
    $foo = 'bar';

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

    // no access to $baz
}

classes

$foo = 'foo';

class Bar {

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

}

// no access to $baz

What is scope good for?

Dealing with scoping issues may seem annoying, but limited variable scope is essential to writing complex applications! If every variable you declare would be available from everywhere else inside your application, you'd be stepping all over your variables with no real way to track what changes what. There are only so many sensible names you can give to your variables, you probably want to use the variable "$name" in more than one place. If you could only have this unique variable name once in your app, you'd have to resort to really complicated naming schemes to make sure your variables are unique and that you're not changing the wrong variable from the wrong piece of code.

Observe:

function foo() {
    echo $bar;
}

If there was no scope, what would the above function do? Where does $bar come from? What state does it have? Is it even initialized? Do you have to check every time? This is not maintainable. Which brings us to...

Crossing scope boundaries

The right way: passing variables in and out

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

The variable $bar is explicitly coming into this scope as function argument. Just looking at this function it's clear where the values it works with originate from. It then explicitly returns a value. The caller has the confidence to know what variables the function will work with and where its return values come from:

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

Extending the scope of variables into anonymous functions

$foo = 'bar';

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

$baz();

The anonymous function explicitly includes $foo from its surrounding scope. Note that this is not the same as global scope.

The wrong way: global

As said before, 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 the global variable $foo. Do not do this! (Unless you really really really really know what you're doing, and even then: don't!)

All the caller of this function sees is this:

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

There's no indication that this function has any side effects, yet it does. This very easily becomes a tangled mess as some functions keep modifying and requiring some global state. You want functions to be stateless, acting only on their inputs and returning defined output, however many times you call them.

You should avoid using the global scope in any way as much as possible; most certainly you should not be "pulling" variables out of the global scope into a local scope.

这篇关于参考:什么是变量范围,哪些变量可从何处访问以及什么是“未定义变量"?错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆