PHP 即超文本预处理器,是一种通用开源脚本语言。PHP 是在服务器端执行的脚本语言,是常用的网络编程语言。PHP 原为 Personal Home Page 的缩写,官方于 1998 年 6 月正式发布 PHP 3.0 时更名为:Hypertext Preprocessor。
更多历史查看:https://www.php.net/manual/zh/history.php.php

以下文档基于 PHP8.x 。

官方文档:https://www.php.net/manual/zh/langref.php

标记

1. <?php code... ?>:XML 风格,建议。纯 php 文件中,结束标记 ?> 建议省略。
2. <? code... ?>:简短风格,不建议。需开启 php.ini 中的 short_open_tag = on。

参考文档:https://www.php.net/manual/zh/language.basic-syntax.phptags.php

注释

#  单行注释
// 单行注释
/**
 * 多行注释
 */

数据类型

  1. 标量类型:Int、Float(Double)、String、Bool。
  2. 复合类型:Array、Object、Callable、Iterable。
  3. 特殊类型:Resource、Null。

数组

// 定义 # ayyay方式
array($value1, $value2, $value3, ...)
array($key1=>$value1, $key2=>$value2, $key3=>$value3, ...)
// 定义 # [] 方式
[$value1, $value2, $value3, ...]
[$key1=>$value1, $key2=>$value2, $key3=>$value3, ...]
// 定义、添加、修改
$arr[] = $value
$arr[$key] = $value
// 删除
unset($arr[$key]);

对象
PHP 对象是通过 class 定义的。

参考文档:https://www.php.net/manual/zh/language.types.intro.php

类型转换
可以在要转换的变量之前加上用括号()括起来的目标类型以强制转换。

settype() : 设置变量的类型
strval($var) : 将变量转换成字符串
intval($var) : 将变量转换成整型
floatval($var) : 将变量转换成浮点型

常量

PHP 中常量使用 define 或 const 定义。在脚本执行期间该值不能改变。传统上常量总是大写的,由字母或者下划线开头,后面跟上任意数量的字母,数字,或者下划线。可使用如下正则校验:

 ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$

参考文档:https://www.php.net/manual/zh/language.constants.php

预定义常量

PHP_VERSION : (string) 当前 PHP 版本号,"主版本号.子版本号.阶段版本号[扩展信息]"形式。
PHP_MAXPATHLEN (int) : 当前 PHP 版本支持的最大文件名(包括路径)长度。
PHP_OS : (string) 运行 PHP 的操作系统。
PHP_OS_FAMILY : (string) 运行 PHP 的操作系统家族。Windows、BSD、Darwin、 Solaris、Linux 或 Unknown 中的一个。
PHP_SAPI : (string) 运行 PHP 的服务器接口类型(Server API)。
PHP_EOL : (string) 当前平台中对于换行符的定义。
PHP_INT_MAX : (int) 当前 PHP 版本支持的最大整型数字。 32 位系统中通常为 int(2147483647),64 位系统中为 int(9223372036854775807)。
PHP_INT_MIN : (int) 当前 PHP 版本支持的最小整型数字。 32 位系统中通常为 int(-2147483648),64 位系统中为 int(-9223372036854775808)。
PHP_INT_SIZE : (int) 当前 PHP 版本的整数大小(以字节为单位)。
PHP_FLOAT_DIG : (int) 可以返回四舍五入为浮点数后不会造成精度损失的小数位数。
PHP_FLOAT_EPSILON : (float) 最小的可表示正数 x,使 x + 1.0 != 1.0。
PHP_FLOAT_MIN : (float) 最小可表示的正浮点数。
PHP_FLOAT_MAX : (float) 最大的可表示浮点数。 
DEFAULT_INCLUDE_PATH : (string)
PEAR_INSTALL_DIR : (string)
PEAR_EXTENSION_DIR : (string)
PHP_EXTENSION_DIR : (string) 寻找可动态加载扩展的默认目录。默认为 PHP_PREFIX 。
PHP_PREFIX : (string) 配置(configure)时设置的 --prefix 值。 在 Windows 上,它是配置(configure)时设置的 --with-prefix 值。
PHP_BINDIR : (string) 配置(configure)时设置的 --bindir 值。 在 Windows 上,它是配置(configure)时设置的 --with-prefix 值。
PHP_BINARY : (string) 脚本执行期间的 PHP 二进制路径。
PHP_LIBDIR : (string) PHP 扩展模块的路径。
PHP_SHLIB_SUFFIX : (string) 构建平台的共享库后缀,例如 ”so“(大多数 Unix) 或 ”dll“(Windows)。
PHP_FD_SETSIZE : (string) 系统调用的文件描述符的最大数目。
E_ERROR : (int) 错误报告常量
E_WARNING : (int) 错误报告常量
E_PARSE : (int) 错误报告常量
E_NOTICE : (int) 错误报告常量
...

