PHP 变量

蘑菇| 阅读:10 发表时间:2017-07-03 14:46 概念

基础

PHP 中的变量用一个美元符号后面跟变量名来表示。变量名是区分大小写的


变量名与 PHP 中其它的标签一样遵循相同的规则。一个有效的变量名由字母或者下划线开头,后面跟上任意数量的字母,数字,或者下划线。按照正常的正则表达式,它将被表述为:'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'。

注:

① 在此所说的字母是 a-z,A-Z,以及 ASCII 字符从 127 到 255(0x7f-0xff)。

② $this 是一个特殊的变量,它不能被赋值。


变量默认总是传值赋值。那也就是说,当将一个表达式的值赋予一个变量时,整个原始表达式的值被赋值到目标变量。这意味着,例如,当一个变量的值赋予另外一个变量时,改变其中一个变量的值,将不会影响到另外一个变量。


PHP 也提供了另外一种方式给变量赋值:引用赋值。这意味着新的变量简单的引用(换言之,“成为其别名”或者“指向”)了原始变量。改动新的变量将影响到原始变量,反之亦然。


使用引用赋值,简单地将一个 & 符号加到将要赋值的变量前(源变量)。例如,下列代码片断将输出“My name is Bob”两次:

$foo = 'Bob';              // 将 'Bob' 赋给 $foo
$bar = &$foo;              // 通过 $bar 引用 $foo
$bar = "My name is $bar";  // 修改 $bar 变量
echo $bar;
echo $foo;                 // $foo 的值也被修改


有一点重要事项必须指出,那就是只有有名字的变量才可以引用赋值。

$foo = 25;
$bar = &$foo;      // 合法的赋值
$bar = &(24 * 7);  // 非法; 引用没有名字的表达式

function test()
{
   return 25;
}

$bar = &test();    // 非法


虽然在 PHP 中并不需要初始化变量,但对变量进行初始化是个好习惯。未初始化的变量具有其类型的默认值 - 布尔类型的变量默认值是 FALSE,整形和浮点型变量默认值是零,字符串型变量(例如用于 echo 中)默认值是空字符串以及数组变量的默认值是空数组。


预定义变量

PHP 提供了大量的预定义变量。由于许多变量依赖于运行的服务器的版本和设置,及其它因素,所以并没有详细的说明文档。


超级全局变量不能被用作函数或类方法中的可变变量。


变量范围

变量的范围即它定义的上下文背景(也就是它的生效范围)。大部分的 PHP 变量只有一个单独的范围。这个单独的范围跨度同样包含了 include 和 require 引入的文件。例如:

$a = 1;
include 'b.inc';

这里变量 $a 将会在包含文件 b.inc 中生效。但是,在用户自定义函数中,一个局部函数范围将被引入。任何用于函数内部的变量按缺省情况将被限制在局部函数范围内。例如:

$a = 1; /* global scope */

function Test()
{
    echo $a; /* reference to local scope variable */
}

Test();

这个脚本不会有任何输出,因为 echo 语句引用了一个局部版本的变量 $a,而且在这个范围内,它并没有被赋值。你可能注意到 PHP 的全局变量和 C 语言有一点点不同,在 C 语言中,全局变量在函数中自动生效,除非被局部变量覆盖。这可能引起一些问题,有些人可能不小心就改变了一个全局变量。

PHP 中全局变量在函数中使用时必须声明为 global


使用静态变量

变量范围的另一个重要特性是静态变量(static variable)。静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失。看看下面的例子:

function Test()
{
    $a = 0;
    echo $a;
    $a++;
}

本函数没什么用处,因为每次调用时都会将 $a 的值设为 0 并输出 0。将变量加一的 $a++ 没有作用,因为一旦退出本函数则变量 $a 就不存在了。要写一个不会丢失本次计数值的计数函数,要将变量 $a 定义为静态的:

function test()
{
    static $a = 0;
    echo $a;
    $a++;
}

现在,变量 $a 仅在第一次调用 test() 函数时被初始化,之后每次调用 test() 函数都会输出 $a 的值并加一。

 

