Featured image of post PHP 基础

PHP 基础

PHP 环境搭建(Apache + PHP)与基础语法(变量、常量、数据类型、运算符、流程控制、函数、数组等)完整教程

•PHP

搭建环境

什么是PHP

PHP 定义:一种服务器端的 HTML 脚本/编程语言,是一种简单的、面向对象的、解释型的、健壮的、安全的、性能非常之高的、独立于架构的、可移植的、动态的脚本语言。是一种广泛用于 Open Source(开放源代码)的尤其适合 Web 开发并可以嵌入 HTML 的多用途脚本语言。它的语法接近 C,Java 和 Perl,而且容易学习。该语言让 Web 开发人员快速的书写动态生成的网页。

PHP前身:Personal HomePage,个人主页,使用 Perl 语言开发的一种写个人主页的语言。

PHP:PHP Hypertext Preprocessor,php超文本预处理器,底层使用 C 语言。

安装 Apache 环境

可参考 在 apache 中添加 php 处理模块_李志圆的博客-CSDN博客

安装 Apache 软件

安装版
  1. 获取 Apache 安装软件
    Apache 安装包

  2. 双击安装
    安装界面

  3. 选择自定义
    自定义安装

  4. 选择安装位置
    选择安装路径

免安装版
  1. 官网下载软件
    下载页面

  2. 解压
    解压下载的文件,将解压后的文件放在相应目录。

  3. 配置
    3.1 进入所在目录。
    3.2 下载服务器
    输入 httpd -k install -n apache(该命令的意思是安装 Apache 服务器,并将该服务器名称命名为 apache)。

    注意
    若出现 localhost 拒绝连接,则可能是未下载服务器。

    安装服务器

    3.3 修改 httpd.conf,把路径改为自己的安装路径。
    修改配置

    3.4 配置文件更改权限(可能?)
    搜到的教程中说要改,于是跟着改了,不知道不改要不要紧。
    权限修改

Apache 的目录结构说明

目录结构

Httpd.exe 的详细应用

  1. 服务器进程
    服务器程序运行之后才能够工作。
    服务器进程

  2. 运行 httpd
    用来查看 Apache 具有哪些功能以及配置文件是否有错:httpdhttpd.exe(文件所在目录)。
    运行 httpd

    • 查看使用的模块:httpd -M
      查看模块
    • 验证配置文件是否有效:httpd -t
      验证配置

配置默认站点

  1. Apache 确定服务器上访问的位置
    网站文件夹所在位置。httpd.conf 中的 DocumentRoot
    DocumentRoot 配置

  2. 方便用户使用名字访问对应的网站
    给文件夹对应的取一个别名。http.conf 中的 ServerName
    ServerName 配置

    端口可以单独实现:httpd.conf 中的 listen
    Listen 配置

  3. 重启 Apache
    凡是涉及到 Apache 配置文件的修改,需要重启 Apache 才能生效。

  4. 实现 DNS 域名解析
    通常默认站点都是本地 DNS:hosts 文件。
    hosts 文件

运行时出现问题
  1. 要确保 Apache 与 PHP 都是 X64/X32 的。
  2. PHP 的版本号要对应 Apache 的版本号。

安装与配置 PHP

安装 PHP 语言

  1. 获取 PHP 安装文件
    PHP 下载
  2. 解压缩

PHP 目录结构说明

PHP 目录结构

PHP.exe 的应用

PHP.exe 可以解析 PHP 代码转变成 HTML 代码,从而让浏览器可以解析。

  1. 进入目录
    通过 CMD 进入到 php.exe 所在目录,例如 cd D:\...\php8

  2. 运行命令
    通过 php.exe 运行命令来指定要解析的 PHP 脚本:php.exe -f PHP文件所在路径

配置 Apache 加载 PHP 模块

  1. Apache 加载 PHP 模块
    在 Apache 的主配置文件中加载对应的 PHP 提供的模块:
    LoadModule php_module php8apache2_4.dll 所提供的模块链接所在路径。
    LoadModule 是加载模块的语法,标准是:LoadModule 模块名称 模块的实现文件。注意 PHP 版本为 8 时 php8_module 中的 8 不需要写,写了会报错。)
    加载模块配置

    • 在 Apache 的 bin 目录下打开 CMD,输入 httpd -M 确认模块已导入。
      确认模块
  2. Apache 分配工作给 PHP 模块
    如果是 PHP 代码就交给 PHP 处理:通过文件后缀判断 .php 结尾肯定是 PHP 代码:
    AddType application/x-httpd-php .php
    AddType 配置

  3. 将 PHP 的配置文件加载到 Apache 配置文件中,共同生效。
    3.1 在 Apache 中指定 PHP 配置文件所在路径:PHPIniDir php.ini 所在路径
    PHPIniDir 配置
    3.2 php.ini 文件
    php.ini 文件默认是不存在的,是以 developmentproduction 格式存在,需要格式化。可以将 php.ini-development 复制后改名为 php.ini

运行时出现问题

错误提示

解决方法
原因是 PHP 8.0 需要用到 Visual Studio 2019 的 Microsoft Visual C++ Redistributable 工具,需要访问 下载 Visual Studio 2019 进行下载。
VS 下载

PHP 连接数据库

PHP 本身不具备操作 MySQL 数据库的能力,需要借助 PHP 操作 MySQL 的扩展来实现。

  1. PHP 加载 MySQL 扩展
    php.ini 文件中配置。
    MySQL 扩展配置

  2. 指定扩展路径
    PHP 中所有的扩展都在 ext 目录中,需要指定扩展所在路径:extension_dir
    extension_dir 配置
    例如:extension_dir = "D:/Security/Server/php/ext"。当添加 redis.dll 扩展时,只需写 extension=redis.dll

  3. 重启 Apache
    php.ini 已被 Apache 加载,所以需要重启才会生效。

搭建基于域名的虚拟主机

在 Apache 中,虚拟主机的搭建有两种方式:

  1. 在主配置文件中搭建
    需要手动开启虚拟主机(基于域名):NameVirtualHost *:80

  2. 在专门的虚拟主机配置文件中配置

    • 加载配置文件
      在主配置文件(php.ini)中加载虚拟主机配置文件:虚拟主机配置文件已经开启了虚拟主机 NameVirtualHost
      加载虚拟主机配置
    • 配置虚拟主机
      在虚拟主机配置文件中配置虚拟主机。
      虚拟主机配置
      2.1 增加一个对应的站点文件夹位置:DocumentRoot
      DocumentRoot 配置
      2.2 增加主机名字(文件夹的别名):ServerName
      ServerName 配置
      2.3 增加域名解析 DNS:hosts
      hosts 配置
      2.4 需要给当前设定的站点(目录)访问权限
      注意
      Apache 2.4 会报错不能识别 OrderDenyAllow
      1
      2
      3
      4
      5
      
      <Directory '站点目录'>
          Order Deny,Allow   # 没有顺序关系:实际顺序有意义
          Deny from 指定的范围
          Allow from 指定范围/all
      </Directory>
      