参考文档:https://www.php.net/manual/zh/reserved.constants.php

魔术常量

__LINE__ : 文件中的当前行号。
__FILE__ : 文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
__DIR__ : 文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(__FILE__)。除非是根目录,否则目录中名不包括末尾的斜杠。
__FUNCTION__ : 当前函数的名称。匿名函数则为 {closure}。
__CLASS__ : 当前类的名称。类名包括其被声明的作用域(例如 Foo\Bar)。当用在 trait 方法中时,__CLASS__ 是调用 trait 方法的类的名字。
__TRAIT__ : Trait 的名字。Trait 名包括其被声明的作用域(例如 Foo\Bar)。
__METHOD__ : 类的方法名。
__NAMESPACE__ : 当前命名空间的名称。
ClassName::class : 完整的类名。

参考文档:https://www.php.net/manual/zh/language.constants.magic.php

常量函数

constrant() : 获取常量的值
get_defined_constants() : 获取所有已定义的常量列表

变量

PHP 中的变量用一个美元符号($)后面跟变量名来表示。变量是区分大小写的。由字母或者下划线开头,后面跟上任意数量的字母,数字,或者下划线。可使用如下正则校验:

^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$
  1. 可变变量:可以变化的变量,右边变量的值作为左边变量的名。
  2. 可以使用 & 符号引用赋值。
  3. PHP 中全局变量在函数中使用时必须声明为 global。

参考文档:https://www.php.net/manual/zh/language.variables.php

超全局变量

$GLOBALS : 引用全局作用域中可用的全部变量
$_SERVER : 服务器和执行环境信息
$_GET : HTTP GET 变量
$_POST : HTTP POST 变量
$_FILES : HTTP 文件上传变量
$_REQUEST : HTTP Request 变量
$_SESSION : Session 变量
$_ENV : 环境变量
$_COOKIE : HTTP Cookies

参考文档:https://www.php.net/manual/zh/language.variables.superglobals.php

变量函数

boolval() : 获取变量的布尔值
debug_zval_dump() :  将内部zend值的字符串表示形式转储到输出
empty() : 检查一个变量是否为空
floatval() : 获取变量的浮点值
doubleval() : floatval 的别名
get_debug_type() : 获取更适合 Debug 的数据类型
get_defined_vars() : 返回由所有已定义变量所组成的数组
get_resource_id() : 返回一个整型的资源 ID 值
get_resource_type() : 返回资源(resource)类型
gettype() : 获取变量的类型
intval() : 获取变量的整数值
is_array() : 检测变量是否是数组
is_bool() : 检测变量是否是布尔值
is_callable() : 检测函数在当前环境中是否可调用
is_countable() : 检测变量的内容是否可计数
is_float() : 检测变量是否是浮点型
is_double() : is_float 的别名
is_int() : 检测变量是否是整数
is_integer() : is_int 的别名
is_long() : is_int 的别名
is_iterable() : 检测变量的是否是一个可迭代的值
is_null() : 检测变量是否为 null
is_numeric() : 检测变量是否为数字或数字字符串
is_object() : 检测变量是否是一个对象
is_resource() : 检测变量是否为资源类型
is_scalar() : 检测变量是否是一个标量
is_string() : 检测变量是否是字符串
isset() : 检测变量是否已声明并且其值不为 null
unset() : 释放给定的变量
print_r() : 以易于理解的格式打印变量。
serialize() : 产生一个可存储的值的表示
unserialize() : 从已存储的表示中创建 PHP 的值
settype() : 设置变量的类型
strval() : 获取变量的字符串值
var_dump() : 打印变量的相关信息
var_export() : 输出或返回变量的可解析字符串表示

