7

语言参考

1. 类型

1.1 简介

数据类型

伪类型

1.2 Float 浮点型

浮点数的精度有限

例如,floor((0.1+0.7) * 10) 通常会返回 7 而不是预期中的 8,因为该结果内部的表示其实是类似 7.9999999999999991118...

1.3 String 字符串

string 最大可以达到 2GB

一个字符串可以用 4 种方式表达

  • 单引号
  • 双引号
  • heredoc 语法结构
  • nowdoc 语法结构

1.4 Array 数组

PHP 中的数组实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型。此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种实现),字典,集合,栈,队列以及更多可能性。由于数组元素的值也可以是另一个数组,树形结构和多维数组也是允许的

1.5 Resource 资源类型

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

1.6 NULL

特殊的 NULL 值表示一个变量没有值。NULL 类型唯一可能的值就是 NULL。

在下列情况下一个变量被认为是 NULL

  • 被赋值为 NULL
  • 尚未被赋值
  • 被 unset()

1.7 伪类型

伪类型(pseudo-types) 是 PHP 文档里用于指示参数可以使用的类型和值。 请注意,它们不是 PHP 语言里原生类型。 所以不能把伪类型用于自定义函数里的类型约束(typehint)

2. 变量

2.1 变量范围

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

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

2.2 可变变量

$a = 'hello';
$$a = 'world';
echo "$a ${$a}";

3. 常量

3.1 魔术常量

名称 说明
__LINE__ 文件中的当前行号
__FILE__ 文件的完整路径和文件号
__DIR__ 文件所在的目录
__FUNCTION__ 函数名称
__CLASS__ 类的名称
__TRAIT__ Trait的名字
__METHOD__ 类的方法名
__NAMESPACE__ 当前命名空间的名称(区分大小写)

4.运算符

4.1 算术运算符

//乘方
$a = 3;
$b = 2;
echo $a ** $b;

4.2 位运算符

位运算符允许对整型数中指定的位进行求值和操作
例子 名称 结果
$a & $b And(按位与) 将把 $a 和 $b 中都为 1 的位设为 1
$a 竖线(注1) $b Or(按位或) 将把 $a 和 $b 中任何一个为 1 的位设为 1
$a ^ $b Xor(按位异或) 将把 $a 和 $b 中一个为 1 另一个为 0 的位设为 1
~ $a Not(按位取反) 将 $a 中为 0 的位设为 1,反之亦然
$a << $b Shift left(左移) 将 $a 中的位向左移动 $b 次(每一次移动都表示“乘以 2”)
$a >> $b Shift right(右移) 将 $a 中的位向右移动 $b 次(每一次移动都表示“除以 2”)
注1:这里“竖线”竖线是“|”,这里 markdown 支持好像有点问题

4.3 比较运算符

比较运算符,如同它们名称所暗示的,允许对两个值进行比较
例子 名称 结果
$a == $b 等于 TRUE,如果类型转换后 $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,如果 $a 严格小于 $b
$a > $b 大于 TRUE,如果 $a 严格大于 $b
$a <= $b 小于等于 TRUE,如果 $a 小于或者等于 $b
$a >= $b 大于等于 TRUE,如果 $a 大于或者等于 $b
$a <=> $b 太空船运算符(组合比较符) 当$a小于、等于、大于$b时 分别返回一个小于、等于、大于0的integer 值。 PHP7开始提供.
$a ?? $b ?? $c NULL 合并操作符 从左往右第一个存在且不为 NULL 的操作数。如果都没有定义且不为 NULL,则返回 NULL。PHP7开始提供

4.4 执行运算符