静态变量也提供了一种处理递归函数的方法。递归函数是一种调用自己的函数。写递归函数时要小心,因为可能会无穷递归下去。必须确保有充分的方法来中止递归。以下这个简单的函数递归计数到 10,使用静态变量 $count 来判断何时停止:

function test()
{
    static $count = 0;

    $count++;
    echo $count;
    if ($count < 10) {
        test();
    }
    $count--;
}

静态变量可以按照上面的例子声明。如果在声明中用表达式的结果对其赋值会导致解析错误。

function foo(){
    static $int = 0;          // correct
    static $int = 1+2;        // wrong  (as it is an expression)
    static $int = sqrt(121);  // wrong  (as it is an expression too)

    $int++;
    echo $int;
}

静态声明是在编译时解析的。


在函数之外使用 global 关键字不算错。可以用于在一个函数之内包含文件时。


可变变量

有时候使用可变变量名是很方便的。就是说,一个变量的变量名可以动态的设置和使用。一个普通的变量通过声明来设置,例如:

$a = 'hello';

一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。在上面的例子中 hello 使用了两个美元符号($)以后,就可以作为一个可变变量的变量了。例如:

$a = 'world';

这时,两个变量都被定义了:$a 的内容是“hello”并且 $hello 的内容是“world”。因此,以下语句:

echo "$a ${$a}";

与以下语句输出完全相同的结果:

echo "$a $hello";

它们都会输出:hello world。


要将可变变量用于数组,必须解决一个模棱两可的问题。这就是当写下 $$a[1] 时,解析器需要知道是想要 $a[1] 作为一个变量呢,还是想要 $$a 作为一个变量并取出该变量中索引为 [1] 的值。解决此问题的语法是,对第一种情况用 ${$a[1]},对第二种情况用 ${$a}[1]。


类的属性也可以通过可变属性名来访问。可变属性名将在该调用所处的范围内被解析。例如,对于 $foo->$bar 表达式,则会在本地范围来解析 $bar 并且其值将被用于 $foo 的属性名。对于 $bar 是数组单元时也是一样。


也可使用花括号来给属性名清晰定界。最有用是在属性位于数组中,或者属性名包含有多个部分或者属性名包含有非法字符时。

class foo {
    var $bar = 'I am bar.';
    var $arr = array('I am A.', 'I am B.', 'I am C.');
    var $r   = 'I am r.';
}

$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo $foo->$bar;         // I am bar.
echo $foo->$baz[1];    // I am bar.

$start = 'b';
$end   = 'ar';
echo $foo->{$start . $end};      // I am bar.

$arr = 'arr';
echo $foo->$arr[1];      // I am r.
echo $foo->{$arr}[1];    // I am B.


注意,在 PHP 的函数和类的方法中,超全局变量不能用作可变变量。$this 变量也是一个特殊变量,不能被动态引用。


来自 PHP 之外的变量

① HTML 表单(GET 和 POST)

当一个表单提交给 PHP 脚本时,表单中的信息会自动在脚本中可用。


② IMAGE SUBMIT 变量名

当提交表单时,可以用一幅图像代替标准的提交按钮。


③ HTTP Cookies

PHP 透明地支持 » RFC 6265定义中的 HTTP cookies。

Cookies 是一种在远端浏览器端存储数据并能追踪或识别再次访问的用户的机制。

可以用 setcookie() 函数设定 cookies。Cookies 是 HTTP 信息头中的一部分,因此 SetCookie 函数必须在向浏览器发送任何输出之前调用。对于 header() 函数也有同样的限制。Cookie 数据会在相应的 cookie 数据数组中可用。


注意在浏览器中一个 cookie 会替换掉上一个同名的 cookie,除非路径或者域不同。因此对于购物车程序可以保留一个计数器并一起传递。

版权声明:
1.本文仅代表作者观点,不代表蒙奇蘑菇的立场。
2.本文系作者授权蒙奇蘑菇发表,未经许可,不得转载。如有侵权,请联系本站删除。