参考文档:https://www.php.net/manual/zh/ref.var.php

运算符

运算符是可以通过给出的一或多个值(表达式)来产生另一个值的东西。

参考文档:https://www.php.net/manual/zh/language.operators.php

赋值运算符

= : 基本的赋值运算符是“=”,可以与一些其他运算符结合使用。

算术运算符

+$a : 标识,根据情况将 $a 转化为 int 或 float。
-$a : 取反,$a 的负值。
$a + $b : 加法,$a 和 $b 的和。
$a - $b : 减法,$a 和 $b 的差。
$a * $b : 乘法,$a 和 $b 的积。
$a / $b : 除法,$a 除以 $b 的商。
$a % $b : 取模,$a 除以 $b 的余数。
$a ** $b : 求幂,$a 的 $b次方的值。

递增/递减运算符

++$a : 前加,$a 的值加一,然后返回 $a。
$a++ : 后加,返回 $a,然后将 $a 的值加一。
--$a : 前减,$a 的值减一, 然后返回 $a。
$a-- : 后减,返回 $a,然后将 $a 的值减一。

注意:如果递增递减运算符在前,表示先将变量 +1 再使用;如果符号在后,表示先使用变量再 +1。

字符串运算符

. : 连接,返回其左右参数连接后的字符串。
.= : 连接赋值,将右边参数附加到左边的参数之后。

比较运算符

$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的 int 值。

逻辑运算符

$a and $b : And(逻辑与),true,如果 $a 和 $b 都为 true。
$a && $b : And(逻辑与),true,如果 $a 和 $b 都为 true。
$a or $b : Or(逻辑或),true,如果 $a 或 $b 任一为 true。
$a || $b : Or(逻辑或),true,如果 $a 或 $b 任一为 true。
$a xor $b : Xor(逻辑异或),true,如果 $a 或 $b 任一为 true,但不同时是。
! $a : Not(逻辑非),true,如果 $a 不为 true。

位运算符(二进制)

$a & $b : And(按位与),将把 $a 和 $b 中都为 1 的位设为 1。
$a | $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”)。

其他运算符