PHP 支持一个执行运算符:反引号(``)。注意这不是单引号!PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回(即,可以赋给一个变量而不是简单地丢弃到标准输出)。使用反引号运算符“`”的效果与函数 shell_exec() 相同

4.5 数组运算符

例子 名称 结果
$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

4.6 类型运算符

instanceof 用于确定一个 PHP 变量是否属于某一类 class 的实例

instanceof 也可用来确定一个变量是不是继承自某一父类的子类的实例

instanceof 也可用于确定一个变量是不是实现了某个接口的对象的实例

5. 流程控制

5.1 流程控制的替代语法

PHP 提供了一些流程控制的替代语法,包括 if,while,for,foreach 和 switch。替代语法的基本形式是把左花括号({)换成冒号(:),把右花括号(})分别换成 endif;,endwhile;,endfor;,endforeach; 以及 endswitch;
if (true) :
    echo "run\n";
endif;

5.2 do-while

5.3 break

break 结束当前 for,foreach,while,do-while 或者 switch 结构的执行

break 可以接受一个可选的数字参数来决定跳出几重循环

5.4 continue

continue 在循环结构用用来跳过本次循环中剩余的代码并在条件求值为真时开始执行下一次循环

continue 接受一个可选的数字参数来决定跳过几重循环到循环结尾。默认值是 1,即跳到当前循环末尾

5.5 declare

declare 结构用来设定一段代码的执行指令
declare(ticks=1);

// A function called on each tick event
function tick_handler()
{
    echo "tick_handler() called\n";
}

register_tick_function('tick_handler');

$a = 1;

if ($a > 0) {
    $a += 2;
    print($a);
}

5.6 require

require 和 include 几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告(E_WARNING),脚本会继续运行

6. 函数

6.1 用户自定义函数

当一个函数是有条件被定义时,必须在调用函数之前定义

PHP 不支持函数重载,也不可能取消定义或者重定义已声明的函数

但是要避免递归函数/方法调用超过 100-200 层,因为可能会使堆栈崩溃从而使当前脚本终止。 无限递归可视为编程错误

6.2 可变函数

PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途
function foo() {
    echo "In foo()<br />\n";
}

$func = 'foo';
$func();        // This calls foo()

6.3 匿名函数

匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值
$greet = function($name)
{
    printf("Hello %s\r\n", $name);
};

$greet('World');
$greet('PHP');

7. 类与对象

7.1 基本概念

每个类的定义都以关键字 class 开头,后面跟着类名,后面跟着一对花括号,里面包含有类的属性与方法的定义

一个类可以包含有属于自己的常量,变量(称为“属性”)以及函数(称为“方法”)

当一个方法在类定义内部被调用时,有一个可用的伪变量 $this

7.2 类的自动加载

在编写面向对象(OOP) 程序时,很多开发者为每个类新建一个 PHP 文件。 这会带来一个烦恼:每个脚本的开头,都需要包含(include)一个长长的列表(每个类都有个文件)

在 PHP 5 中,已经不再需要这样了。 spl_autoload_register() 函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载。通过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类

spl_autoload_register(function ($class_name) {
    require_once $class_name . '.php';
});

$obj  = new MyClass1();
$obj2 = new MyClass2();

7.3 构造函数和析构函数

  • 构造函数
PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作
  • 析构函数
PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行

7.4 抽象类

PHP 5 支持抽象类和抽象方法。定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现

7.5 对象接口

使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容

接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的

接口中定义的所有方法都必须是公有,这是接口的特性

  • 实现(implements)
要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称

7.6 Trait

自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait

Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题

Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承

7.7 匿名类

7.8 魔术方法

__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke() 等方法在 PHP 中被称为"魔术方法"(Magic methods)

7.9 Final 关键字

PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承

8. 生成器

9. 预定义变量

名称 用途
超全局变量 超全局变量是在全部作用域中始终可用的内置变量
$GLOBALS 引用全局作用域中可用的全部变量
$_SERVER 服务器和执行环境信息
$_GET HTTP GET 变量
$_POST HTTP POST 变量
$_FILES HTTP 文件上传变量
$_REQUEST HTTP Request 变量
$_SESSION Session 变量
$_ENV 环境变量
$_COOKIE HTTP Cookies
$php_errormsg 前一个错误信息
$HTTP_RAW_POST_DATA 原生POST数据
$http_response_header HTTP 响应头
$argc 传递给脚本的参数数目
$argv 传递给脚本的参数数组

《PHP 面试问答》

结合实际 PHP 面试,系统的汇总面试中的各种各样的问题,尝试提供简洁准确的答案。如果你在 PHP 面试中遇到问题,欢迎提 Issues 交流。包含网络协议、数据结构与算法、PHP、Web、MySQL、Redis、Linux、安全、设计模式、架构、自我介绍、离职原因、职业规划、准备问题等部分。

凌枫
1k 声望49 粉丝

PHP面试问答 [链接]