权限配置
2.5 配置访问列表
当访问一个目录时(没有指定具体要访问的文件):Options Indexes [FollowSymLinks],如果访问目录,则列表显示所有文件。
Options 配置
2.6 当用户访问指定目录不指定文件时,通常需要系统指定一个默认文件:DirectoryIndex 默认的文件列表,使用空格分隔。
DirectoryIndex 配置

注意:如果网站中整个根目录允许访问,但其中还有其他文件夹不允许访问,可以增加多个 <Directory> 标签,针对不同的文件夹。

  • localhost 配置
    一旦启用虚拟主机配置文件,默认的主机地址 localhost 就不再生效。如果想要生效,需要为 localhost 增加单独的虚拟主机。
  • 添加样图
    样图

PHP 基础

PHP 语法初步

PHP 是一种运行在服务器端的脚本语言,可以嵌入到 HTML 中。

PHP 代码标记

在 PHP 历史发展中,可以使用多种标记来区分 PHP 脚本:

  • ASP 标记:<% php 代码 %>
  • 短标记:<? php 代码 ?>

以上两种基本弃用,如果要使用需要在配置文件 php.ini 中开启。
开启短标记

  • 脚本标记:<script language="php">php 代码</script>
  • 标准标记(常用):<?php php 代码 ?>

PHP 注释

注释是个人学习和写代码的思路说明。PHP 中注释分为两种:

  • 行注释:一次注释一行
    // 后面跟的所有内容都是注释。
    #// 一样。
  • 块注释:一次注释多行
    /**/ 之间的全部内容都是注释。

PHP 语句分隔符

语句分隔符:在 PHP 中,代码以行为单位,系统通过分号 ;(英文状态)判断行的结束。

特殊说明:

  1. PHP 中标记结束符 ?> 自带语句结束符的效果,最后一行 PHP 代码可以没有语句结束符 ;
  2. PHP 中很多代码的书写并不是嵌入到 HTML 中,而是单独存在,通常书写习惯中就不建议使用标记结束符 ?>,PHP 会自动从开始到最后全部认为是 PHP 代码,从而解析。

变量

变量来源于数学,是计算机语言中能储存计算结果或能表示值的抽象概念。变量可以通过变量名访问。在指令式语言中,变量通常是可变的。

变量基本概念

  1. 变量是用来存储数据的。
  2. 变量是存在名字的。
  3. 变量是通过名字来访问数据的。
  4. 变量是可以改变数据的。

变量的使用

  1. 定义:在系统中增加对应的变量名字(内存)。
  2. 赋值:将数据赋值给变量名(可以在定义的同时完成)。
  3. 通过变量名访问存储的数据。
  4. 将变量从内存中删除。
    变量示例

变量命名规则

  1. 在 PHP 中变量名字必须以 $ 符号开始。
  2. 名字由字母、数字和下划线 _ 构成,但不能以数字开头。
  3. 在 PHP 中本身还允许中文变量(不建议)。

预定义变量

预定义变量:提前定义的变量,系统定义的变量,存储许多要用到的数据(预定义变量都是数组)。

  • $_GET:获取所有表单以 GET 方式提交的数据。
  • $_POST:POST 提交的数据都会保存在此。
  • $_REQUEST:GET 和 POST 提交的都会保存。
  • $GLOBALS:PHP 中所有的全局变量。
  • $_SERVER:服务器信息。
  • $_SESSION:session 会话数据。
  • $_COOKIE:cookie 会话数据。
  • $_ENV:环境信息。
  • $_FILES:用户上传的文件信息。

可变变量

可变变量:如果一个变量保存的值刚好是另外一个变量的名字,那么可以直接通过访问一个变量得到另外一个变量的值:在变量前面再多加一个 $ 符号。
例如:$a = 'b'; $b = 'bb'; 那么 $$a = 'bb'

变量传值

将一个变量赋值给另外一个变量:变量传值。有两种方式:值传递和引用传递。

  • 值传递:将变量保存的值复制一份,然后将新的值给另外一个变量保存(两个变量没有关系)。
    值传递
  • 引用传递:将变量保存的值所在的内存地址传递给另外一个变量,两个变量指向同一块内存空间(两个变量是同一个值)。
    1
    2
    
    // $新变量 = &$老变量
    $a = &$b;
    
    引用传递

内存分区:

  • 栈区:程序可以操作的内存部分(不存数据,运行程序代码),少但快。
  • 代码段:存储程序的内存部分(不执行)。
  • 数据段:存储普通数据(全局区和静态区)。
  • 堆区:存储复杂数据,大但效率低。

常量

常量与变量一样,都是用来保存数据的。

常量基本概念

常量(const/constant)是一种在程序运行当中不可改变的量(数据)。常量一旦定义,通常数据不可改变(用户定义)。

常量定义形式

在 PHP 5.3 之后有两种定义方式:

  1. 使用函数 define('常量名', 常量值);
  2. 使用 const 常量名 = 值;
1
2
3
4
5
6
<?php
    // 使用函数定义常量:define
    define('PI', 3.14);
    // 使用 const 关键字定义
    const PII = 3;
?>

常量命名规则

  1. 常量不需要使用 $ 符号,一旦使用系统就会认为是变量。
  2. 常量的名字由字母、数字和下划线组成,不能以数字开头。
  3. 常量的名字通常以大写字母为主(与变量以示区别)。
  4. 常量命名的规则比变量要松散,可以使用一些特殊字符,但只能使用 define 定义。
    1
    2
    
    define('-_-', 'smile');
    // const -_- = 'smile'; // 错误
    

注意:defineconst 定义的常量有区别:在于访问权限区别。定义常量通常不区分大小写,但可以区分,可参照 define 函数的第三个参数(参考文档)。

常量使用形式

常量的使用与变量一样:不可改变值(在定义的时候必须赋值)。
对于特殊名字的常量,需要使用 constant('常量名') 函数来访问。

1
2
3
4
5
6
// 定义特殊常量
define('-_-', 'smile');
// 使用常量
echo PI;
// echo -_-;  // 特殊符号不能直接使用
echo constant('-_-');

