PHP手册总结

类型

简介

PHP 支持 10 种原始数据类型

四种标量类型:

  • bool(布尔型)
  • int(整型)
  • float(浮点型,也称作 double)
  • string(字符串)

四种复合类型:

  • array(数组)
  • object(对象)
  • callable(可调用)
  • iterable(可迭代)

两种特殊类型:

  • resource(资源)
  • NULL(无类型)

“双精度(double)”类型,实际上和 float 是相同的,由于一些历史的原因,这两个名称同时存在。
得到一个易读懂的类型的表达方式,用 gettype() 函数。要检验某个类型,用 is_type 函数。

Boolean 布尔类型

bool 表达了真值,可以为 true 或 false,两个都不区分大小写。

转换为布尔值
  1. 用 (bool) 或者 (boolean) 来强制转换
  2. 自动转换

当转换为 bool 时,以下值被认为是 false:

  • 布尔值 false 本身
  • 整型值 0(零)
  • 浮点型值 0.0(零)-0.0(零)
  • 空字符串,以及字符串 “0”
  • 不包括任何元素的数组
  • 特殊类型 NULL(包括尚未赋值的变量)
  • 由无属性的空元素创建 SimpleXML 对象,也就是既没有子节点也没有属性的元素。

所有其它值都被认为是 true(包括任何资源 和 NAN)。

字符串’0.0’,-1 和其它非零值(不论正负),被认为是 true!

Integer 整型

整型值 int 可以使用十进制,十六进制,八进制或二进制表示,前面可以加上可选的符号(- 或者 +)。 可以用 负运算符 来表示一个负的int。
要使用八进制表达,数字前必须加上 0(零)。
PHP 8.1.0 起,八进制表达也可以在前面加上 0o 或者 0O 。 要使用十六进制表达,数字前必须加上 0x。要使用二进制表达,数字前必须加上 0b。
PHP 7.4.0 开始,整型数值可能会包含下划线 (_)
整型数 int 的字长和平台有关。64 位平台下的最大值通常是大约 9E18。 PHP 不支持无符号的 int。int 值的字长可以用常量 PHP_INT_SIZE来表示, 最大值可以用常量 PHP_INT_MAX 来表示, 最小值可以用常量 PHP_INT_MIN 表示。

整数溢出

如果给定的一个数超出了 int 的范围,将会被解释为 float。同样如果执行的运算结果超出了 int 范围,也会返回 float。
PHP 没有 int 除法取整运算符,要使用 intdiv() 实现。 1/2 产生出 float 0.5。强制转换为 int,值会舍弃小数部分。使用 round() 函数会地进行四舍五入。

intdiv(int $dividend, int $divisor): int

  • dividend 除以 divisor ,对该商取整
  • 如果 divisor 是 0,将抛出 DivisionByZeroError 异常
  • 如果 dividend 是 PHP_INT_MIN 并且 divisor 是 -1,将抛出 ArithmeticError 异常
转换为整型
  • 用 (int) 或 (integer) 强制转换
  • intval() 将一个值转换成 int 整型
  • 自动转换

从布尔值转换

  • false 将产生出 0(零),true 将产生出 1(壹)

从浮点型转换

  • 当从浮点数 float 转换成整数 int 时,将向下取整。
  • 如果浮点数超出了 int 范围,结果为未定义
  • NaN 和 Infinity 在转换成 int 时是零
  • 将未知的分数强制转换为 int,这样有时会导致不可预料的结果

从字符串转换

  • 如果 string 是 numeric 或者前导数字, 则将它解析为相应的 int 值,否则将转换为零(0)

从 NULL 转换

  • null 会转换为零(0)

从其它类型转换

  • 没有定义从其它类型转换为 int 的行为

Float 浮点型

浮点型(也叫浮点数 float,双精度数 double 或实数 real)

浮点数的精度

浮点数的精度有限。非基本数学运算可能会给出更大误差,如果确实需要更高的精度,应该使用任意精度数学函数或者 gmp 函数。

  • bcadd — 两个任意精度数字的加法计算
  • bccomp — 比较两个任意精度的数字
  • bcdiv — 两个任意精度的数字除法计算
  • bcmod — 任意精度数字取模
  • bcmul — 两个任意精度数字乘法计算
  • bcpow — 任意精度数字的乘方
  • bcpowmod — Raise an arbitrary precision number to another, reduced by a specified modulus
  • bcscale — 设置/获取所有
  • bc math 函数的默认小数点保留位数
  • bcsqrt — 任意精度数字的二次方根
  • bcsub — 两个任意精度数字的减法
转换为浮点数