@ : 错误控制,用于屏蔽单行错误信息,多行错误无效,应尽量少用。
? : : 三元运算,类似于 if... else ...
?? : null 运算, 如果值为 NULL,则使用后面的默认值。
`` : 执行运算符(反引号),注意这不是单引号!PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回。使用反引号运算符“`”的效果与函数 shell_exec() 相同。
, : 多变量分割符,用于同时定义多个变量。
=> : 数组元素访问符,用于访问数组内容。
-> : 对象成员访问符,用于访问 class 中的成员。

流程控制

参考文档:https://www.php.net/manual/zh/language.control-structures.php

条件语句(if)

// if 语句
if ( $expr ) {
    // code...
}

// 替代语法 # 只能管理之后的一行语句
if ( $expr )
    // code...
// if ... else ... 语句
if ( $expr ) {
    // code...
} else {
    // code...
}

// 替代语法 # 只能管理之后的一行语句
if ( $expr )
    // code...
else
    // code...
// if ... elseif ... else ... 语句
if ( $expr1 ) {
    // code...
} elseif ( $expr2 ) {
    // coding
} else {
    // code...
}

// 替代语法 # 可以管理之后的多行语句(注意冒号)
if ( $expr1 ):
    // code...
elseif ( $expr2 ):
    // code...
else ( $expr3 ):
    // code...
endif;

条件语句(switch)

// switch ... case ... 语句,松散比较(==)
switch ( $expr ) {
    case $value:
        // code...
        break;
    case $value:
        // code...
        break;
    default: 
        // code...
}

条件语句(match)

// match 语句,严格比较(===)
$return_value = match ( $expr ) {
    $single_expr => $return_expr,
    $conditional_expr1, $conditional_expr2 => $return_expr,
}

// 替代语法(无)

循环语句(for)

// for 语句
for ( $expr1; $expr2; $expr3 ) {
    // code...
}

// 替代语法 # 可以管理之后的多行语句(注意冒号)
for ( $expr1; $expr2; $expr3 ):
    // code...
endfor;
// 处理数组
// foreach 语句 # $value 格式
foreach ( $iterable_expr as $value) {
    // code...
}

// 替代语法(无)

// foreach 语句 # $key => $value 格式
foreach ( $iterable_expr as $key => $value ) {
    // code...
}

// 替代语法(无)

循环语句(while)

// while 语句
while ( $expr ) {
    // code...
}

// 替代语法 # 可以管理之后的多行语句(注意冒号)
while ( $expr ):
    // code...
endwhile;
// do ... while ... 语句
do {
    // code...
} while ( $expr )

// 替代语法(无)

其他语句

break : 结束执行当前的循环结构。
continue : 跳过本次循环中剩余的代码并开始执行下一次循环。
return :将程序控制返还给调用模块
require : 包含并运行指定文件,在出错时产生 E_COMPILE_ERROR 级别的错误
require_once :require 完全相同,唯一区别是文件仅仅包含(require)一次
include : 包含并运行指定文件,在出错时只产生警告(E_WARNING),脚本会继续运行
include_once :include 完全相同,唯一区别是文件仅仅包含(include)一次
goto : 跳转到程序中的指定标记位置,限制较多,慎用
declare : 声明一段代码的执行指令,目前支持:ticks、encoding、strict_types

函数

参考文档:https://www.php.net/manual/zh/language.functions.php

  • 参数列表以逗号作为分隔符。
  • 支持按值传参,引用传参(&)以及默认参数。也支持可变长度参数列表(…)和命名参数(😃。
  • 可使用 return 返回函数执行结果。
  • 函数内部定义的变量仅作用在函数内,函数外的变量需要声明全局变量(global)后使用或通过 $GLOBALS 使用。
  • 支持箭头函数语法:fn (arg_list) => expr。
  • 支持变量函数。如果一个变量名后有圆括号,PHP 将寻找同名函数,并尝试执行。
  • 支持递归函数、回调函数及匿名函数。
// 函数结构
function funcName ($arg_1, $arg_2='defVal',/* ..., */ $arg_n)
{
    // code...
}

类与对象

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

参考文档:https://www.php.net/manual/zh/language.oop5.php

  • 使用对象运算符(->)访问非静态属性,示例:$this->property
  • 使用范围解析操作符(::)访问静态属性,示例:self::$property
  • 使用 const 定义类常量,类常量一般用大写
  • 构造函数:对象初始化,使用预定义方法 __construct()
  • 析构函数:销毁对象时自动调用,使用预定义方法 __destruct()
  • 使用魔术方法 __clone() 克隆对象
  • 使用 public(公有),protected(受保护)或 private(私有)实现访问控制
  • 使用 static 关键字声明类属性或方法为静态,用类访问而不是对象
  • 使用 self 关键字在类的内部代替类名
  • 使用 extends 关键字继承类
  • 使用 parent 关键字访问父类成员
  • 使用 new 关键字实例化一个类
  • 使用 $this 在实例化的对象中访问对象成员
  • 使用 final 关键字修饰类、方法、属性,标识其不可被继承或重定义
  • 使用 abstract 关键字声明抽象类或抽象方法,使其只能被继承不能被实例化
  • 使用 trait 关键字实现代码的复用
  • 使用 interface 关键字可以指定某个类必须实现哪些方法,但不需要定义具体内容
// 类结构
class _ParentClassName {
    // 常量
    const CONSTNAME = '常量值';
    // 属性 # 类属性必须使用访问控制操作符
    public $varNormal = '属性值';
    // 静态属性
    public static $varStatic = '静态属性值';
    // 构造函数
    function __construct () {
        // code...
    }
    // 析构函数
    function __destruct () {
        // code...
    }
    // 方法
    public function methodName () {
        // code...
        echo '$varStatic:'. self::$varStatic .'<br/>';    # 避免使用类名直接访问,后续修改类名导致的错误
        echo '$varNormal:'. $this -> varNormal .'<br/>';
    }
    // 静态方法
    public static function methodStaticName () {
        // code...
    }
}

final class _ChildClassName extends _ParentClassName {
    # 属性
    public $varNormal = '重写属性值';
    # 方法
}
$initClass = new _ChildClassName();
$initClass -> methodName();
// 代码复用
trait _TraitName {
    # 属性
    # 方法
}
// 接口
interface _InterfaceName {}
class _ClassName implements _InterfaceName {}

Iterator (迭代器)
使用 foreach 遍历对象时会受到访问修饰限定符的限制。使用 Iterator 可以修改 foreach 的内部运行机制。foreach 在遍历的时候本身需要执行五个步骤:

  1. 初始化目标,将对象指针指向第一个属性
  2. 判断指针是否有效,存在下一步,不存在则中止
  3. 取出当前指针元素的值存储到变量中
  4. 取出当前指针元素的键存储到变量中
  5. 将取出元素后的指针指向下一个属性

实现了迭代器的类的对象在 foreach 的时候,不会按照 foreach 的机制处理,而是调用迭代器的 5 个方法:

  • Iterator::rewind : 返回到迭代器的第一个元素
  • Iterator::valid : 检查当前位置是否有效
  • Iterator::current : 返回当前元素
  • Iterator::key : 返回当前元素的键
  • Iterator::next : 向前移动到下一个元素
use Iterator;
class myIterator implements Iterator {
    // 索引数组
    private $varArray = array(
        "第 1 个元素", 
        "key"=>"第 2 个元素", 
        "第 3 个元素"
    ); 
    
    // 5个方法 : 初始化迭代器的第一个元素
    public function rewind() {
        echo __METHOD__ .'<br/>';
        reset($this->varArray);
    }
    // 5个方法 : 检查当前位置是否有效
    public function valid() {
        echo __METHOD__ .'<br/>';
        return isset($this->varArray[key($this->varArray)]);
    }
    // 5个方法 : 返回当前元素
    public function current() {
        echo __METHOD__ .'<br/>';
        return current($this->varArray);
    }
    // 5个方法 : 返回当前元素的键
    public function key() {
        echo __METHOD__ .'<br/>';
        return key($this->varArray);
    }
    // 5个方法 : 向前移动到下一个元素
    public function next() {
        echo __METHOD__ .'<br/>';
        next($this->varArray);
    }
}
$it = new myIterator;
foreach($it as $key => $value) {
    echo $key .'=>'. $value .'<br/><br/>';
}

Generator (生成器)
生成器是一个类,Generator 实现了 Iterator 接口极其内部方法。

final class Generator implements Iterator {
    /* 方法 */
    public current(): mixed    # 返回当前产生的值
    public getReturn(): mixed  # 获取生成器的返回值
    public key(): mixed        # 返回当前产生的键
    public next(): void        # 生成器继续执行
    public rewind(): void      # 重置迭代器
    public send(mixed $value): mixed             # 向生成器中传入一个值
    public throw(Throwable $exception): mixed    # 向生成器中抛入一个异常
    public valid(): bool       # 检查迭代器是否被关闭
    public __wakeup(): void    # 序列化回调
}

yield : 生成器会暂停循环执行逻辑,等到使用的时候才再次触发。

// 生成器
echo '<h3>Gererator 生成器</h3>';
// 生成器生成数组
function getGereratorArr () {
    for ($i=0; $i<10000; $i++){
        yield $i;
    }
}
$generatorArr = getGereratorArr();    // Gererator 对象
foreach($generatorArr as $value) {
    echo $value.'; ';
}