常量和变量的使用选择

  1. 数据可能会变化 → 用变量。
  2. 数据不一定会变 → 可以用常量或变量(变量居多)。
  3. 数据不允许被修改 → 一定用常量。

系统常量

系统常量:系统帮助用户定义的常量,用户可以直接使用。

常用系统常量:

  • PHP_VERSION:PHP 版本号。
  • PHP_INT_SIZE:整型大小(所占用的字节数)。
  • PHP_INT_MAX:整型能表示的最大值(整型中允许出现负数:带符号)。

魔术常量(双下划线开头+常量名+双下划线结束,值会随环境变化):

  • __DIR__:当前被执行的脚本所在电脑的绝对路径。
  • __FILE__:当前被执行的脚本所在的电脑的绝对路径(带自己的文件名)。
  • __LINE__:当前所属的行数。
  • __NAMESPACE__:当前所属的命名空间。
  • __CLASS__:当前所属的类。
  • __METHOD__:当前所属的方法。

数据类型

数据类型(data type):在 PHP 中指的是存储的数据本身的类型,而不是变量的类型。PHP 是一种弱类型语言,变量本身没有数据类型。

PHP 的八种数据类型

简单(基本)数据类型(4小类)

  • 整型:int/integer,系统分配 4 个字节存储,表示整数类型(有前提)。
  • 浮点型:float/double,系统分配 8 个字节存储,表示小数或者整型存不下的整数。
  • 字符串型:string,系统根据实际长度分配,表示字符串(引号)。
  • 布尔类型:bool/boolean,只有两个值:truefalse

复合数据类型(2小类)

  • 对象类型:object,存放对象(面向对象)。
  • 数组类型:array,存储多个数据(一次性)。

特殊数据类型(2小类)

  • 资源类型:resource,存放资源数据(PHP 外部数据,如数据库、文件)。
  • 空类型:NULL,只有一个值就是 NULL(不能运算)。

类型转换

类型转换:在需要指定数据类型时,将外部数据转换成目标数据类型。PHP 中有两种类型转换方式:

  1. 自动转换:系统根据需求自己判定转换(用的比较多,效率偏低)。
  2. 强制(手动)转换:人为根据需要的目标类型转换。
    强制转换规则:在变量之前增加一个括号 (),里面写上对应类型:int/integer… 其中 NULL 类型要用到 unset()

在转换过程中,用得比较多的是转布尔类型(判断)和转数值类型(算术运算)。

其他类型转布尔类型truefalse,在 PHP 中比较少类型会变成 false
转布尔规则

其他类型转数值的说明

  1. 布尔 true 为 1,false 为 0。
  2. 字符串转数值有自己的规则:
    • 以字母开头的字符串,永远为 0。
    • 以数字开头的字符串,取到碰到字符串为止(不会同时包含两个小数点)。

类型判断

通过一组 is_ 开头的函数来判断变量类型,返回布尔值:is_XXX(变量名)

bool 类型不能用 echo 查看,可以使用 var_dump 结构查看:var_dump(变量1, 变量2...)

1
2
3
$a = '123asdf';
var_dump(is_int($a));   // false
var_dump(is_string($a)); // true

另外还有一组函数用来获取以及设定数据(变量)的类型:

  • gettype(变量名):获取类型,返回类型对应的字符串。
  • settype(变量名, 类型):设定数据类型,与强制转换不同。强制转换 (类型)变量名 是对数据值复制的内容进行处理(不会处理实际存储的内容);而 settype 会直接改变数据本身。
1
2
3
4
5
$a = 'sad123';
echo (float)$a;           // 输出 0
echo gettype($a);         // string
var_dump(settype($a, 'int')); // true
echo gettype($a);         // integer

整数类型

整数类型保存整数数值(范围限制),4 个字节存储数据,最大 32 位约 42 亿。PHP 中默认是有符号类型(区分正负数)。

PHP 提供了四种整型定义方式:十进制、二进制、八进制、十六进制。

1
2
3
4
5
6
$a = 110;      // 十进制
$b = 0b110;    // 二进制
$c = 0110;     // 八进制
$d = 0x110;    // 十六进制
// 默认 PHP 输出数值都会自动转换成十进制输出
echo $a, $b, $c, $d; // 输出 110 6 72 272

进制转换函数:

  • decbin():十进制转二进制。
  • decoct():十进制转八进制。
  • dechex():十进制转十六进制。
  • bindec():二进制转十进制。
1
var_dump(decbin(10)); // 得到1010

浮点类型

浮点型:小数类型以及超过整型存储范围的整数(不保证精度),精度范围大约 15 个有效数字。

定义方式:

1
2
$f = 1.23;
$f = 1.23e10; // 科学计数法,e 表示底数 10

尽量不要用浮点数做精确判断,因为浮点数保存的数据不够精确,计算机中小数基本上存储都不准确。

布尔类型

布尔类型:两个值 truefalse,通常用于判断比较。

常用判断函数:

  • empty():判断数据的值是否为“空”,不是 NULL,如果为空返回 true,不为空返回 false
  • isset():判断数据存储的变量本身是否存在,存在返回 true,不存在返回 false

运算符

运算符(operator)是一种将数据进行运算的特殊符号,PHP 中有十种运算符之多。

赋值运算符

符号 =,将右边的结果(可以是变量、数据、常量和其他运算出来的结果)保存到内存的某个位置,然后将该内存地址赋值给左侧的变量(常量)。

算术运算符

  • +:累加
  • -:相减
  • *:相乘
  • /:相除
  • %:取余(模),两个整数相除保留余数

进行除法或取余运算时,被除数(第二个数)不能为 0。

比较运算符

比较两个数据的大小或内容是否相同,返回布尔类型:

  • >:左边大于右边
  • >=:左边大于等于右边
  • <:左边小于右边
  • <=:左边小于等于右边
  • ==:左边等于右边(大小相同)
  • !=:左边不等于右边(大小不同)
  • ===:全等于,大小和数据类型都相同
  • !==:不全等于,大小或类型不同

逻辑运算符

  • &&:逻辑与,两边条件同时成立
  • ||:逻辑或,至少一边成立
  • !:逻辑非,对已有条件取反
1
2
3
4
5
6
7
8
9
$a = '123';
$b = '456';
# 逻辑与
var_dump($a == '123' && $b == '45'); // false
# 逻辑或
var_dump($a == '123' || $b == '456'); // true
# 逻辑非
var_dump($b == '456'); // true
var_dump(!($b == '456')); // false

逻辑与和逻辑或具有短路运算特性:如果第一个表达式结果已经满足条件,则不会运行后面的表达式。书写代码时尽量将出现概率最高的表达式放在第一位。