从 string 转换

  • 如果 string 是 numeric 或者前导数字, 则将它解析为相应的 float 值,否则将转换为零(0)

从其他类型转换

  • 对于其它类型的值,其情况类似于先将值转换成 int,然后再转换成 float
比较浮点数

要使用一个仅比该数值大一丁点的最小误差值。该值也被称为机器极小值(epsilon)或最小单元取整数,是计算中所能接受的最小的差别值。

<?php
//$a 和 $b 在小数点后五位精度内都是相等的
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;

if(abs($a-$b) < $epsilon) {
    echo "true";
}
?>
NaN

某些数学运算会产生一个由常量 NAN 所代表的结果。此结果代表着一个在浮点数运算中未定义或不可表述的值。任何拿此值与其它任何值(除了 true)进行的松散或严格比较的结果都是 false。
由于 NAN 代表着任何不同值,不应拿 NAN 去和其它值进行比较,包括其自身,应该用 is_nan() 来检查。

String 字符串

一个字符串 string 就是由一系列的字符组成,其中每个字符等同于一个字节。这意味着 PHP 只能支持 256 的字符集,因此不支持 Unicode

语法
  1. 单引号
  2. 双引号
  3. heredoc 语法结构

没有双引号的双引号string
PHP 7.3.0 之前的版本中,结束时所引用的标识符必须在该行的第一列
结束标识符的缩进不能超过正文的任何一行 缩进结束标识符和内容,
制表符和空格不能混合使用
内容字符串的结束标识符后面不需要跟分号或者换行符
不要选择正文内容中出现的词作为结束标识符

$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

/* 含有变量的更复杂示例 */
class foo
{
    var $foo;
    var $bar;

    function __construct()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;

My name is “MyName”. I am printing some Foo.
Now, I am printing some Bar2.
This should print a capital ‘A’: A

  1. nowdoc 语法结构

单引号字符串

/* 含有变量的更复杂的示例 */
class foo
{
    public $foo;
    public $bar;

