2. 变量

基本概念

PHP中的变量是用一个美元符号跟变量名组合而成,变量名可以是字母、数字、下划线、中文组合而成,但变量名的首位不能是数字。

$this 是一个特殊的变量,不能对其赋值

定义变量

// 以下定义的变量其命名都合法
$foo123 = '刘德华';
$_bar456 = 'LiuDeHua';
$刘德华 = '对,就是我';

变量赋值

变量在赋值的时候,默认总是 传值赋值,还有一种是 引用赋值,使用引用赋值只需要在变量前面加上 & 符号即可,两者具体表现看下面代码。

  • 传值赋值
// 定义变量
$foo = 123;
$bar = $foo;
// 修改变量
$foo = 456;
// 此时 $bar 还是等于123
  • 引用赋值
// 定义变量
$foo = 123;
$bar = &$foo;
// 修改变量
$foo = 456;
// 此时 $bar 等于456

全局变量

PHP提供了大量的预定义变量,例如$_SERVER$_ENV$_REQUEST$_COOKIE等,这些变量有一个特性,就是拥有全局性,可以在项目中的任意代码位置使用,而不会得到一个变量未定义的错误提示。
其中许多变量会受到web服务器的版本和设置等原因而有所不同。

全局变量不能用作函数或是方法中的可变变量

变量范围

变量拥有自己的生效范围,也就是 作用域 ,官方称之为 ** 上下文背景 ** ,在作用域之外使用将会提示未定义。
作用域将影响到通过includerequire引入的文件

// 当前页面定义一个变量
$foobar = 'abc';

// $foobar 在 下面两个引入的文件中同样可以使用
include('a.php');
require('b.php');

// 反过来也是,引入文件中的变量在当前页面也可以使用

在函数中存在一个 局部作用域 ,使得函数外的变量在里头没法用,同样的,里面的变量,外面也无法使用。

$foobar = "123";
function hello(){
    echo $foobar;
}
// 不会有任何输出
hello();

上例中函数里的 $foobar 会提示未定义,因为PHP在寻找这个变量的定义时,不会跑到局部作用域外去寻找。

如果需要在函数里使用外部变量,需要使用global关键字声明。

$foobar = "123";
function hello(){
    // 声明此处的变量将引用外部变量
    global $foobar;
    echo $foobar;
}
// 输出 123
hello()

换种方式,也可以使用PHP自定义的$GLOBALS数组,这是一个预定义的超全局变量。

$foobar = "123";
function hello(){
    echo $GLOBALS['foobar'];
}
// 输出 123
hello();

静态变量

静态变量仅存在于函数的局部作用域中,但当程序离开该程序时,该变量的值却不丢失。

先看这个例子

function hello(){
    $count = 1;
    echo $count;
    $count++;
}
// 输出 1
hello();
// 输出 1
hello();

在这个例子中,hello函数的初衷显然是希望每次执行后便输出一个数字,同时将该数字递增,等待下次调用。
但实际上却在每一次调用的时候将其中的count变量重新进行定义和赋值,使得其永远都等于1

下面,使用静态变量后,再来看。

function hello(){
    static $count = 1;
    echo $count;
    $count++;
}
// 输出 1
hello();
// 输出 2
hello();

这个例子中发生了变化的就是在 $count 变量的声明处增加了 static 关键字,表明 $count 变量是一个静态变量。
静态变量将在PHP编译时进行解析,而不是等你运行时才去解析,换而言之,PHP在你还没运行程序之前就已经将该变量进行声明和定义了,等到你去运行代码的时候,可能此时的代码在PHP看来,会变成了这个样子:

function hello(){
    // $count 已定义好且保管妥当,你尽管用。
    echo $count;
    $count++;
}

可变变量

可变变量,指的是一个变量的变量名是动态的,或者说它的变量名是另一个变量的值,因此它的实际变量名会跟随着另一个变量的值而进行变化。

  • 普通变量

    // 我的变量名固定是 foo,没办法变
    $foo = 'hello';
    
    // 我的变量名是动态的,依赖于$foo变量的值,它改我也改
    $$foo = 'world';
    
    // 正常调用
    echo $foo . ' ' . $$foo . '
    '; // 也可以这么调用 echo $foo . ' ' . $hello . '
    '; // 花式调用 echo "$foo ${$foo}";
  • 数组变量

    // 基本变量
    $a = "test";
    $foobar = 'array';
    // 可变变量的数组
    $$foobar = ['hello', 'world'];
    // 输出hello
    echo $$foobar[0];
    

    在这个例子中,有一点难以让人一眼明确,那就是$$foobar[0],因为这个表达式在多年后让别人去看容易产生歧义。
    其一:先获取$$foobar数组,然后[0]根据索引得到值,事实上PHP就是这么理解的。
    其二:先获取$foobar[0]字符串中的第一个字符,得到$a最终获取的值为test
    所以,为避免这种难以区分理解的尴尬,可以使用界定符 {} 来隔开。

    // 输出hello
    echo ${$foobar}[0];
    
    // 输出test
    echo ${$foobar[0]};
    
  • 对象属性

    // 定义类
    class Example{
      public $foo = " hello world ";
      public $bar = [' php ', ' mysql ', ' redis '];
      public static function hello(){
          echo 'nihao';
      }
    }
    // 实例化
    $exam = new Example();
    // 第一种
    echo $exam->{'foo'};
    echo $exam->{'bar'}[1];
    
    // 第二种
    $f = 'foo';
    $b = 'bar';
    echo $exam->{$f};
    echo $exam->{$b}[1];
    
    // 第三种
    echo $exam->$f;
    echo $exam->$b[1];
    
    // 保存类名
    $class = 'Example';
    // 花式调用
    $class::hello();
    // 实例化
    $exam = new $class();
    // 调用
    $exam::hello();
    

你可能感兴趣的:(2. 变量)