连接运算符

  • .:将两个字符串连接在一起。
  • .=:复合运算,将左边的内容与右边的内容连接起来,然后重新赋值给左边变量($a .= $b 等价于 $a = $a . $b)。
1
2
3
4
5
$a = 'hello ';
$b = 123;
echo $a . $b; // hello 123
$a .= $b;     //等价于$a = $a . $b
echo $a;      // hello 123

错误抑制符

@:在可能出错的表达式前面使用,可以抑制错误输出。

1
2
3
4
$a = 10;
$b = 0;
$a / $b;      // 报错
@($a / $b);   // 不报错

三目运算符

表达式1 ? 表达式2 : 表达式3:如果表达式1成立则执行表达式2,否则执行表达式3。
可以复合使用。

1
2
3
$a = 10;
$b = $a > 10 ? 100 : 0;
echo $b; // 0

三目运算还可以复合三木运算:表达式1 ? (表达式2 ? 表达式3 : 表达式4) : (表达式5 ? 表达式6 : 表达式7)

自操作运算符

  • ++:在原值上 +1
  • --:在原值上 -1

前置与后置:
如果只有自操作不参与其他运算,效果相同;如果同时参与其他运算,则后置先保留原值再改变,前置先改变再使用。

1
2
3
4
5
6
$a = $b = 1;
$a++; ++$b;
echo $a, $b; // 2,2

$a = $b = 1;
echo $a++, ++$b; // 1,2

衍生赋值运算符:+=-=*=/=%=

1
2
3
4
$a = 10;
$b = 5;
$a += $b;        // $a = $a + $b = 15
$a -= $b - 1;    // $a = $a - ($b - 1) = 6

位运算符

计算机码

计算机存储数据采用二进制编码规则:原码、反码、补码,最左边一位是符号位(正数为0,负数为1)。

  • 原码:数据本身从十进制转换成二进制的结果。正数的原码、反码、补码相同;负数符号位为1。
  • 反码:负数符号位不变,其他位取反。
  • 补码:负数反码+1。

系统中存在 +0 和 -0:
+0: 00000000
-0: 10000000(原码) → 11111111(反码) → 00000000(补码)

位运算
  • &:按位与,两位都为1结果为1,否则0。
  • |:按位或,至少一位为1结果为1。
  • ~:按位非,位取反。
  • ^:按位异或,相同为0,不同为1。
  • <<:按位左移,整体向左移动,右边补0。
  • >>:按位右移,整体向右移动,左边补符号位(正数补0,负数补1)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$a = 5;
$b = -5;
//按位与
var_dump($a & $b);     //得到int(1)
/*
	5	原码	00000101

	-5	原码	10000101
		取反	11111010  //反码:符号位不变:其他位取反
		求补	11111011  //补码:反码+1
	取出系统存储的结果进行与操作
	5	00000101
	-5	11111011
	&	00000001	   //最终结果
	转换:判断符号位,0表示正数(原码),1表示附属(补码)
*/

//按位非
var_dump(~ $b);        //得到int(4)
/*
	-5	补码	11111011
		取反	00000100
		原码	00000100
*/

//按位右移
var_dump($b >> 1);     //得到int(-2)
/*
	-5	补码	11111011
		>>1	 11111110  //运算结果:补码
        反码	11111101  //补码-1
        取反	10000010  //原码:-2
*/

注意:

  1. 系统进行任何位运算时都使用补码。
  2. 运算结束后必须转换成原码才是最终显示的数据。
  3. 按位左移相当于乘以2,按位右移相当于除以2(不完全正确,整数除以2可能出现小数)。

运算符优先级

多种运算符同时存在时的结合顺序。
运算符优先级表

流程控制

流程控制:代码执行的方向。

控制分类

  • 顺序结构:代码从上往下顺序执行(最基本结构)。
  • 分支结构:给定条件,有多种可执行代码块,根据条件执行某一段。
  • 循环结构:在条件控制范围内,指定代码块重复执行。
顺序结构

最基本结构,所有代码默认从上往下依次执行。

分支结构

PHP 中分支结构主要有 if 分支和 switch 分支。

if 分支

给定一个条件,同时为该条件设置多种(两种)情况,然后通过条件判断来实现具体的执行段。

  • 最简 if:只有一段代码,可选择是否执行。
    1
    2
    3
    
    if(条件表达式){
        // 满足条件执行的代码
    }
    
  • 基础 if:两面性。
    1
    2
    3
    4
    5
    
    if(条件表达式){
        // 满足条件
    }else{
        // 不满足条件
    }
    
  • 复杂 if:可在不满足后再次判断。
    1
    2
    3
    4
    5
    6
    7
    
    if(条件表达式1){
        // 满足1
    }else if(条件表达式2){
        // 不满足1但满足2
    }else{
        // 全部不满足
    }
    

switch 分支:适合条件单一、固定值匹配的情况。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
switch(条件表达式){
    case 值1:
        // 代码1
        break;
/*
	在 switch 中,如果条件匹配成功,那么系统就不会继续匹配,而是会顺序执行该 case 下的所有代码,如:匹配到了值1,那么就会执行 代码1和代码2(没有 break 的情况)。如果不需要继续执行,那么就需要使用 break 中断 switch。
*/
    case 值2:
        // 代码2
        break;
    default:
        // 都不匹配
        break;
}

选择if 能做所有分支结构;switch 处理条件多且单一、固定值匹配的情况。

循环结构

for 循环

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
//条件表达式1:定义初始化条件,可以有多种赋值语句存在,使用逗号分隔即可。
//条件表达式 2:边界判定,限定循环执行的次数。
//条件表达式3:用来执行条件变化
for(条件表达式1; 条件表达式2; 条件表达式3){
    // 循环体
}

//从1到10输出
for($i = 1,$end = 10; $i <= $end; $i++){
	echo $i,'<br />';	//循环体
}

执行原理:1 → 2(判断) → 循环体 → 3 → 2(判断)→ …

while 循环

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
条件初始化;
while(条件表达式){
    // 循环体
    // 条件变化
}

$i = 1;
//从1输出到10
while($i <= 10){
    echo $i++,'<br />';//循环体
    //循环条件变更	$i++
}

do-while 循环:至少执行一次循环体。

1
2
3
do {
    // 循环体
} while(条件);

循环控制

  • continue [层级]:重新开始循环(默认1层)。
  • break [层级]:终止循环。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$i = 1;
