PHP 是一种运行在服务器端的脚本语言,可以嵌入到 HTML 中。
基础语法
PHP 代码标记
当解析一个文件时,PHP 会寻找起始和结束标记,也就是 <?php 和 ?>,这告诉 PHP 开始和停止解析二者之间的代码。此种解析方式使得 PHP 可以被嵌入到各种不同的文档中去,而任何起始和结束标记之外的部分都会被 PHP 解析器忽略。
短标记: <? 代码 ?>
脚本标记: <script language="php">代码</script>
标准标记(常用): <?php 代码 ?>
// 如需使用短标记的用法,需去配置文件中开启
如果文件内容以 PHP 代码结束,最好省略 PHP 的结束标记。
<?php
echo "Hello world";
PHP 注释
// 单行注释
# 单行注释
/* 多行注释
* 也称为块注释
*/
PHP 语句分隔符(执行符)
在 PHP 中,代码是以行为单位,系统需要通过判断行的结束,该结束通常都是一个符号分号 “;”
- PHP 中标记结束符 ?> 有自带语句结束符的效果,也就是说最后一句代码可以不用带分隔符
- PHP 中其实很多代码的书写并不是嵌入 HTML 中,而是单独存在,通常书写习惯中就不建议使用标记结束符 ?>,PHP 会自动从开始到最后全部认为是PHP代码,因此建议所有行结束的代码后都加上分号
基本概念
表达式
表达式是 PHP 最重要的基石,在 PHP 中,几乎所写的任何东西都是一个表达式。简单但却最精确的定义一个表达式的方式就是“任何有值的东西”。
最基本的表达式形式是常量和变量。当键入 “$a = 5″,即将值 5 分配给变量 $a,换句话说 5 是一个值为 5 的表达式。
常用输出语法
echo
var_damp()
print_r()
文件引入
include
将目标文件的代码复制一份到当前文件中,可以使用当前文件的全局变量
include 'folder/file.php';
include_once
目标文件仅复制一次到当前文件中,如果有重复调用,后面的则不会重新复制
require
强加载
require_once
import
变量 Variable
变量源于数学,是计算机语言中能储存计算结果或能表示值抽象概念,变量可以通过变量名访问,在指令式语言中,变量通常是可变的。
- 变量是用来存储数据的
- 变量是存在名字的
- 变量是通过名字来访问数据的
- 变量是可以改变的
变量的声明
在PHP中不需要使用任何关键字来定义变量,但所有变量都必须使用 “$” 符号开头
$var1; // 定义变量
$var2 = 3; // 定义变量并赋值
echo $var2; // 访问变量
unset($var2); // 删除变量
- 变量名必须以 “$” 开始;
- 名字由字母、数字和下划线 “_” 构成,但是不能以数字开头;
- 还允许中文变量(不建议)。
预定义变量(超全局变量)
系统定义的变量,存储了许多需要用到的数据(预定义变量都是数组)。
$_GET; // 获取地址栏的传参
$_POST; // POST 提交的数据都会保存在此
$_REQUEST; // GET 和 POST 提交的都会保存
$GLOBALS; // PHP 中所有的全局变量
$_SERVER; // 服务器信息
$_SESSION; // session 会话数据
$_COOKIE; // cookie 会话数据
$_ENV; // 环境信息
$_FILES; // 用户上传的文件信息
可变变量
如果一个变量保存的值刚好是另一个变量的名字,那么可以直接通过访问一个变量得到另一个变量的值,在变量前再多加一个$ 符号
$name = 'puji';
$$name = 'puji.design';
echo $$name; // puji.design
echo $puji; // puji.design
变量传值
将一个变量赋值给另一个变量,这样的过程称为变量传值。
变量传值一共有两种方式:
值传递
将变量保存的值复制一份,然后将新的值给另一个变量进行保存。(两个变量没有关系)
$a = 1;
$b = $a;
引用传递
将变量保存的值所在的内存地址,传递给另一个变量,两个变量指向同一快内存空间(两个变量是同一个值)
$a = 1;
$b = &$a;
变量的作用域
局部变量
局部变量也称为内部变量,局部变量是在函数内定义的,其作用域仅限于当前函数内不,离开该函数后无法使用。
全局变量
全局变量也称为外部变量,在函数的外部定义,他的作用域为从变量定义处开始,到程序文本结束。
$a = 1;
function test() {
global $a; // 声明 $i 为全局变量,然后再在这个函数内部使用
echo $a;
}
$a = 1;
function test() {
echo $GLOBALS['a'];
}
但是在 PHP 函数中无法直接使用全局变量,如需使用必须使用 global 声明变量。
静态变量
在函数内部定义的变量的时候使用 static 关键字来定义的变量,特点是在函数执行完毕之后变量不会立即消失,当再次调用函数时,静态变量保存的值依然存在,并且在第一次执行函数的时候会初始化值。
// 普通变量
function test() {
$a = 1;
$a = $a + 1;
return $a;
}
echo test(); // 2
echo test(); // 2
echo test(); // 2
// 静态变量
function test() {
static $a = 1;
$a = $a + 1;
return $a;
}
echo test(); // 2
echo test(); // 3
echo test(); // 4
判断变量是否存在
$name = 'PUJI';
var_dump( isset($name) );
删除变量
删除变量仅可在定义变量的块中进行删除,如全局变量,无法在函数体内删除。
unset( $name );
常量 Constant
常量也是用于保存数据的,是一种在程序运行中不可改变的量(数据)。常量一旦定义,数据不可改变。
常量的定义
常量由两种定义方式
// 使用定义常量的函数
define('常量名', 常量值);
// 使用 const 关键字 (5.3 之后才有的方法)
const 常量名 = 常量值;
const PI = 3.14;
echo PI;
define('-_-', 'smile');
echo constant('-_-');
- 常量不需要使用 $ 符号,一旦使用系统会认为是变量
- 常量没有变量的作用域,可以在任何地方定义和使用
- 常量的名字组成由字母、数字和下划线组成,同样不能以数字开头;
- 常量名通常是以大写字母为主(与变量进行区别)
- 常量的命名比较松散,可以使用特殊字符定义常量,单使用特殊字符,必须用 define() 的形式;
- 常量由于不可修改,所以在创建常量的时候就需要赋值
- 常量的值只能是 bool,int,float,string类型
常量的使用
常量的使用,不受变量中的作用域影响,可以在不同地方直接使用。
const NAME = 'PUJI';
function show() {
echo NAME;
}
show();
判断常量是否存在
const NAME = 'PUJI';
var_dump( defined('NAME') );
系统常量
PHP_VERSION; // PHP 版本号
PHP_OS; // 当前系统
PHP_INT_SIZE; // 整形大小
PHP_INT_MAX; // 整形能表示的最大值(PHP中整形是允许出现负数:带符号)
在 PHP 中还有一些特殊的常量,他们有双下划线开始+常量名+双下划线结束,这种常量称之为系统魔术常量。魔术常量的值通常会跟着环境变化,但是用户改变不了。
__DIR__; // 当前被执行的脚本所在电脑的绝对路径
__FILE__; // 当前被执行的脚本所在电脑的绝对路径(带自己文件名)
__LINE__; // 当前所属的行数
__NAMESPACE__; // 当前所属的命名空间
__CLASS__; // 当前所属的类
__METHOD__; // 当前所属的方法
查看全部常量
get_defined_constants()
数据类型 Data Type
在PHP中指的是数据本身的类型,而不是变量的类型。PHP是一种弱类型语言,变量本身没有数据类型。
在PHP中将数据分为三大类与八小类
- 简单(基本)数据类型
- 整形:int / integer, 系统分配4个字符存储,表示整数类型(有前提)
- 浮点型:float/double, 系统分配8个字节存储,表示小数或者整形存不下的整数。
- 字符串型:string,系统根据实际长度分配,表示字符串(引号)
- 布尔型:bool/boolean,只有两个值 true / false
- 复合数据类型
- 对象型:object,存放对象
- 数组型:array,一次存放多个数据
- 特殊数据类型
- 资源类型:resource 存放资源数据(PHP外部数据,如数据库,文件)
- 空类型:null,只有一个值就是null(不能运算)
整形类型 (Int)
保存整数数值(范围限制)4个字节存储数据,即 32 位,换算为十进制最大值为42亿多,但是在 PHP 中默认是有符号类型(区分正负数),因此最大数与最小数大概为21亿
在 PHP 中提供了四种整形的定义方式:十进制定义,二进制定义,八进制定义和十六进制定义
$a = 100; // 十进制
$a = 0b100; // 二进制,前面带 0b
$a = 0100; // 八进制,前面带 0
$a = 0x100; // 十六进制,前面带 0x
- 十进制:逢 10 进 1,出现的数字是 0-9
- 二进制,逢 2 进 1,出现的数字是 0-1
- 八进制,逢 8 进 1,出现的数字是 0-7
- 十六进制,逢 16 进 1,出现的数字是 0-9 以及 a-f
浮点类型 (Float)
小数类型以及超过整数所能存储范围的整数(不保证精度),进度范围大概在15个有效数字左右
// 定义方式 1
$f = 1.23;
// 定义方式 2
$f = 1.23e10; // 科学计数法,其中 e 表示底 10
注:尽量不要使用浮点数进行精确判断,浮点数保存的数据不够精确,而且在计算机中凡是小数基本上存的都不准确。
字符串型 (String)
基本使用
使用单引号或双引号进行包裹,注意:单引号内不可以调用变量,双引号可以调用变量
$a = 'PUJI';
echo '输出1: ' . $a;
echo "输出2: {$a}";
字符串拼接
使用 “.” 进行不同字符串的拼接
$a = 'PUJI';
$b = 'Design';
echo $a . ' ' . $b;
字符串转义符
将具有含义的字符进行转换,使用反斜杠进行转换 “\”
$a = "PUJI Design \"https://puji.design\"";
// 制表符
\t tab
\n 换行
定界符
当需要频繁使用单引号或双引号时,可以使用定界符来实现,这样更方便阅读。定界符中的名称可以自定义,如 str
$a = <<<str
<h1 style="color: blue">PUJI Design</h1>
str;
echo $a;
strlen()
获取字符串长度
$a = 'PUJI Design';
echo strlen( $a );
mb_strlen()
可以指定字符编码进行显示
$a = '朴及设计';
echo mb_strlen( $a );
trim()
去除字符串首尾的空白字符(或其他字符)
ltrim()
rtrim()
strtoupper()
strtolower()
substr_count()
strpos()
strstr()
strrchr()
substr()
截取字符串
$file = 'user.jpg';
echo substr( $file, 0, -4 );
explode()
拆分字符串
$a = 'puji.design';
print_r( explode( ".", $a ) );
implode()
合并字符串
$arr = [ 'PUJI', 'Design' ];
echo implode( '.', $arr );
str_replace()
ucfirst()
将单词首字母大写
ucwords()
每个单词首字母大写
md5()
将字符串转换为32位字符
布尔类型 (Boolean)
通常用于判断比较
$a = true;
在进行某些数据判断的时候,需要特别注意类型转换
empty() // 判断数据的值是否为空,而不是 null
isset() // 判断数据存储的变量本身是否存在
is_null() // 判断是否为空类型
数据类型转换
在很多的条件下,需要指定的数据类型,这种情况下需要将php取得的数据转换成目标数据类型
在PHP中有两种类型转换方式
进制转换
decbin() // 十进制转二进制
decoct() // 十进制转八进制
dechex() // 十进制转十六进制
bindec() // 二进制转十进制
...
自动转换
系统根据需求自己判断,自己转换(用的较多,但效率偏低)
$a = 'abc1.1.1';
$b = '1.1.1abc';
// 自动转换
echo $a + $b;
强制(手动)转换
人为根据需要的目标类型进行转换
$a = 'abc1.1.1';
$b = '1.1.1abc';
// 强制转换
echo (float)$a, (int)$b;
在转换过程中使用较多的是转布尔类型(判断)和转数值类型(算术运算)
其他类型转数值型
- 布尔型 true 为1,false 为0;
- 字符串转数值由自己的规则;
- 以字母开头的字符串,永远为0;
- 以数字开头的字符串,取到第一个字符前的数字(不会同时包含两个小数点)
数据类型判断
通过一组类型判断函数来判断变量,最终返回这个变量所保存数据的数据类型:是一组以 is_ 开头后面跟类型名字的函数。返回的结果 true / false
// 格式结构
is_XXX(变量名)
is_int // 是否为整形
is_float // 是否为浮点型
is_string // 是否为字符串
is_bool // 是否为布尔型
is_array // 是否为数组型
is_object // 是否为对象型
// 判断类型使用 var_dump() 输出结果
$a = 1;
var_dump(is_int($a)); // bool(true)
获取以及设定数据类型
Gettype(变量名); // 获取类型,得到的是类型对应的字符串
Settype(变量名); // 设定类型,与强制转换不同
强制转换,是对数据值复制的内容进行处理,Settype 会直接改变数据本身
settype($a,'int');
运算符 Operator
运算符是对一个或多个操作数(变量或数值)执行某种运算的符号,也称为操作符,可根据操作数的数量分为一元运算符、二元运算符以及三元运算符。
赋值运算符
使用符号 “=” , 表示将右边的结果(可以是变量、数据、常量和其他运算出来的结果等),保存到内存的某个位置,然后将位置的内存地址赋值给左侧的变量/常量。左边的操作数必须是一个变量或常量
赋值运算符还包括其他一些方法
$a += 1 // 相当于 $a = $a + 1
$a -= 1 // 相当于 $a = $a - 1
$a *= 1 // 相当于 $a = $a * 1
$a /= 1 // 相当于 $a = $a / 1
$a %= 1 // 相当于 $a = $a % 1
$a .= "1" // 相当于 $a = $a."1"
算术运算符
基本的算数操作,使用符号 “+”、 “-“、 “*”、 “/”、 “%”,
- “-” 不仅可以对不同的变量进行运算,还可以对自身进行取反,如 -$a(不会修改变量原始的值)
- 取余的计算,两个数必须为整数
- 在进行除法运算或取余运算时,对应的第二个数(被除数)不能为0
递增/递减运算符
++$a // $a的值加一,然后返回 $a
$a++ // 返回 $a, 然后 $a 的值加一
--$a // $a的值减一,然后返回 $a
$a-- // 返回 $a,然后 $a 的值减一
字符串运算符
在 PHP 中的字符串运算符只有一个英文的句号 “.”,也称为连接运算符
$a = 'PUJI';
$b = 'Design';
echo $a.$b
比较运算符
比较两个数据的大小,或者两个内容是否相同 “>”、 “<“、 “>=”、 “<=”、 “==”、 “!=”、 “===”、 “!==”,返回值为boolean
逻辑运算符
对表达式不同的结果进行逻辑判断, “&&”、 “||”、 “xor”、 “!”,运算出的结果是布尔类型的值。参与逻辑运算的表达式的值是布尔类型的值,如果不是布尔类型的值会被自动转换成布尔类型的值然后再参与运算。
&& 或 and // 逻辑与,所有条件同时成立
|| 或 or // 逻辑或,所有条件只要有一个满足
xor // 逻辑异或,当左右两边表达式的值不一样的时候结果返回true,否则 false
! 或 not // 逻辑非,对已有的条件进行取反
逻辑与和逻辑或隐含了一个短路问题,即运算符的优先级问题。
$a = false;
$b = 1;
$a && ++$b;
echo $b; // 1
位运算符
对操作数中的每一个二进制位进行运算,由于 PHP 主要用于网站开发,所以位运算符在 PHP 中使用较少。
三元运算符
用于判断条件是否为真,然后进行后面表达式的运算
// 基础格式
表达式1 ? 表达式2 : 表达式3
如果表达式1为真,则执行表达式2,否则执行表达式3
$a = true ? 10 : 20 // 10;
$b = 'PUJI';
echo $b?:'Design'; // PUJI
// ?? 满足两个条件即可,1,变量存在,2,不为空(null)
$name = 0;
echo $name??'NO'; // 0
错误控制运算符
使用 “@”,用于屏蔽错误
echo @$a;
执行运算符
使用反引号 “ ,可以将操作系统的命令放在里面执行。因为涉及到跨平台,因此命令可能有所不同。
`ipconfig`;
数组运算符
使用符号 “=>”
对象运算符
使用符号 “->”
类型运算符
instanceof
运算符优先级
运算符优先级指定了两个表达式绑定得有多“紧密”。
- 优先级的概念:谁的优先级别高就先算谁。
- 结合方向:规定了从哪个方向开始计算,从左往右或从右往左
流程控制
对 PHP 程序执行的过程进行控制即是流程控制
- 顺序执行:按照代码的先后顺序自上而下的执行即是顺序执行,也就是说对执行过程没有进行控制
- 分支执行:分支执行可以根据条件是否满足来选择执行某些代码,PHP 的分支执行主要通过两种语句( if , switch )来实现
- 循环执行:while语句,do…whild语句,for语句
- 特殊的流程控制语句:
if 语句
如果条件为真则执行里面的语句。
// 单向条件
if(表达式) {
执行语句
}
// 双向条件
if(表达式) {
执行语句1
} else {
执行语句2
}
// 多向条件
if(表达式1) {
执行语句1
} elseif {
执行语句2
} ... {
...
} else {
不满足全部条件执行语句
}
// 简写形式
if (表达式):
...
else:
...
endif;
switch 语句
// 基础格式
switch(表达式) {
case 值1:
执行语句1;
break;
case 值2:
执行语句2;
break;
...
default:
不满足全部条件执行语句
}
// 简化写法
switch(表达式):
case 值1:
执行语句1;
break;
case 值2:
执行语句2;
break;
...
default:
不满足全部条件执行语句
endswitch;
- 表达式的值最好是整形或字符串形;
- 每个 case 的执行语句后都需要添加 break; 来跳出;
- 如果某个 case 语句后面并没有接语句块,那么就同下条件的语句相同;
- case 后面语句块不需要花括号 {} 来包裹。
while 语句
当条件满足时就执行内部的语句,执行结束后,继续判断条件是否满足是否进行继续执行,直到条件不满足后终止执行。
// 基础格式
while(表达式) {
执行语句
}
// 简化写法
while (表达式):
...
endwhile;
do…while 语句,首先执行循环里的执行语句,再判断while里的表达式是否为真进行后面的循环执行。
// 基础格式
do {
执行语句
} while(表达式);
for 语句
for(表达式1;表达式2;表达式3) {
执行语句
}
- 执行for循环语句时首先会执行表达式a;
- 表达式1一般会放一些初始化语句,如变量声明 如 $i = 0,也可以放多个表达式中间使用逗号隔开;
- 表达式2一般会放用来判断的表达式,也可以放多个表达式中间使用逗号隔开;
- 表达式3一般会放对一些对初始化变量进行自增的语句。
break 语句
用于 switch 语句或循环语句 for, while, do…while, foreach,用于中断这些语句。
for($i=0;$i<10;$i++) {
if($i==5) {
break;
}
echo $i;
}
// 跳出 2 层循环
$num = 0;
while (true):
$num++;
switch ($num) {
case $num % 2 == 0;
echo $num;
break;
case $num % 15 == 0;
echo $num;
break 2;
}
endwhile;
break; 仅仅中断当前所在的循环语句,如果循环体内有多个循环,可以使用 break 2; (数字可以自己设定) 进行设置跳出的层级。
continue 语句
跳出本次循环,继续执行之后的循环,只能用在循环语句。
exit() 语句
结束当前 PHP 整个脚本的执行。
// 基础格式
exit();
或
exit;
函数
声明
function 函数名([参数1,参数2,...]) {
函数体 // 任何有效的 PHP 代码都可以作为函数体使用
reture 表达式; // 可以从函数中返回一个值,也可以不返回
}
调用
函数需要调用后才会被执行,执行的过程是相对独立的,执行完毕返回调用的位置继续向下执行。函数的调用和函数的声明顺序没有联系。
函数名();
传递参数(重要)
参数分为形参与实参,形参由零个、一个或多个变量组成,实参由零个、一个或多个参数组成,每个参数是一个表达式,用逗号分隔。实参的数量不得少于形参的数量,如果多余形参的数量,多处的部分不进行函数的运算。如果实参数量少于形参数量则会报错。
按值传递参数(默认)
对形式参数的操作,不会影响到实际参数(变量)的值,两者没有联系。
// 返回值 11 10
function test($a) {
echo ++$a;
}
$b = 1;
test($b);
echo $b;
按引用传递参数
形式参数和实际参数指的是同一个参数,只是名称不一样,所以对于形式参数的操作会直接影响到实际参数(变量)。
// 返回值 11 11
function test(&$a) {
echo ++$a;
}
$b = 1;
test($b);
echo $b;
不固定参数数量
function sum(...$vars) {
return array_sum($vars);
}
echo sum(1,2,3);
默认参数
可以给形式参数设置默认值,直接赋值即可,如果调用函数中不传实参,则使用函数参数的默认值,如果调用函数传了实参,则使用实参。给形参添加默认值的时候是从右往左的顺序添加。
// 10
function test($a=10) {
echo ++$a;
}
test();
// 30
function test($a, $b=10) {
echo $a + $b;
}
test(20);
可变长度参数列表
PHP 提供给我们可以直接使用的
// func_get_args() 返回传入函数的参数中的所有值 (数组)
function () {
func_get_args();
}
test(1,2,3);
// func_get_arg() 返回传入函数的参数中相应序号的值
function () {
func_get_arg(0);
}
test(1,2,3);
// func_num_args() 返回传入函数的参数的数量
function () {
func_num_args();
}
test(1,2,3);
这三个函数可以使用在我们的自定义函数内部,可以返回给我们一些关于参数的信息。
参数类型约束
https://www.bilibili.com/video/BV1A4411M7iA?p=38
在非严格模式下,传过来的参数会强制转换为相应的类型,如果无法转换则报错。在严格模式下,传来的参数类型必须和形参里规定的类型一致,否则会报错。
// 非严格模式
function show( int $num ) {
return $num;
}
var_dump(show('1'));
// 严格模式
declare( strict_type = 1 );
function show( int $num ) {
return $num;
}
var_dump(show(1));
返回值
函数的返回值是将函数执行后的结果返回给调用者,默认如果不写返回,函数的返回值为 null,return不仅可以将值返回给调用的地方,还可以结束这个函数的运行。
function add($a,$b) {
return $a + $b;
}
var_dump(add(1,2));
返回值类型约束
function sum(): int {
return 1;
}
// 返回值为空时的处理方式
function sum(): ?int {
return null;
}
如果函数不需要返回值,可在函数前加上 void
function sum(): void {
}
可变函数 (变量函数)
PHP 支持可变函数的概念,如果一个变量名后面有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可用来实现包括回调函数、函数表在内的一些用途。
可变函数不能用于如 echo , print , unset() , isset() , empty() , include , require 以及类似的语言结构。需要使用自己的包装函数来将这些结构作用可变函数。
function test(){
echo 'PUJI Design';
}
$a = 'test'; // 把函数名字加上引号,赋值给变量即可
$a(); // 相当于 test();
递归函数
递归函数即是在函数内部自己调用自己的函数。
// 阶乘
function recursive( $num ) {
if ($num == 1) return $num;
return $num*recursive($num-1);
}
echo recursive( 4 );
// 返回值 3 2 1 0 End 0 1 2 3
function test($a) {
echo $a;
if($n > 0) {
test( $a - 1 );
} else {
echo 'End';
}
echo $a;
}
test(3);
- 函数在被调用的执行过程中会在内存里分配空间用于存储临时数据,函数在执行过程中默认之间是没有联系的(除静态变量,按引用传,全局变量),里面定义的变量都是局部变量,相互之间没有影响;
- 在函数内部需要有适时结束的条件判断语句。
内部/内置函数
PHP 给我们提供了很多内置的函数或结构,我们可以在实际的开发中直接使用。部分内置函数需开启特定的 PHP 扩展模块,否则使用他们的时候就会得到一个致命的“未定义函数”错误。
数组
数组数据类型属于复合数据类型,是用于存放一组数据的单个空间
数组的分类
- 名字如果是整型,那么这个数组就是索引数组
- 名字如果是字符串型,那么这个数组就是关联数组
创建数组
PHP 中创建数组非常灵活,与其他许多编程语言不通的是 PHP 不需要在创建数组时指定数组的大小,甚至不需要在使用数组之前声明,也可以在同一个数组中存储任何类型的数据。
// 方法 1
$变量名[索引值] = 具体的值;
$a[0] = 1;
$a[2] = 'PUJI';
$a[3] = true;
$a[4] = 36.9;
print_r($a); // 数组需要使用 print_r() 或 var_dump() 函数来输出
$a['num'] = 1;
$a['name'] = 'PUJI';
$a['enable'] = true;
$a['point'] = 36.9;
// 方法 2
$a = [
1,2,3
];
$a = [
0 => 1,
1 => 2,
2 => 3
];
$a = [
'num' => 1,
'name' => 'PUJI',
'age' => 36
];
// 方法 3
$函数名 = array(索引值=>具体的值, ...);
$a = array(1,'PUJI',true,36.9);
$a = array(
0 => 1,
1 => 'PUJI',
2 => true,
3 => 36.9
);
$a = array(
'num' => 1,
'name' => 'PUJI',
'enable' => true,
'point' => 36.9
);
// 使用数组里具体某一个数据的方法
数组变量名称[索引值];
echo $a[0];
- 如果省略索引值不写,那么默认索引值就是整数,从0开始依次添加。
二维数组
数组中可以存放其他数组,如果数组中存放了新的数组,可以称为二维数组,如果包含多层级的数组嵌套,可称为多维数组。
// 二维数组
$a = [
[1,'a',true],
[2,'b',true],
[3,'c',false]
]
// 多维数组访问某一个数据的方法
echo $a[0][1];
数组的遍历
PHP 中很少需要自己手动将大量的数据赋值到数组变量中,而是通过调用函数返回结果集(这些结果集数据很多情况下都是数组类型),使用数组类型返回的目的是将多个相互关联的数据,组织在一起形成一个集合,以方便我们的批量处理的目的,所以我们实际工作中遍历数组的需求比较多。
// 使用 for 循环可以遍历数组 (使用不多)
$arr = [
'a','b','c','d','e','f'
];
for( $i=0; $i<count($arr); i++ ) {
echo $arr[$i];
}
// count()返回数组里数据的数量,还可以获取多维数组的个数
$arr1 = [
[1,2,3],
[4,5,6]
];
echo count($arr1,1); // 返回值 8
foreach() 遍历
遍历关联数组无法使用 for() 循环进行,可以使用 foreach() 来遍历,可以遍历索引数组和关联数组
foreach( 数组名 as 变量1 ) { // 变量1代表当前正在经历的数据,名称可自定义
每次循环执行的语句
}
$arr = [
'name' => 'PUJI',
'num' => 39
];
// 遍历数据中具体的值
foreach( $arr as $v ) {
echo $v;
}
// 遍历数据中的索引值与具体的值
foreach( $arr as $k=>$v ) {
echo $k . '=' .$v;
}
遍历多维数组
如果数组中的数据都是数组(有规律),可以使用 foreach() 进行嵌套来遍历
$arr = [
[1,2,3],
['a','b','c','d','e'],
[1,2,3,4,5,6,7,8],
[1,2]
];
foreach ( $arr as $val1 ) {
foreach ( $val1 as $val2 ) {
echo $val2;
}
}
如果数组中的数据没有规律,可以使用递归思想来解决
$arr = [
'a',
'b',
'c',
[1,2,3,4,5]
];
function fn($arr) {
foreach ( $arr as $item) {
if(is_array($item)) {
lined($item);
} else {
echo $item;
}
}
}
fn($arr);
count()
获取数组长度
key()
获取键名
current()
获取键值
next() / prev()
下 / 上一个数组项目
$arr = [
'PUJI',
'Design'
];
echo current($arr); // PUJI
next($arr);
echo current($arr); // Design
// 简化写法
$arr = [
'PUJI',
'Design'
];
echo current($arr); // PUJI
echo next($arr); // Design
// 遍历数组
$users = [
['name' => 'A', 'num' => '1'],
['name' => 'B', 'num' => '2'],
['name' => 'C', 'num' => '3'],
];
while( $user = current($users) ) {
echo $user['name'];
echo $user['age'];
next($users);
}
list
$arr = ['PUJI', 'Design'];
list($a, $b) = $arr;
echo $a; // PUJI
// 关联数组
$arr = ['name'=>'PUJI', 'work'=>'Design'];
list('name'=>$a, 'work'=>$b) = $arr;
echo $a; // PUJI
// 遍历数组
$users = [
['name' => 'A', 'num' => '1'],
['name' => 'B', 'num' => '2'],
['name' => 'C', 'num' => '3'],
];
while(list('name'=>$name, 'num' => $num) = current($users)) {
echo "name:{$name}, num:{$num}";
next($users);
}
array_push()
从后面添加数据
$users = ['A','B'];
array_push($users, 'C');
print_r($users); // A, B, C
array_pop()
从后面删除数据
$users = ['A','B'];
array_pop($users);
print_r($users); // A
array_unshift()
从前面添加数据
array_shift()
从前面删除数据
array_keys()
in_array()
$allowImageType = ['jpeg','jpg','png'];
$file = 'file.txt';
$ext = strtolower(substr(strrchr($file,','), 1));
if( !in_array($ext, $allowImageType) ) {
echo 'wrong';
} else {
echo 'success';
}
array_key_exists()
$allowImageType = ['jpeg'=>2000000,'jpg'=>2000000,'png'=>2000000];
$file = 'file.txt';
$ext = strtolower(substr(strrchr($file,','), 1));
if( !array_key_exists($ext, $allowImageType) ) {
echo 'wrong';
} else {
echo 'success';
}
array_filter()
array_map()
unset()
array_values()
array_merge()
array_change_key_case()
array_walk_recursive()
var_export()
serialize() / unserialize()
预定义超全局数组变量
系统已经定义好的变量,存放的数据类型是数组。PHP 中许多预定义变量都是“超全局”的,这意味着他们在一个脚本的全部作用域中都可用。在函数或方法中无需执行 global 就可以访问他们。
$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV
传递数据(提交数据)给服务器端主要有两种方式
1、get 方式
url?参数名=参数值& ...
在请求的php文件这边可以通过 $_GET 来获取
get方式的优点是比较方便,但是安全性比较低
2、post 方式
在请求的php文件这边可以通过 $_POST 来获取
post方式适合传递一些数据量较大的数据,安全性比较高
处理数组的相关函数
处理数组的函数很多,在需要使用的时候查找 PHP 官方手册即可,以下几种函数较为常用
array_count_values(数组名) // 统计数组中所有的值出现的次数
array_key_exists(键名,数组名) // 检查给定的键名或索引是否存在于数组中,返回 boolean 值
array_search(键值,数组名[,true]) // 在数组中搜索给定的值,如果成功返回相应的键名,失败则返回false
count(数组名) // 计算数组中单元数目或对象中的属性个数
in_array(键值,数组名) // 寻找数组中是否存在某个值,如果找到返回true,否则false
list // 把数组中的值赋值给一些变量,仅用于索引数组并从索引号0开始
asort // 对数组进行排列并保持索引关系
array_filter // 用回调函数过滤数组中的单元
面向对象
https://www.bilibili.com/video/BV14x411o7SL
声明
class User {
protected $name;
public function say() {
return $this->name;
}
public function setName( string $name ) {
$this->name = $name;
}
}
$obj = new User;
$obj->setName('PUJI');
echo $obj->say();
- public:公共,可在实例化对象中使用
- protected:保护,只可在类里使用,可继承
- private:私有,只可在类里使用,不可继承
$this
调用类中的方法或属性。指向当前实例化的对象。
class User {
protected $name;
public function say() {
return $this->getName();
}
public function setName( string $name ) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
$obj = new User;
$obj->setName('PUJI');
echo $obj->say();
静态属性
属于类自有的属性,可供所有的实例化对象共用。使用 self 进行调用。
class User {
protected static $range = "Design";
public function say() {
return self::$range;
}
}
$obj = new User;
echo $obj->say();
静态方法
属于类的共用方法。静态方法中不可使用 $this。
class User {
protected static $range = "Design";
public static function say() {
return self::$range;
}
}
$obj = new User;
echo $obj->say();
类常量
使用 const 定义,作用域在类里,需要使用类进行调用
class Modal {
const PUJI_AGE = 36;
}
echo Modal::PUJI_AGE;
Extends 继承
使用 extends 继承父类的属性和方法,只可继承1个。
class Notify {
public function message() {
return '发送通知消息';
}
}
class User extends Notify {
public function register() {
return $this->message();
}
}
class Comment extends Notify {
public function send() {
return $this->message();
}
}
echo (new User)->register();
echo (new Comment)->send();
属性和方法的重写
在子类中重写属性和方法,将覆盖父类的子类与方法。
class Notify {
protected $age = 36;
public function message() {
return $this->age;
}
}
class User extends Notify {
protected $age = 1;
public function message() {
return 'PUJI Lab'.$this->age;
}
public function register() {
return $this->message();
}
}
class Comment extends Notify {
public function send() {
return $this->message();
}
}
echo (new User)->register();
echo (new Comment)->send();
禁止重写
防止子类重写方法,可以使用 final 进行声明。
class Notify {
protected $age = 36;
public final function message() {
return $this->age;
}
}
class User extends Notify {
protected $age = 1;
public function register() {
return $this->message();
}
}
class Comment extends Notify {
public function send() {
return $this->message();
}
}
echo (new User)->register();
echo (new Comment)->send();
Trait 多重继承
https://www.bilibili.com/video/BV14x411o7SL?p=13
如果一个类中同时有 Extend 继承与 Trait 继承,父类中同样有相同的属性或方法,以 Trait 类更具优先级。
trait Log {
public function save() {
return __METHOD__;
}
}
trait Common {
public function total() {
return __METHOD__;
}
}
class Topic {
use Log, Common;
}
$topic = new Topic;
echo $topic->save();
echo $topic->total();
trait 继承 trait
trait Log {
public function save() {
return __METHOD__;
}
}
trait Common {
use Log;
public function total() {
return __METHOD__;
}
}
trait 冲突问题
如果调用的trait类中同时拥有相同的方法,会产生冲突而报错,可以使用以下方法进行解决。
trait Log {
public function save() {
return __METHOD__;
}
}
trait Common {
public function save() {
return __METHOD__;
}
}
class Topic {
use Log, Common {
Log::save insteadof Common;
Common::save as send;
}
}
$topic = new Topic;
echo $topic->save();
echo $topic->send();
trait 访问权限控制
使用 protected 进行保护
trait Log {
protected function save() {
return __METHOD__;
}
}
抽象类与抽象方法
使用 abstract 关键词定义。父类定义了抽象方法,子类需重新有这个抽象方法。
abstract public function name();
构造函数
适合传递参数
class Code {
protected $width;
public function __construct( int $width ) {
$this->width = $width;
}
public function make() {
return $this->width;
}
}
echo (new Code(100))->make();
析构函数
对象不使用后就进行卸载。
class Code {
protected $width;
public function __construct( int $width ) {
$this->width = $width;
}
public function make() {
return $this->width;
}
public function __destruct() {
echo 'Desturct';
}
}
$a = new Code(100);
echo $a->make();
__get
https://www.bilibili.com/video/BV14x411o7SL?p=20
__set
接口
https://www.bilibili.com/video/BV14x411o7SL?p=11
interface implements
命名空间
https://www.bilibili.com/video/BV1Zx411R7Wv
类似于电脑中的文件夹,使用反斜杠来分隔每个路径
// file1.php
namespace Modal;
function make() {
echo 'a';
}
// file2.php
namespace User;
function make() {
echo 'b';
}
// 调用
include 'file1.php';
include 'file2.php';
Modal\make();
User\make();
正则表达式
正则表达式就是描述了一类字符串的特征,通过这个特征与特定的函数配合使用,对其他的字符串进行匹配、查找、替换、分隔等操作。不是所有字符操作都用正则表达式,只有遇到复杂字符串处理的时候,才会用到正则表达式。正则表达式并不是 PHP 自己的产物,在很多领域都会见到他的应用。
语法规则
正则表达式由普通字符 (如 a 到 z) 与元字符 (有特殊功能的字符,如* + ? 等) 等组成的一个字符串。
/a/ // a是普通字符, / 是定界符(表示正则表达式的开始或结束)
$pattern = '/test/';
$str = 'testabctest'
preg_match_all($pattern, $str, $arr);
定界符
我们一般习惯使用正斜线 “/” 作为定界的字符,除了字母、数字和反斜线以外的字符都可以作为定界符。定界符放在正则表达式的起始位置,前后一致。
普通字符
没有特殊含义的字符,如 a ~ z , A ~ Z , 0 ~ 9 , 双引号 , 单引号。
元字符
元字符指的是在正则表达式中有特殊含义的字符
\d \\ 匹配任意一个十进制数字,等价于 0~9
\D \\ 匹配任意一个除十进制数字以外字符
\s \\ 匹配人意一个空白字符,如换页符、换行符、回车符、制表符、垂直制表符
\S \\ 匹配除空白字符以外的任何一个字符
\w \\ 匹配任意一个数字或字母或下划线
\W \\ 匹配除数字、字母、下划线以外的任意一个字符
. \\ 匹配除换行符以外的任意一个字符
* \\ 匹配0次、或1次、或多次其前面的字符
+ \\ 匹配1次或多次其前面的字符
? \\ 匹配0次或1次其前面的字符
{n} \\ 表示其前面字符恰好出现n次
{n,} \\ 表示其前面字符出现不少于n次
{n,m} \\ 表示其前面字符出现不少于n次,最多出现m次
^或\A \\ 匹配字符串开始位置
$或\Z \\ 匹配字符串的结束位置
| \\ 匹配两个或多个模式
[] \\ 匹配方括号中的任意一个字符
[^] \\ 匹配除方括号中字符以外的任意一个字符
() \\ 将括号中作为一个整体以便将其中的内容获取到
常用函数
preg_filter // 执行一个正则表达式搜索和替换
preg_grep // 返回匹配模式的数组条目
preg_last_error // 返回最后一个PCRE正则执行产生的错误代码
preg_match_all // 按指定的正则表达式,在给定的字符串中进行搜索,匹配到复合特征的部分取出来
preg_match // 执行一个正则表达式匹配
preg_quote // 转义正则表达式字符
preg_replace_callback // 执行一个正则表达式搜索并且使用一个回调进行替换
preg_replace // 执行一个正则表达式的搜索和替换
preg_split // 通过一个正则表达式分隔字符串
原子组 / 原子表
日期与时间
https://www.bilibili.com/video/BV1A4411M7iA?p=54
在 PHP 中可以使用相关函数来取得服务器的时间或日期,以及对日期类型的数据进行各种处理,来满足程序的需求。
date_default_timezone_set()
设置时区
date_default_timezone_set('PRC')
date_default_timezone_get()
获取时区
date()
time()
取当前 Unix 时间戳(秒)
microtime()
取当前 Unix 时间戳(微秒)
strtotime()
DateTime()
DateInterval()
数学函数
ceil()
向上取整
floor()
向下取整
max()
取最大值
min()
取最小值
round()
四舍五入
mt_rand()
取随机数
mt_rand(min, max)
文件操作
https://www.bilibili.com/video/BV1A4411M7iA?p=71
disk_total_space()
获取磁盘总大小,返回单位为字节
disk_free_space()
获取磁盘可用空间大小,返回单位为字节
fopen()
打开文件
fread()
读取文件
案例
生成随机验证码
function code( int $len = 5 ) : string {
$str = '0123456789abcdefghjkmnpqrstuvwxyz';
$code = '';
for( $i = 0; $i < $len; $i++ ) {
$index = mt_rand( 0, strlen( $str ) - 1 );
$code .= strtoupper($str[$index]);
}
return $code;
}
echo code();
参考链接
PHP 官方中文手册
https://www.php.net/manual/zh/index.php
Bilibili 视频教程(推荐)
https://www.bilibili.com/video/BV1A4411M7iA
Bilibili 视频教程(上):
https://www.bilibili.com/video/BV1ct411S7nj?spm_id_from=333.999.0.0
Bilibili 视频教程(下):
https://www.bilibili.com/video/BV1mt411q789?spm_id_from=333.999.0.0