    function __construct()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
EOT;

My name is “$name”. I am printing some $foo->foo.

Now, I am printing some {$foo->bar[1]}.
This should not print a capital ‘A’: \x41

变量解析
  • 简单规则
    美元符号($)
  • 复杂规则
    花括号 { 和 }
    只有 $ 紧挨着 { 时才会被识别,用 {\ $ 来表达 {$
存取和修改字符串中的字符
  • 可以通过一个从 0 开始的下标,用类似 array 结构中的方括号包含对应的数字来访问和修改,函数 substr() 和 substr_replace() 可用于操作多于一个字符的情况
  • PHP 7.1.0 开始,支持 string 负偏移量,以前,负偏移量读取时(返回空 string)会发出 E_NOTICE, 写入时(string 保持不变)会发出E_WARNING。
  • PHP 8.0.0 之前, 可以使用大括号访问 string,例如 $str{42}。PHP 7.4.0
    起,此大括号语法被弃用,PHP 8.0.0 开始不再受支持
  • PHP 7.1.0 开始,对空字符串应用空索引运算符会引发致命错误。 以前是空字符串会被静默转为数组
  • 字符串下标必须为整数或可转换为整数的字符串,否则会发出警告
  • 用 [] 或 {} 访问任何其它类型(不包括数组或具有相应接口的对象实现)的变量只会无声地返回 null
有用的函数和运算符

字符串可以用 ‘.’(点)运算符连接起来

转换成字符串
  1. (string) 或用 strval() 函数
  2. 自动转换
  • 一个布尔值 bool 的 true 被转换成 string 的 “1”。bool 的 false 被转换成 “”(空字符串) 一个整数
  • int 或浮点数 float 被转换为数字的字面样式的 string(包括 float
    中的指数部分)。使用指数计数法的浮点数(4.1E+6)也可转换
  • 数组 array 总是转换成字符串 “Array” 必须使用魔术方法
  • __toString 才能将 object 转换为 string
  • 资源 Resource 总会被转变成 “Resource id #1”,可以用函数 get_resource_type()
  • null 总是被转变成空字符串
  • 大部分的 PHP 值可以转变成 string 来永久保存,这被称作串行化,可以用函数 serialize() 来实现
字符串类型详解

PHP 中的 string 的实现方式是一个由字节组成的数组再加上一个整数指明缓冲区长度

数字字符串

如果一个 PHP string 可以被解释为 int 或 float 类型,则它被视为数字字符串
当一个 string 需要被当作一个数字计算时,(例如:算术运算, int 类型声明等),则采取以下步骤来确定结果:

  1. 如果 string 是数字,当 string 是整数字符串并且符合 int 类型的范围限制(即是 PHP_INT_MAX 定义的值),则解析为 int ,否则解析为 float 。
  2. 上下文允许前导数字和一个 string,如果 string 的前导部分是整数数字字符串且符合 int 类型限制(由 PHP_INT_MAX 定义),则解析为 int ,否则解析为 float 。 此外,还会导致 E_WARNING 级别的错误。
  3. 果 string 不是数字,则会抛出一个 TypeError 的异常。
PHP 8.0.0 之前的行为

在 PHP 8.0.0 之前, 只有在前导空格的时候,string 才被认为是数字;如果它有尾随空格,则该字符串被视为是前导数字。

在 PHP 8.0.0 之前,当在数字上下文中使用字符串时,它将执行与上述相同的步骤,但有以下区别:

  • 使用前导数字字符串将导致 E_NOTICE 而不是 E_WARNING 错误。
  • 如果字符串不是数字,则会导致 E_WARNING 错误并返回 0 。

在 PHP 7.1.0 之前,则既不会导致 E_NOTICE,也不会导致 E_WARNING。

Array 数组

语法

定义数组

  • array()
  • 短数组语法 []

key 可以是 integer 或者 string。value 可以是任意类型

  • String 中包含有效的十进制 int,除非数字前面有一个 + 号,否则将被转换为 int 类型。
  • Float 也会被转换为 int ,意味着其小数部分会被舍去。
  • Bool 也会被转换成 int。
  • Null 会被转换为空字符串,即键名 null 实际会被储存为 “”。
  • Array 和 object 不能 被用为键名。坚持这么做会导致警告:Illegal offset type。

key 为可选项。如果未指定,PHP 将自动使用之前用过的最大 int 键名加上 1 作为新的键名

用方括号语法访问数组单元

数组单元可以通过 array[key] 语法来访问
试图访问一个未定义的数组键名与访问任何未定义变量一样:会导致 E_NOTICE 级别错误信息,其结果为 null。

用方括号的语法新建/修改

在方括号内指定键名来给 array 赋值实现的。也可以省略键名
PHP 7.1.0 起,对字符串应用空索引操作符会抛出致命错误。以前,字符串被静默地转换为数组。
PHP 8.1.0 起,弃用从 false 值中创建一个新数组。 但仍然允许从 null 或者未定义的变量中创建新数组
要修改某个值,通过其键名给该单元赋一个新值。要删除某键值对,对其调用 unset() 函数
如果给出方括号但没有指定键名,则取当前最大 int 索引值,新的键名将是该值加上 1(但是最小为 0)。如果当前还没有 int 索引,则键名将为 0

实用函数

unset() 函数允许删除 array 中的某个键,数组将不会重建索引
array_values() 函数重建 array 索引

转换为数组
  • 对于任意 int,float, string,bool 和 resource 类型,如果将一个值转换为 array,将得到一个仅有一个元素的数组,其下标为 0,该元素即为此标量的值
  • object 类型转换为 array,则结果为一个数组,其单元为该对象的属性
比较

array_diff() 函数

返回一个数组,该数组包括了所有在 array 中但是不在任何其它参数数组中的值,保留数组 array 里的键

数组运算符

例子名称结果
$a + $b联合$a 和 $b 的联合
$a == $b相等如果 $a 和 $b 具有相同的键/值对则为 true
$a === $b全等如果 $a 和 $b 具有相同的键/值对并且顺序和类型都相同则为 true
$a != $b不等如果 $a 不等于 $b 则为 true
$a <> $b不等如果 $a 不等于 $b 则为 true
$a !== $b不全等如果 $a 不全等于 $b 则为 true
数组解包

在 array 定义时,用 … 前缀的一个 array 可以被展开到当前位置,PHP 7.4.0 开始可以使用
… 操作符解包 array 时也遵守函数 array_merge() 的语义。key 为字符时,后面的字符键会覆盖之前的字符键;key 为 integer 时则会重新编号
既不是 integer 也不是 string 的 key 会抛出 TypeError
在 PHP 8.1 之前,带有 string 键的 array 无法解包

Iterable 可迭代对象

PHP 7.1 中引入的一个伪类型,可迭代对象可以用作参数类型,表示函数需要一组值, 但是不会关心值集的形式,还可以用作返回类型,表示函数将返回一个可迭代的值

Object 对象

对象初始化

要创建一个新的对象 object,使用 new 语句实例化一个类

转换为对象
  • 如果将一个对象转换成对象,它将不会有任何变化。
  • 如果其它任何类型的值被转换成对象,将会创建一个内置类 stdClass 的实例。
  • 如果该值为 null,则新的实例为空。
  • array 转换成 object 将使键名成为属性名并具有相对应的值
  • PHP 7.2.0 之前的版本,数字键只能通过迭代访问
  • 其他值,会包含进成员变量名 scalar
  • 例子:
$bar = 'string';
var_dump((object)$bar);
//返回值
object(stdClass)#34 (1) {
  ["scalar"]=>
  string(6) "string"
}

Enum 枚举

(PHP 8 >= 8.1.0)

枚举基础

基础上的约束层, 目标是提供一种能力:定义包含可能值的封闭集合类型

类型转换
  • 将 enum 转换为 object 不会有变化。
  • 将 enum 转换为 array, 纯粹枚举会创建单个 name 键的数组; 回退枚举创建带 name 和 value 键的数组。
  • 其他类型转换都会导致错误
<?php
enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

function do_stuff(Suit $s)
{
    // ...
}

do_stuff(Suit::Spades);
?>

Resource 资源类型

资源 resource 是一种特殊变量,保存了到外部资源的一个引用。资源是通过专门的函数来建立和使用的

转换为资源

由于资源类型变量保存有为打开文件、数据库连接、图形画布区域等的特殊句柄,因此将其它类型的值转换为资源没有意义

释放资源

引用计数系统是 Zend 引擎的一部分,可以自动检测到一个资源不再被引用了(和 Java 一样)。这种情况下此资源使用的所有外部资源都会被垃圾回收系统释放。因此,很少需要手工释放内存

NULL

特殊的 null 值表示一个变量没有值。NULL 类型唯一可能的值就是 null。
在下列情况下一个变量被认为是 null:

  • 被赋值为 null。
  • 尚未被赋值。
  • 被 unset()。
语法

null 类型只有一个值,就是不区分大小写的常量 null。

<?php
$var = NULL;       
?>

参见 is_null() 和 unset()

转换到 NULL

本特性自 PHP 7.2.0 起废弃,并且自 PHP 8.0.0 起被移除
使用 (unset) $var 将一个变量转换为 null 将不会删除该变量或 unset 其值。仅是返回 null 值而已

Callback / Callable 类型

回调可以通过 callable 类型声明来表示

传递

PHP是将函数以string形式传递的。 可以使用任何内置或用户自定义函数,但除了语言结构例如:array(),echo,empty(),eval(),exit(),isset(),list(),print 或 unset()

<?php 

// 回调函数示范
function my_callback_function() {
    echo 'hello world!';
}

// 回调方法示范
class MyClass {
    static function myCallbackMethod() {
        echo 'Hello World!';
    }
}

// 类型 1:简单的回调
call_user_func('my_callback_function'); 

// 类型 2:静态类方法回调
call_user_func(array('MyClass', 'myCallbackMethod')); 

// 类型 3:对象方法回调
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));

// 类型 4:静态类方法回调
call_user_func('MyClass::myCallbackMethod');

// 类型 5:父级静态类回调
class A {
    public static function who() {
        echo "A\n";
    }
}

class B extends A {
    public static function who() {
        echo "B\n";
    }
}

call_user_func(array('B', 'parent::who')); // A

// 类型 6:实现 __invoke 的对象用于回调
class C {
    public function __invoke($name) {
        echo 'Hello ', $name, "\n";
    }
}

$c = new C();
call_user_func($c, 'PHP!');

// 闭包
$double = function($a) {
    return $a * 2;
};

// 这是数字范围
$numbers = range(1, 5);

// 这里使用闭包作为回调,
// 将范围内的每个元素数值翻倍
$new_numbers = array_map($double, $numbers);

print implode(' ', $new_numbers); //2 4 6 8 10

类型声明

类型声明可以用于函数的参数、返回值,PHP 7.4.0 起还可以用于类的属性,来显性的指定需要的类型,如果预期类型在调用时不匹配,则会抛出一个 TypeError 异常

单一类型
类型说明版本
类/接口 名称值必须为指定类和接口的实例化对象 instanceof
self值必须是用于类型声明相同类的 instanceof 。 仅可在类中使用。
parent值必须是用于类型声明父级类的 instanceof , 仅可在类中使用。
array值必须为 array。
callable值必定是一个有效的 callable。 不能用于类属性的类型声明。
bool值必须为一个布尔值。
float值必须为一个浮点数字。
int值必须为一个整型数字。
string值必须为一个 string。
iterable值必须为 array 或 instanceof Traversable。PHP 7.1.0
object值必须为object。PHP 7.2.0
mixed值可以为任何类型。PHP 8.0.0
mixed

mixed 等同于 联合类型 object|resource|array|string|int|float|bool|null。PHP 8.0.0 起可用

范例
<?php
//在类中使用类型声明
class C {}
class D extends C {}

// 它没有 extend C。
class E {}

function f(C $c) {
    echo get_class($c)."\n";
}

f(new C);
f(new D);
f(new E);
//在接口中使用类型声明
interface I { public function f(); }
class C implements I { public function f() {} }

// 它没有 implement I。
class E {}

function f(I $i) {
    echo get_class($i)."\n";
}

f(new C);
f(new E);
//返回类型声明
function sum($a, $b): float {
    return $a + $b;
}

// 注意必须返回一个 float。
var_dump(sum(1, 2));
//返回一个对象
class C {}

function getC(): C {
    return new C;
}

var_dump(getC());
?>
允许为空的(Nullable)类型

PHP 7.1.0 起,类型声明允许前置一个问号 (?) 用来声明这个值允许为指定类型,或者为 null

<?php
//定义可空(Nullable)的参数类型
class C {}

function f(?C $c) {
    var_dump($c);
}

f(new C);
f(null);
//返回值
object(C)#1 (0) {
}
NULL
//定义可空(Nullable)的返回类型
function get_item(): ?string {
    if (isset($_GET['item'])) {
        return $_GET['item'];
    } else {
        return null;
    }
}
联合类型

联合类型接受多个不同的类型做为参数。声明联合类型的语法为 T1|T2|…。联合类型自 PHP 8.0.0 起可用

允许为空的联合类型

null 类型允许在联合类型中使用,例如 T1|T2|null 代表接受一个空值为参数。已经存在的 ?T 语法可以视为以下联合类型的一个简写 T|null
null 不能作为一个独立的类型使用

false 伪类型

通过联合类型支持字面类型(Literal Type)false, 出于历史原因,很多内部函数在失败时返回了 false 而不是 null。 这类函数的典型例子是 strpos()
false 不能单独作为类型使用(包括可空 nullable 类型)。 因此,false、false|null、 ?false 都是不可以用的
true 字面类型不存在

重复冗余的类型

为了能在联合类型声明中暴露简单的 bug,不需要加载 class 就可以在编译时让重复冗余的类型产生错误。 包含:

  • 解析出来的类型只能出现一次。例如这样的类型 int|string|INT 会导致错误。
  • 使用了 bool 时就不能再附带使用 false。
  • 使用了 object 时就不能再附带使用 class 类型。
  • 使用了 iterable 时,array、 Traversable 都不能再附带使用。

不过它不能确保类型最小化,因为要达到这样的效果,还要加载使用类型的 class
例如,假设 A 和 B 都是一个类的别名, 而 A|B 仍然是有效的,哪怕它可以被简化为 A 或 B。 同样的,如果 B extends A {},那 A|B 仍然是有效的联合类型,尽管它可以被简化为 A。

<?php
function foo(): int|INT {} // 不允许
function foo(): bool|false {} // 不允许

use A as B;
function foo(): A|B {} // 不允许 ("use" 是名称解析的一部分)

class_alias('X', 'Y');
function foo(): X|Y {} // 允许 (运行时才能知道重复性)
?>
仅仅返回类型
void

void 是一个返回类型,用于标识函数没有返回值。 它不能是联合类型的一部分。 PHP 7.1.0 起可用
PHP 8.1.0 起弃用引用返回 void 的函数, 因为这样的函数是矛盾的

never

never 是一种表示没有返回的返回类型。这意味着它可能是调用 exit(), 抛出异常或者是一个无限循环。所以,它不能作为联合类型的一部分。PHP 8.1.0 起可用。

在类型理论用于中,never 是底层类型。 意味着它是其它所有类型的子类型,并且可以在继承期间替换任何其他返回类型。

static

它的值必须是一个 class 的 instanceof,该 class 是调用方法所在的同一个类。 PHP 8.0.0 起有效。

严格类型

PHP 会强制转化不合适的类型为想要的标量类型。 比如,参数想要 string,传入的是 int, 则会获取 string 类型的变量
可以按文件开启严格模式。 在严格模式下,只能接受完全匹配的类型,否则会抛出 TypeError。 唯一的例外是 int 值也可以传入声明为 float 的类型
通过内部函数调用函数时,不会受 strict_types 声明影响
要开启严格模式,使用 declare 开启 strict_types:
注意:
文件开启严格类型后的内部调用函数将应用严格类型, 而不是在声明函数的文件内开启。 如果文件没有声明开启严格类型,而被调用的函数所在文件有严格类型声明, 那将遵循调用者的设置(开启类型强制转化), 值也会强制转化。
注意:
只有为标量类型的声明开启严格类型。

<?php
declare(strict_types=1);

function sum(int $a, int $b) {
    return $a + $b;
}

var_dump(sum(1, 2));
var_dump(sum(1.5, 2.5));
?>
联合类型的内部隐式强制转化

没有开启 strict_types 时,标量类型可能会限制内部隐式类型转化。 如果值的类型不是联合类型中的一部分,则目标类型会按以下顺序:

  1. int
  2. float
  3. string
  4. bool

如果类型出现在组合中,值可以按 PHP 现有的类型语义检测进行内部隐式强制转化,则会选择该类型。 否则会尝试下一个类型。
警告
有一个例外:当值是字符串,而 int 与 float 同时在组合中,将按现有的“数字字符串”检测语义,识别首选的类型。 例如,“42” 会选择 int 类型, 而 “42.0” 会选择 float 类型。
注意
没有出现在上面列表中的类型则不是有效的内部隐式转化目标。 尤其是不会出现内部隐式转化 null 和 false 类型。

<?php
// int|string
42    --> 42          // 类型完全匹配
"42"  --> "42"        // 类型完全匹配
new ObjectWithToString --> "__toString() 的结果"
                      // object 不兼容 int,降级到 string
42.0  --> 42          // float 与 int 兼容
42.1  --> 42          // float 与 int 兼容
1e100 --> "1.0E+100"  // float 比 int 大太多了,降级到 string
INF   --> "INF"       // float 比 int 大太多了,降级到 string
true  --> 1           // bool 与 int 兼容
[]    --> TypeError   // array 不兼容 int 或 string

// int|float|bool
"45"    --> 45        // int 的数字字符串
"45.0"  --> 45.0      // float 的数字字符串

"45X"   --> true      // 不是数字字符串,降级到 bool
""      --> false     // 不是数字字符串,降级到 bool
"X"     --> true      // 不是数字字符串,降级到 bool
[]      --> TypeError // array 不兼容 int、float、bool
?>
其他

示例 #12 传引用参数的类型

仅仅会在函数入口检查传引用的参数类型,而不是在函数返回时检查。 所以函数返回时,参数类型可能会发生变化。

<?php
function array_baz(array &$param)
{
    $param = 1;
}
$var = [];
array_baz($var);
var_dump($var);
array_baz($var);
?>

类型转换的判别

PHP 在变量定义中不需要(或不支持)明确的类型定义;变量类型是根据使用该变量的上下文所决定的

类型强制转换

在要转换的变量之前加上用括号括起来的目标类型
允许的强制转换有:

  • (int), (integer) - 转换为整形 int
  • (bool), (boolean) - 转换为布尔类型 bool
  • (float), (double), (real) - 转换为浮点型 float
  • (string) - 转换为字符串 string
  • (array) - 转换为数组 array
  • (object) - 转换为对象 object
  • (unset) - 转换为 NULL

向前兼容 (binary) 转换和 b 前缀转换。注意 (binary) 转换和 (string) 基本相同,但是不应该依赖它。

(unset) 转换在 PHP 7.2.0 中已被废弃。请注意 (unset) 转换等于将值赋予 NULL。(unset) 转换已经在 PHP 8.0.0 中被移除。

注意在括号内允许有空格和制表符,所以下面两个例子功能相同:

<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>

变量

预定义变量

PHP 提供了大量的预定义变量
PHP 提供了一套附加的预定数组,这些数组变量包含了来自 web 服务器(如果可用),运行环境,和用户输入的数据,它们在全局范围内自动生效

变量范围

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

global 关键字
$a = 1;
$b = 2;

function Sum()
{
    global $a, $b;

    $b = $a + $b;
}
function Sum()
{
    $GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}

Sum();
echo $b;
使用静态变量

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

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

赋值给静态变量,但是动态表达式(比如函数调用)会导致解析错误
静态声明是在编译时解析的

全局和静态变量的引用

对于变量的 static 和 global 定义是以引用的方式实现的。例如,在一个函数域内部用 global 语句导入的一个真正的全局变量实际上是建立了一个到全局变量的引用。这有可能导致预料之外的行为

function test_global_ref() {
    global $obj;
    $new = new stdclass;
    $obj = &$new;
}

function test_global_noref() {
    global $obj;
    $new = new stdclass;
    $obj = $new;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
//返回值
NULL
object(stdClass)#1 (0) {
}

function &get_instance_ref() {
    static $obj;

    echo 'Static object: ';
    var_dump($obj);
    if (!isset($obj)) {
        $new = new stdclass;
        // 将一个引用赋值给静态变量
        $obj = &$new;
    }
    if (!isset($obj->property)) {
        $obj->property = 1;
    } else {
        $obj->property++;
    }
    return $obj;
}

function &get_instance_noref() {
    static $obj;

    echo 'Static object: ';
    var_dump($obj);
    if (!isset($obj)) {
        $new = new stdclass;
        // 将一个对象赋值给静态变量
        $obj = $new;
    }
    if (!isset($obj->property)) {
        $obj->property = 1;
    } else {
        $obj->property++;
    }
    return $obj;
}

$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();

//返回
Static object: NULL
Static object: NULL

Static object: NULL
Static object: object(stdClass)#3 (1) {
  ["property"]=>
  int(1)
}