while($i <= 100){
    //判断是否是5的倍数
    if($i % 5 != 0){	//不是5的倍数
        //重新循环
        $i++;
        continue;//重新跳到循环开始时
  
        //终止循环
        break;
    }
    //输出数值
    echo $i++,'<br />';
}
流程控制替代语法

用于在 HTML 中混写 PHP 时替代大括号,使代码更美观。
左大括号 { 用冒号 : 替代,右大括号 }end + 起始标记 替代。
例如:if(): ... endif;for(...): ... endfor;switch(): ... endswitch; 等。

示例:九九乘法表(表格展示)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<table border=1>
    <?php for($i = 1; $i < 10; $i++): ?>
        <tr>
            <?php for($j = 1; $j <= $i; $j++): ?>
                <td>
                    <?php echo $i . ' * ' . $j . ' = ' . $i * $j; ?>
                </td>
            <?php endfor; ?>
        </tr>
    <?php endfor; ?>
</table>

文件包含

在一个 PHP 脚本中将另外一个文件包含进来,合作完成任务。

文件包含的作用

  1. 使用被包含文件中的内容,实现代码共享(向上包含)。
  2. 将自身内容提供给其他文件使用(向下包含)。
  3. 分工协作,多个脚本共同完成任务。

文件包含四种形式

  • include:包含文件。
  • include_once:判断是否已包含过,一个文件最多被包含一次。
  • require:与 include 相同,但错误级别更高(包含出错时停止执行)。
  • require_once:与 include_once 相同。

向上包含:先包含文件,后使用文件中的内容

1
2
3
4
5
6
//文件1	//include1.php
<?php
	//被包含文件:定义数据
    $a = 1;
	define('PI',3.14);
?>
1
2
3
4
5
6
7
//文件2	//include2.php
<?php
    //包含文件:使用数据
//包含当前文件include2.php所在文件夹下的include1.php
    include "include1.php";
	echo $a,PI;//得到结果 13.14
?>

向下包含:先准备内容,然后包含另外的文件,在另外的文件中,使用当前的内容

1
2
3
4
5
6
7
8
9
//文件3	//include3.php
 <?php
     //定义数据
     $a = 10;
	const PI = 3.14;

	//包含文件:为了显示以上数据
	include_once "include4.php";
?>
1
2
3
4
5
//文件4	//include4.php
<table>
    <tr><td> <?php echo $a; ?> </td></tr>
    <tr><td> <?php echo PI; ?> </td></tr>
</table>

文件加载原理

PHP 执行流程:读取代码 → 编译成字节码 → zend engine 解析 opcode → 输出 HTML。
文件加载时,被包含文件的代码嵌入到当前文件的 include 位置,单独编译。如果被包含文件有错误,在执行到 include 语句时才报错。

include 与 require 的区别

include 和 include_once 的区别
  • Include:系统会碰到一次,执行一次;如果对同一个文件进行多次加载,那么系统会执行多次;
  • Include_once:系统碰到多次,也只会执行一次。
1
2
3
4
5
//文件1	//include1.php
<?php
    $a = 10;
	define('PI',3.14);
?>
1
2
3
4
5
6
7
8
//文件2	//include2.php
<?php
    echo "hello";//正常执行
	include "include1.php";//正常执行
	echo $a;//正常执行
	//再次包含
	include "include1.php";//报错,变量不可重复定义
?>
require 和 include 的区别
  • include 错误级别较轻,不会阻止后续代码执行。
  • require 要求较高,包含出错后后续代码不再执行。

image-20220122193045252 image-20220122193441945

文件加载路径

  • 绝对路径:从磁盘根目录开始(如 D:/sever/apache/htdocs/include1.php),效率偏低但安全。
  • 相对路径:从当前文件所在目录开始,./ 当前,../ 上级,效率高但容易出错。
  •  1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
      <?php
      	//PHP文件加载路径
          //绝对路径
      	include_once "D:/sever/apache/htdocs/include1.php";
    
      	//相对路径加载
      	include_once 'include1.php';   //默认当前文件本身
          include_once "./include1.php";
    
      	//复杂相对路径
      	include_once "../htdocs/include1.php";
      ?>
    

文件嵌套包含

一个文件包含另一个文件,被包含文件又包含其他文件。嵌套容易导致相对路径出错。

1
2
//include1.php
<?php $a = 10; ?>
1
2
//include2.php
<?php include_once "include1.php"; ?>
1
2
3
4
5
6
7
//include3.php
<?php
    //文件嵌套包含
    //被包含include2本身包含了include1
    include_once "include2.php";
	echo $a;//正常输出,得到10
?>

函数

函数的基本概念

函数(function)是一种语法结构,将实现某一功能的代码块封装起来,实现代码复用。

函数定义语法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php
    /*
    Function 函数名 ([参数]){
    	//函数体
		//返回值:return 结果;
	  }
	  */
    
    // 调用可以在定义之前(编译与执行分离)
    display();

    function display(){
        echo "hello";
    }

    display();
?>
  • 函数通过 函数名() 调用。
  • 如果定义时有参数,调用时必须传入对应参数。
  • 函数不会自动运行,必须调用才执行。
  • 只要系统在内存中能够找到对应的函数,就可以执行(函数的调用可以在函数定义之前)。

函数命名规范

由字母、数字和下划线组成,不能以数字开头。常用命名方式:驼峰法(showParentInfo)或下划线法(show_parent_info)。在同一脚本周期内不允许出现同名函数。

函数的参数

形参与实参:形参是定义时的形式参数,实参是调用时传入的实际数据。PHP 允许实参多于形参(多余不用),但不能少于形参个数。

  • 形参是实参的载体:实参在调用时通常是需要传入到函数内部参与计算(运算),那么需要在函数内部去找到实际数据所在的位置才能找到数据本身:需要实际调用的时候,将数据以实参的形式传递给形参:给形参赋值,从而使得函数内部可以用到外部数据。

  • image-20220122203206128

  • 📝 备注

    在PHP中允许实参多余形参(个数):函数内部不用而已。

    在PHP中理论上形参个数没有限制(实际开发不会太多)。

    实参不能少于形参个数。

默认值:形参可以设置默认值,当实参未提供时使用。默认值必须放在参数列表的右边。

1
2
3
4
5
6
7
8
$num1 = 10;
//函数的默认值
function add($num1 = 0,$num2 = 0){
    echo $num1 + $num2;
}

//调用:默认值如果存在,可以不再传入
add($num1);//得到 10,且不报错
📝 备注

默认值的定义是放在最后边的(多个),不能左边形参有默认值,但是右边没有。

函数外部定义的变量名字与函数定义的形参名字冲突(同名)是没有任何关联关系的,如果多个函数使用同样的形参名字也不冲突。

引用传递:使用 & 符号,使函数内部可以修改外部变量的值。调用时必须传入变量。

1
2
3
	function 函数名 (形参 1, &形参 2){
		//函数体
	}

在调用的时候,必须给引用传值的参数位置传入实际参数,而且参数本身必须是变量。(变里才有指向的数据的内存地址)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
//定义变量
$a = 10;
$b = 5;

//函数定义
function add($a, &$b){
    $a = $a + $a;
    $b = $b + $b;
    echo $a;//得到 20
    echo $b;//得到 10
}

//调用函数
add($a, $b);
echo $a;//得到 10,$a的本身没变
echo $b;//得到 10,$b改变
/*
说明:函数在定义的时侯,对应的b形参采用的是取地址;
所以在实参传入之后,形参b取到了外部变量b的内存地址,
而a取的是值,因此改变之后:a只改变了函数内部的自己;
b改变自己的同时也改变了外部
*/

函数体

函数体内可以定义变量、常量,使用流程控制,调用其他函数等。

函数返回值

使用 return 关键字将结果返回给调用处。所有函数都有返回值,未明确 return 时默认返回 NULL

image-20220122211657823

函数的返回值可以是任意数据类型

return 在函数内部会终止函数执行;在文件外部使用 return 可以返回内容给包含它的文件,并终止后续代码。

image-20220122212030835 image-20220122212725313

作用域

作用域:变量(常量)能够被访问的区域。变量可以在普通代码或函数内部定义。

在 PHP 中作用域严格来说分为两种:但是 PHP 内部还定义一些在严格意义之外的一种,所以总共算三种:

  • 全局变量

    • 函数外部定义只在全局空间使用,函数内部不可直接访问(可通过 $GLOBALS 或参数传递)。
    • 函数周期:直到脚本运行结束(最后一行代码执行完)。
    • image-20220122214222524
  • 局部变量

    • 函数内部定义,只在当前函数内使用。
    • 函数周期:函数执行结束即销毁。
    • image-20220122214428317
  • 超全局变量

    • 系统预定义(如 $_SERVER),无访问限制。
    • 超全局变量会将全局变量自动纳入到$GLOBALS 里面,而$GLOBALS 没有作用城限制,所以能够帮助局部去访问全局变量:但是必须使用数组方式。
    • image-20220122215011845
    • image-20220122215320562

global 关键字可以在函数内部声明全局变量,使局部与全局共享同一内存空间。

基本语法:

1
2
global 变量名;//不能赋值
变量名 = ;  //修改

具体使用示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$str_a = "this a";
function str(){
    //定义变量:使用全局变量
    global $str_a;
    echo $str_a;
  
    //定义变量:全局不存在
    global $str_b;
    $str_b = "this b";
}

//调用函数
str();//可以得到输出:this a

//访问‘局部’变量
echo $str_b;//可以得到输出:this b

虽然以上方式可以实现局部与全局的互访,但是通常不会这么用。一般如果会存在特殊使用,也会使用参数的形式来访问。(还可以使用常量:define定义的)

静态变量

static是在函数内部定义的变量,使用 static 关键字修饰,用来实现跨函数共享数据的变量:函数运行结束,所有同部变量都会清空,如果重新运行一下函数,所有的局部变量又会重新初始化。

静态变量的使用:

  1. 为了统计当前函数被调用的次数。
  2. :为了统筹函数多次调用得到的不同结果(递归思想)。

基本语法

1
2
3
4
  function 函数名(){
    //定义变量
    static $变量名 = ;//通常会在定义的时候就直接赋值
}

静态变量的作用是为了跨函数共享数据(同一个变量多次调用)

1
2
3
4
5
6
7
function countCall(){
    static $count = 0;
    $count++;
    echo $count;
}
countCall(); // 1
countCall(); // 2

image-20220122221752626

可变函数

如果变量保存的值刚好是一个函数的名字,可以使用 $变量() 来调用该函数。

1
2
3
4
5
$func = 'display';
function display(){
    echo 'hello';
}
$func(); // 输出 hello

image-20220122222640027

可变函数在系统使用的过程中还是比较多的,尤其是使用很多系统函数的时候:需要用户在外部定义一个自定义函数,但是是需要传入到系统函数内部使用。

image-20220122223050266

匿名函数(闭包)

没有名字的函数,通常赋值给变量。

1
2
3
4
$greet = function($name){
    echo "Hello, $name";
};
$greet('Tom');

image-20220122223454813 image-20220122223608545

闭包:匿名函数可以使用 use 关键字引用外部变量,即使外部函数已执行完毕,这些变量仍被保留。

1
2
3
4
5
6
7
8
function getClosure(){
    $msg = 'hello';
    return function() use ($msg){
        echo $msg;
    };
}
$closure = getClosure();
$closure(); // hello

image-20220122224256874

证明:函数的局部变量在函数使用完之后没有被释放

  1. 使用内部匿名函数;
  2. 匿名函数使用局部变量:use;
  3. 匿名函数被返回给外部使用;

image-20220122224659290

伪类型

假类型,实际上在 PHP 中不存在的类型。但是通过伪类型可以帮助程序员去更好的查看操作手册从而更方便学习。

伪类型主要有两种:在三大类八小类之外。

  • mixed:可以是多种数据类型。
  • number:可以是整型或浮点型。
  • image-20220122225144593

常用系统函数

输出函数

  • print():类似 echo,返回 1。
  • print_r():简化版的 var_dump,只输出值(常用于数组)。
  • header('Content-type:text/html;charset=utf-8'):设置浏览器字符集。
  • image-20220123152941816

时间函数

  • date('Y-m-d H:i:s'[, 时间戳]):格式化时间戳。
  • time():当前时间戳。
  • microtime():微秒级时间。
  • strtotime():字符串转时间戳。
  • image-20220123170113659

数学函数

  • max() / min():最大/最小值。
  • rand() / mt_rand():随机数(推荐 mt_rand)。
  • round():四舍五入;ceil() 向上取整;floor() 向下取整。
  • pow():乘方;abs() 绝对值;sqrt() 平方根。

函数相关函数

  • function_exists('函数名'):判断函数是否存在。
  • func_get_arg($n):获取第 n 个参数。
  • func_get_args():获取所有参数(数组)。
  • func_num_args():获取参数数量。
  • image-20220123172234340

错误处理

错误处理:指的是系统(或者用户)在对某些代码进行执行的时候,发现有错误,就会通过错误处理的形式告知程序员。