可变变量

一个变量的变量名可以动态的设置和使用

来自 PHP 之外的变量

  • HTML 表单(GET 和 POST)
  • IMAGE SUBMIT 变量名
  • HTTP Cookies
前言 作者和贡献者 I. 入门指引 1. 简介 2. 简明教程 II. 安装与配置 3. 安装前需要考虑的事项 4. Unix 系统下的安装 5. Mac OS X 系统下的安装 6. Windows 系统下的安装 7. PECL 扩展库安装 8. 还有问题? 9. 运行时配置 III. 语言参考 10. 基本语法 11. 类型 12. 变量 13. 常量 14. 表达式 15. 运算符 16. 流程控制 17. 函数 18. 类与对象(PHP 4) 19. 类与对象(PHP 5) 20. 异常处理 21. 引用的解释 IV. 安全 22. 简介 23. 总则 24. 以 CGI 模式安装时 25. 以 Apache 模块安装时 26. 文件系统安全 27. 数据库安全 28. 错误报告 29. 使用 Register Globals 30. 用户提交的数据 31. 魔术引号 32. 隐藏 PHP 33. 保持更新 V. 特点 34. 用 PHP 进行 HTTP 认证 35. cookies 36. 会话 37. 处理 XForms 38. 文件上传处理 39. 使用远程文件 40. 连接处理 41. 数据库永久连接 42. 安全模式 43. PHP 的命令行模式 VI. 函数参考 I. .NET 函数 II. Advanced PHP debugger III. Alternative PHP Cache IV. Apache 特有函数 V. Array 数组函数 VI. Aspell 函数(已废弃) VII. BC math 高精度数学函数 VIII. Bzip2 压缩函数 IX. Calendar 日历函数 X. CCVS API Functions [deprecated] XI. Character Type Functions XII. Classes/Objects 类/对象函数 XIII. Classkit Functions XIV. ClibPDF Functions XV. COM 和 .Net(Windows)函数 XVI. Crack Functions XVII. Credit Mutuel CyberMUT functions XVIII. CURL, Client URL Library Functions XIX. Cybercash Payment Functions XX. Cyrus IMAP administration Functions XXI. Database (dbm-style) Abstraction Layer Functions XXII. Date/Time 日期/时间函数 XXIII. DB++ Functions XXIV. dBase Functions XXV. DBM Functions [deprecated] XXVI. dbx Functions XXVII. Direct IO Functions XXVIII. Directory 目录函数 XXIX. DOM Functions XXX. DOM XML Functions XXXI. Error Handling and Logging Functions XXXII. Exif Functions XXXIII. File Alteration Monitor Functions XXXIV. filePro Functions XXXV. Filesystem 文件系统函数 XXXVI. Firebird/InterBase Functions XXXVII. Firebird/Interbase Functions (PDO_FIREBIRD) XXXVIII. Forms Data Format Functions XXXIX. FriBiDi Functions XL. FrontBase Functions XLI. FTP 函数 XLII. Function Handling Functions XLIII. Gettext XLIV. GMP Functions XLV. GNU Readline XLVI. GNU Recode Functions XLVII. HTTP 函数 XLVIII. Hyperwave API Functions XLIX. Hyperwave Functions L. IBM DB2, Cloudscape and Apache Derby Functions LI. ICAP Functions [deprecated] LII. iconv Functions LIII. ID3 Functions LIV. IIS Administration Functions LV. Image 图像函数 LVI. IMAP, POP3 and NNTP Functions LVII. Informix Functions LVIII. Ingres II Functions LIX. IRC Gateway Functions LX. KADM5 LXI. LDAP Functions LXII. libxml Functions LXIII. Lotus Notes Functions LXIV. LZF Functions LXV. Mail Functions LXVI. mailparse Functions LXVII. Math 数学函数 LXVIII. MaxDB PHP Extension LXIX. MCAL Functions LXX. Mcrypt Encryption Functions LXXI. MCVE Payment Functions LXXII. Memcache Functions LXXIII. Mhash Functions LXXIV. Microsoft SQL Server and Sybase Functions (PDO_DBLIB) LXXV. Microsoft SQL Server Functions LXXVI. Mimetype Functions LXXVII. Ming functions for Flash LXXVIII. Miscellaneous Functions LXXIX. mnoGoSearch Functions LXXX. Mohawk Software Session Handler Functions LXXXI. mSQL Functions LXXXII. Multibyte String Functions LXXXIII. muscat Functions LXXXIV. MySQL 函数 LXXXV. MySQL Functions (PDO_MYSQL) LXXXVI. MySQL Improved Extension LXXXVII. Ncurses Terminal Screen Control Functions LXXXVIII. Network Functions LXXXIX. Net_Gopher XC. NSAPI-specific Functions XCI. Object Aggregation/Composition Functions XCII. Object property and method call overloading XCIII. ODBC and DB2 functions (PDO_ODBC) XCIV. ODBC Functions (Unified) XCV. oggvorbis XCVI. OpenAL Audio Bindings XCVII. OpenSSL Functions XCVIII. Oracle 函数 XCIX. Oracle Functions (PDO_OCI) C. Oracle 函数(已废弃) CI. Output Control 输出控制函数 CII. Ovrimos SQL Functions CIII. Paradox File Access CIV. Parsekit Functions CV. PDF functions CVI. PDO Functions CVII. PHP / Java Integration CVIII. PHP bytecode Compiler CIX. PHP Options&Information CX. POSIX Functions CXI. PostgreSQL 数据库函数 CXII. PostgreSQL Functions (PDO_PGSQL) CXIII. PostgreSQL Session Save Handler CXIV. PostScript document creation CXV. Printer Functions CXVI. Process Control Functions CXVII. Program Execution Functions CXVIII. Pspell Functions CXIX. qtdom Functions CXX. Radius CXXI. Rar Functions CXXII. Perl 兼容正则表达式函数 CXXIII. POSIX 扩展正则表达式函数 CXXIV. runkit Functions CXXV. SDO Functions CXXVI. SDO Relational Data Access Service Functions CXXVII. SDO XML Data Access Service Functions CXXVIII. Secure Shell2 Functions CXXIX. Semaphore, Shared Memory and IPC Functions CXXX. SESAM Database Functions CXXXI. Session Handling Functions CXXXII. Shared Memory Functions CXXXIII. Shockwave Flash Functions CXXXIV. SimpleXML functions CXXXV. SNMP 函数 CXXXVI. SOAP Functions CXXXVII. Socket Functions CXXXVIII. SQLite Functions CXXXIX. SQLite Functions (PDO_SQLITE) CXL. Standard PHP Library (SPL) Functions CXLI. Stream Functions CXLII. String 字符串处理函数 CXLIII. Sybase Functions CXLIV. TCP Wrappers Functions CXLV. Tidy Functions CXLVI. Tokenizer Functions CXLVII. Unicode Functions CXLVIII. URL 函数 CXLIX. Variable 变量函数 CL. Verisign Payflow Pro Functions CLI. vpopmail Functions CLII. W32api 函数 CLIII. WDDX Functions CLIV. xattr Functions CLV. xdiff Functions CLVI. XML 语法解析函数 CLVII. XML-RPC 函数 CLVIII. XMLReader functions CLIX. XSL functions CLX. XSLT Functions CLXI. YAZ Functions CLXII. YP/NIS Functions CLXIII. Zip File Functions (Read Only Access) CLXIV. Zlib Compression Functions VII. PHP 和 Zend 引擎内部资料 44. PHP 扩展库编程 API 指南 45. Zend API:深入 PHP 内核 46. 扩展 PHP 3 VIII. FAQ:常见问题 47. 一般信息 48. 邮件列表 49. 获取 PHP 50. 数据库问题 51. 安装常见问题 52. 编译问题 53. 使用 PHP 54. PHP 和 HTML 55. PHP 和 COM 56. PHP 和其它语言 57. 从 PHP/FI 2 移植到 PHP 3 58. 从 PHP 3 移植到 PHP 4 59. 从 PHP 4 移植到 PHP 5 60. 杂类问题 IX. 附录 A. PHP 及其相关工程的历史 B. 从 PHP 4 移植到 PHP 5 C. 从 PHP 3 移植到 PHP 4 D. 从 PHP/FI 2 移植到 PHP 3 E. PHP 的调试 F. 配置选项 G. php.ini 配置选项 H. 扩展库分类 I. 函数别名列表 J. 保留字列表 K. 资源类型列表 L. 支持的协议/封装协议列表 M. 可用过滤器列表 N. 所支持的套接字传输器(Socket Transports)列表 O. PHP 类型比较表 P. 解析器代号列表 Q. 关于本手册 R. 开放出版许可协议 S. 函数索引
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值