错误分类

  • 语法错误:编译不通过,代码不执行(Parse error)。

    • 用户书写的代码不符合PHP的语法规范,语法错误会导致代码在编译过程中不通过,所以代码不会执行(Parse error)。
  • 运行时错误:编译通过,执行时条件不满足导致(如调用未定义函数)。

  • 逻辑错误:代码正常执行但结果不符合预期。

错误代号(系统常量)

  • E_PARSE:编译错误。
  • E_ERROR:致命错误,代码不能继续执行。
  • E_WARNING:警告,不影响执行但可能结果异常。
  • E_NOTICE:通知,不影响执行。
  • E_USER_ERROR / E_USER_WARNING / E_USER_NOTICE:用户自定义错误。
  • E_ALL:所有错误。

错误触发

  • 系统自动触发。系统自动根据错误发生后,对比对应的错误信息,输出给用户:主要针对代码的语法错误和运行时错误。

    • image-20220123194505244
  • 人为触发:trigger_error('错误信息'[, 错误类型])。知道某些逻辑可能会出错,从而使用对应的判断代码来触发响应的错误提示。

    • Trigger_error(错误提示);image-20220123195249237
    • 可以通过第二个参数进行严格性控制。image-20220123195357201

错误显示设置

哪些错误该显示,以及该如何显示。在 PHP 中,其实有两种方式来设置当前脚本的错误处理。

  • 在配置文件 php.ini 中:display_errors = On是否显示错误,error_reporting = E_ALL显示什么级别的错误。
  • 在脚本中:在脚本中定义的配置项级别比配置文件高(通常在开发当中都会在代码中去进行控制和配置)。ini_set('display_errors', 1); error_reporting(E_ALL);
    • error_reporting():设置对应的错误显示级别。
    • ini_set(“配置文件中的配置项“,配置值)。

错误日志设置

生产环境通常不显示错误,而是记录到日志文件。在 php.ini 中设置 log_errors = Onerror_log = 路径

image-20220123201440520 image-20220123201720775

自定义错误处理

最简单的错误处理:trigger_errors()函数,但是该函数不会阻止系统报错。

PHP系统提供了一种用户处理错误的机制:用户自定义错误处理函数,然后将该函数增加到系统错误处理的句柄中,然后系统会在碰到错误之后,使用用户定义的错误函数。

  • 使用 set_error_handler('自定义函数') 接管系统错误处理。
    • image-20220123202333327
  • 自定义错误处理函数,系统有要求。
    • image-20220123202930563

代码实现:

  1. 自定义错误处理函数:注意参数
  2. 注册自定义函数:修改错误处理机制
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
    header("Content-type:text/html;charset=utf-8");
   //自定义函数
   //$error,是系统提供的错误代码:E_ALL,E_NOTICE
    function my_error($errno,$errstr,$errfile,$errline){
    //判断:当前会碰到的错误有哪些.排除当前本身系统就要排除的错误
    if(!(error_reporting() & $errno)){
        return false;
        //error_reporting没有参数代表获取当前系统错误处理对应的级别
    }
    //开始判断错误类型
    switch($errno){//错误匹配
        case E_ERROR:
        case E_USER_ERROR:
            echo "fltal error in file " . $errfile . " on line" . $errline . "<br />";
    		echo "error info: " . $errstr;
            break;
        case E_WARNING:
        case E_USER_WARNING:
            echo "warning in file " . $errfile . " on line" . $errline . "<br />";
    		echo "error info: " . $errstr;
            break;
        case E_NOTICE:
        case E_USER_NOTICE:
            echo "notice in file " . $errfile . " on line" . $errline . "<br />";
    		echo "error info: " . $errstr;
            break;
    	}
    return true;
	}
//报错
echo $a;//未定义报错

//修改错误机制
set_error_handler("my_error");
echo $a;//报自定义的错
?>

image-20220123205621601

当前属于简单自定义模式,如果要复杂,可以在某些影响代码功能的错误发生后,让用户跳转到某个指定界面。

字符串

字符串定义语法

  • 单引号$str = 'content'; 不解析变量和转义(除 \'\\)。

  • 双引号$str = "content"; 解析变量和转义(\n\r\t\$ 等)。

    • 1
      2
      3
      
        $name = 'Tom';
        echo "Hello $name"; // Hello Tom
        echo 'Hello $name'; // Hello $name
      
    • image-20220123210328294

比较适合定义那些比较短(不超过一行)或者没有结构要求的字符串。

  • Nowdoc(无单引号的单引号字符串):$str = <<<'EOT' ... EOT;,不解析变量。
  • Heredoc(无双引号的双引号字符串):$str = <<<EOT ... EOT;,解析变量。
    • image-20220123210620988

适合有结构要求,或者内容超过一行。

无引号字符串与有引号字符串的区别

image-20220123211103379

字符串转义

常用转义符

\':在单引号字符串中显示单引号。

\":在双引号字符串中显示双引号。

\r:代表回车(理论上是回到当前行的首位置)。

\n:代表新一行。

\t:类似 tap 键,输出4个空格。

\$:在PHP中使用$符号作为变量符号,因此需要特定识别。

单引号和双引号的区别

  • 单引号中能够识别\’,而双引号中就不能识别\’。
    • image-20220123213747979
  • 双引号中因为能够识别$符号,所以双引号中可以解析变量,而单引号不可以。
    • image-20220123214008395

双引号中变量识别的规则

  • 变量本身系统能够与后面的内容区分:应该保证变量的独立性,不要让系统难以区分。
    • image-20220123214049607
  • 使用变量专业标识符(区分),给变量加上一组大括号{};
    • image-20220123214236432
  • 双引号中解析变量的规则:为保证变量独立,可使用 {$var}${var}

结构化定义字符串变量的规则

  • 结构化定义字符串对应的边界符有条件:

    • 上边界符后面不能跟任何内容;
    • 下边界符必须顶格:最左边;
    • 下边界同样后面只能跟分号,不能跟任何内容;
  • 结构化定义字符串的内部(边界符之间)的所有内容都是字符串本身。

    • image-20220123215145582

字符串长度

  • strlen():字节长度(中文在 UTF-8 下占 3 字节)。
  • mb_strlen($str, 'utf-8'):多字节字符串长度,需开启 mbstring 扩展。

常用字符串函数

  • 转换

    • implode()(数组→字符串),将数组中的元素按照某个规则连接成一个字符串。

    • explode()(字符串→数组),将字符串按照某个格式进行分割,变成数组。

      • 中国|北京|顺义 == array(“中国,北京"顺义);
    • str_split()。按照指定长度拆分字符串得到数组。

  • 截取

    • trim(字符串[,指定字符])(去两边空格或指定字符)
    • ltrim()
    • rtrim()
  • 子串

    • substr(字符串,起始位置从 0 开始[长度]),指定位置开始截取字符串,可以截取指定长度(不指定到最后)
    • strstr(字符串,匹配字符),从指定位置开始,截取到最后(可以用来去文件后缀名)。
  • 大小写

    • strtolower(),全部小写。
    • strtoupper(),全部大写。
    • ucfirst(),首字母大写。
  • 查找

    • strpos(),判断字符在目标字符串中出现的位置(首次)。
    • strrpos(),判断字符在目标字符串中最后出现的位置。
    • 1
      2
      3
      4
      
        $str = "12a4a67a";
        //查找位置
        echo strpos($str,"a");//得到 2,从0开始
        echo strrpos($str,"a");//得到 7
      
  • 替换

    • str_replace(匹配目标,替换的内容,字符串本身),将目标字符串中部分字符串进行替换。
    • 1
      2
      3
      
        $str = "abacd";
        //字符串替换
        echo str_replace("a","b",$str);//得到 bbbcd
      
  • 格式化

    • printf()
    • sprintf()
    • 1
      2
      3
      4
      5
      
        $age = 10;
        $name = "tom";
        //格式化输出
        echo printf("我叫%s,我%d岁了",$name,$age);
        //得到 我叫tom,我10岁了
      
  • 重复/打乱

    • str_repeat(),重复某个字符串N次。

    • str_shuffle(),随机打乱字符串。

    • 1
      2
      3
      
        $str = "abcd";
        echo str_repeat($str,2);//得到 abcdabcd
        echo str_shuffle($str);//得到一个打乱了的字符串
      

数组

数组的概念

数组(array)是将一组数据存储到一个容器中,通过变量指向容器,从而一次性获取所有数据。

数组定义语法

  1. 使用 array() 关键字:

    1
    
    $arr = array(元素1, 元素2, ...);
    

    image-20220124202727304

  2. 使用中括号 [](PHP 5.4+):

    1
    
    $arr = [元素1, 元素2, ...];
    

    image-20220124202820101

  3. 隐式定义:给变量加上中括号,系统自动转为数组。

    1
    2
    
    $arr[] = 值1;     //如果不提供下标也可以,系统自动生成(数字:从 0 开始)
    $arr[下标] = 值2; //该下标可以是字母(单词)或者数字,与变量命名的规则相似。
    

    image-20220124202947455

PHP 数组特点

  • 下标可以是整数或字符串,可混合(索引数组/关联数组/混合数组)。
  • 元素顺序以放入顺序为准,与下标无关。
  • 数字下标自动增长,从 0 开始,若手动指定较大下标,后续自动增长从最大值+1 开始。
  • 特殊值下标自动转换:true→1,false→0,NULL→空字符串。
  • 元素无类型限制,无长度限制。
  • 数组存储在堆区,分配连续内存。

多维数组

数组中元素又是数组,支持任意维度(不建议超过三维)。二维数组示例:

1
2
3
4
5
$arr = array(
    0 => array('name' => 'Tom'),
    1 => array('name' => 'Jim')
);
echo $arr[1]['name']; // Jim

数组遍历

普通数组数据的访问都是通过数组元素的下标来实现访问,如果说数组中所有的数据都需要依次输出出来,就需要我们使用到一些简化的规则来实现自动获取下标以及输出数组元素。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
//二维数组
$arr = array(
    0 => array('name' => 'Tom'),
    1 => array('name' => 'Jim')
);

//访问一维元素:$arr[一维下标]
$arr[0];//结果:array('name' => 'Tom');

//访问二维元素:$arr[一维下标][二维下标]
$arr[1]['name']; //得到 Jim

foreach 遍历: foreach($数组变量 as [$下标 =>] $值)

1
2
3
foreach($arr as $key => $value){
    // $key 为下标,$value 为值
}

foreach 会重置数组指针。

for 循环遍历(要求数字索引连续):

1
2
3
for($i = 0, $len = count($arr); $i < $len; $i++){
    echo $arr[$i];
}

while + each + list 遍历
each() 返回当前指针位置的键值对数组(四个元素:0,1,key,value),指针下移。
list() 将数组元素赋值给变量。
组合使用可实现遍历。

Each函数使用:each 能够从一个数组中获取当前数组指针所指向的元素的下标和值,拿到之后将数组指针下移,同时将拿到的元素下标和值以一个四个元素的数组返回:

  • 0 下标 –> 取得元素的下标值
  • 1 下标 –> 取得元素的值
  • Key 下标 –> 取得元素的下标值
  • Value 下标 –> 取得元素的值
  • image-20220124215827551

如果 each 取不到结果(数组指针移动到最后),返回 false

image-20220124220348510

List 函数使用:list 是一种结构,不是一种函数(没有返回值),是 list 提供一堆变量去从一个数组中取得元素值,然后依次存放到对应的变量当中(批量为变量赋值:值来源于数组):

list 必须从索引数组中去获取数据,而且必须从 0 开始。

正确:

  • image-20220124221446529

错误:变量多于数组元素,没有指定从 0 到指定变量的下标的数组元素。

  • image-20220124221930386

所以 List 与 each 可以配合:each 一定有两个元素就是 0 和 1 下标元素。

List[变量 1,变量 2)= each(数组); //是一种赋值运算,但是可以得到 false 结果(each 取不到正确的结果),整个表达式为 false

image-20220124222415409

数组相关函数

排序函数

  • sort() / rsort():顺序/逆序,下标重排。

    • image-20220126151805161
  • asort() / arsort():顺序/逆序,保留下标。

    • image-20220126151916972
  • ksort() / krsort():按键名排序。

    • image-20220126152034820
  • shuffle():随机打乱。

指针函数

  • reset() / end():重置到首位/末位。

    • image-20220126153216584
  • next() / prev():下移/上移。

    • image-20220126153157775
  • current() / key():获取当前值/下标。

    • image-20220126153014420

注意事项:next 和 prev 会移动指针,有可能导致指针移动到最前或者最后(离开数组),导致数组不能使用,通过 next 和 prev 不能回到正确的指针位置。只能通过 end 或者 reset 进行指针重置。

其他函数

  • count():元素个数。
  • array_push() / array_pop():尾部添加/删除。
  • array_shift() / array_unshift():头部删除/添加。
  • array_reverse():反转。
  • in_array():判断值是否存在。
  • array_keys() / array_values():获取所有键/所有值。