一、PHP语法初步

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

(1)PHP代码标记

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


【基本弃用】

ASP标记:

1
<% php代码 %>

短标记:

1
<? php代码 ?>

脚本标记:

1
2
3
4
5
6
7
8
9
10
11
12
<script language="php"> php代码 </script>

<html>
<body>
<b>
<script language="php">
//脚本标记
echo 'hello world';
</script>
</b>
</body>
</html>

【最常用】标准标记:

1
2
3
4
5
6
7
8
9
10
11
12
<?php php代码 ?>

<html>
<body>
<b>
<?php
//脚本标记
echo 'hello world;
?>
</b>
</body>
</html>

(2)PHP注释

1.行注释

一次注释一行

1
2
//注释内容
#注释内容

2.块注释

一次注释多行

1
2
3
/*
注释内容
*/

(3)PHP语句分隔符

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

1
2
$a = 5;
echo 'hello world';

特殊说明:

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

二、变量

php是一种动态网站开发的脚本语言,动态语言特点是交互性,会有数据的传递,而php作为”中间人”,需要进行数据的传递,传递的前提就是php自己能存储(临时)数据。

(1)变量的使用

PHP中的所有变量都必须使用 $ 符号。

1.定义:在系统中增加对应的变量名字。(内存)

1
2
<?php
$var1; //定义变量

2.赋值:可以将数据赋值给变量名。

1
2
<?php
$var2 = 1; //定义同时赋值

3.可以通过变量名访问存储的数据

1
2
3
4
5
6
<?php
$var2 = 1;
echo $var2; //通过var2变量名字找到存储的内容1,然后输出

$var2 = 2; //修改变量
echo '<hr/>', $var2;

4.可以将变量从内存中删除

1
2
3
4
<?php
//删除变量,使用unset(变量名)
$var2 = 1;
unset($var2);

(2)变量命名规则

  1. 在PHP中变量名字必须以 “$” 符号开始。
  2. 名字由字母,数字和下划线构成,但不能以数字开头。
  3. PHP本身中允许中文变量。【不推荐】

(3)预定义变量

提前定义的变量,系统定义的变量,存储许多需要用到的数据。

这些预定义变量都是数组。

1
2
3
4
5
6
7
8
9
$_GET;			//获取所有表单以GET方式提交的数据
$_POST; //POST提交的数据都会保存在此
$_REQUEST; //GET和POST提交的数据都会保存在此
$GLOBALS; //PHP中所有的全局变量
$_SERVER; //服务器信息
$_SESSION; //session会话数据
$_COOKIE; //cookie会话数据
$_ENV; //环境信息
$_FILES; //用户上传的文件信息

(4)可变变量

如果一个变量保存的值,刚好的是另外一个变量的名字,那么可以直接通过访问一个变量得到另外一个变量的值。

语法:在变量前面再多加一个 $ 符号。

1
2
3
4
5
6
<?php
//定义两个变量
$a = 'b';
$b = 'bb';

echo $$a; //输出'bb'

过程:

1.找到 $a ,解析结果:’b’

2.将前面的 $ 与结果 ‘b’ 绑定,得到:$b

3.解析 $b

(5)变量传值

将一个变量赋值给另外一个变量。

1.值传递

将变量保存的值复制一份,然后将新的值给另外一个变量保存。【两个变量没有关系】

1
2
3
4
5
6
<?php
$a = 1;
$b = $a; //值传递

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

2.引用传递

将变量保存的值所在的内存地址,传递给另外一个变量,两个变量指向同一块内存空间。【两个变量是同一个值】

1
2
3
4
5
6
<?php
$a = 1;
$b = &$a; //引用传递

$b = 2;
echo $a,$b; //2,2
1
2
3
4
5
在内存中,通常有以下几个分区:
栈区:程序可以操作的内存部分,不存储数据,运行程序代码,小但快速。
代码段:存储程序的内存部分,存储但不执行。
数据段:存储普通数据,包括全局区和静态区。
堆区:存储复杂数据的部分,大但效率低。

三、常量

(1)基本概念

常量:const/constant,是一种在程序运行当中,不可改变的量(数据)。

常量一旦定义,通常数据不可改变(用户级别)。

(2)常量定义形式

1.使用定义常量的函数:define(‘常量名’, 常量值)

1
2
<?php
define('PI', 3.14);

define()函数定义的常量默认不区分大小写,可以改变函数参数以区分大小写。

2.const 常量名 = 值; 【此方法php5.3之后出现】

1
2
<?php
const PI = 3.14;

3. define() 和 const 两种方式定义的常量,有访问权限上的区别。

(3)常量命名规则

  1. 常量不需要使用特殊符号 “$”。
  2. 常量的名字由字母、数字和下划线组成,不能以数字开头。
  3. 常量名字通常以大写字母为主(与变量区别)。
  4. 常量命名规则比变量松散,可以使用一些特殊字符。【这种常量只能用define()定义】拥有特殊字符的常量需要用函数 constant(‘常量名’) 来访问。

(4)系统常量

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

1
2
3
PHP_VERSION:PHP版本号
PHP_INT_SIZE:整型所占用的字节数
PHP_INT_MAX:整型能表示的最大值

系统魔术常量:双下划线+常量名+双下划线,魔术常量的值会跟随环境变化,但用户不能改变。

1
2
3
4
5
6
__DIR__			:当前被执行的脚本所在电脑的绝对路径
__FILE__ :当前被执行的脚本所在电脑的绝对路径,包括自己文件的名字
__LINE__ :当前所属的行数
__NAMESPACE__ :当前所属的命名空间
__CLASS__ :当前所属的类
__METHOD__ :当前所属的方法

四、数据类型

因为php是一种弱类型语言,php变量本身没有数据类型,数据类型data type在php中指的是存储的数据本身的类型。

(1)php中的八种数据类型

三大类:

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

整型:int/integer,4字节,表示整数类型。

浮点型:float/double,8字节,表示小数或整型存不下的整数。

字符串型:string,系统根据实际长度分配空间,表示字符串(引号)。

布尔类型:bool/boolean,表示布尔类型,只有两个值:true和false。

2.复合数据类型:2小类

对象类型:object,存放对象(OO)。

数组类型:array,存储多个数据(一次性)。

3.特殊数据类型:2小类

资源类型:resouce,存放资源数据(php外部数据,如数据库、文件)。

空类型:NULL,只有一个值NULL,不能运算。

(2)类型转换

在很多情况下,需要将外部数据(当前php取得的数据)转换成目标数据类型。

1.自动转换:系统根据需求自己判定,自己转换。使用多,效率偏低。

2.强制转换:人为根据需要的目标类型转换。

1
(目标类型)$变量

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

其他类型转bool:true和false。

其他类型转数值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
1.bool转数值:true为1,false为0。
2.字符串转数值:
2.1 以字母开头的字符串,永远为0。
2.2 以数字开头的字符串,取碰到字符串为止的数字,不会同时包含两个小数点。
*/

<?php
//创建数据
$a = 'abc1.1.1';
$b = '1.1.1abc';
//自动转换 1.1
echo $a + $b;
//强制转换 0 1.1
echo '<br/>',(float)$a,(float)$b;

(3)类型判断

1.is_数据类型($变量名)

通过一组类型判断函数,来判断变量,最终返回这个变量所保存数据的数据类型与函数类型是否相同,相同返回 true ,不同返回 false 。

是一组以 is_ 开头,后面跟类型名字的函数:

1
is_数据类型($变量名)

Bool类型不能用echo来查看,可以使用 var_dump(变量1, 变量2, …) 来查看。

1
2
3
4
5
6
7
<?php
//创建数据
$a = 'abc1.1.1';
$b = '1.1.1abc';

var_dump(is_int($a)); //bool(false)
var_dump(is_string($a)); //bool(true)

2.gettype($变量名)

用来获取数据(变量)的类型。

获取类型,得到的是该类型对应的字符串。

3.bool settype($变量名, 类型)

用来设定数据(变量)的类型。

设定数据类型,与强制转换不同, settype() 会直接改变存储的数据本身。

返回值bool为设定类型是否成功。

(4)整数、浮点、布尔

1.整数类型

保存整数数值(范围限制),4Bytes存储数据,最大32bits。

php中整型默认为有符号类型。

定义方式:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
#十进制定义
$a1 = 120;

#二进制定义 0b+二进制数值
$a2 = 0b110;

#八进制定义 0+八进制数值
$a8 = 0120;

#十六进制定义 0x+十六进制数值
$a16 = 0x120;

2.浮点类型

浮点型:小数类型以及超过整型存储范围的整数(不保证精度)。

精度范围:大概在15个有效数字左右。

定义方式:

1
2
3
4
<?php
$f1 = 1.23;
$f2 = 1.23e10; //科学计数法
$f3 = PHP_INT_MAX + 1 //整型超过自身存储大小后会变为浮点型存储

浮点数保存的数据不够精确,尽量不用浮点数进行精确判断。

1
2
3
4
5
<?php
$f4 = 0.7;
$f5 = 2.1;
$f6 = $f5 / 3;
var_dump($f4 == $f6); //bool(false)

3.布尔类型

两个值:true 和 false。

通常用于判断比较。

empty():判断数据的值是否为”空”(不是NULL),如果为”空”返回 true 。

isset():判断数据的值是否存在,存在返回 true 。

五、运算符

operator

(1)赋值运算符

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

(2)算术运算符

算术运算:基本的算术操作。

1
2
3
4
5
+:加
-:减
*:乘
/:除
%:取余(模运算)

(3)比较运算符

比较运算:比较两个数据的大小或是否相同。

1
2
3
4
5
6
7
8
>:大于
>=:大于等于
<:小于
<=:小于等于
==:等于(大小相同)
!=:不等于(大小不同)
===:全等于(大小以及数据类型完全相同)
!==:不全等于(大小或类型不同)

等于和全等例子:

1
2
3
4
5
6
<?php
$a = '123';
$b = 123;

var_dump($a == $b); //bool(true)
Var_dump($a === $b); //bool(false)

(4)逻辑运算符

逻辑运算:针对不同的结果进行匹配。

1
2
3
&&:逻辑与,两边条件同时成立返回 true 
||:逻辑或,两边条件只要有一个成立返回 true
!:逻辑非,对已有条件取反。

&& 和 || 又称为短路运算,如果第一个表达式结果已经可以得出返回值,那么就不会运行逻辑运算符后面的表达式。

(5)连接运算符

连接运算:php中将多个字符串拼接的一种符号。

1
2
.:将两个字符串连接到一起
.=:符合运算,将左面的内容与右边的内容连接起来,然后重新赋值给左边变量。

(6)错误抑制符

php中有一些错误可以提前预知,但可能无法避免,这时可以使用错误抑制符处理。

1
@:在可能出错的表达式前面使用@符号

例子:

1
2
3
4
<?php
$a = 10;
$b = 0;
@($a % $b); //不会报错

错误抑制符通常在生产环境(上线)用到,在开发时不会使用。

(7)三目运算符

三目运算符:有三个表达式参与的运算,是简单的分支结构的缩写。

1
表达式1 ? 表达式2 : 表达式3;

如果表达式1成立,那么执行表达式2,否则执行表达式3。

(8)自操作运算符

自操作:自己操作自己的运算符。

1
2
++:在原值上加1
--:在原值上-1

(9)位运算符

位运算:取出计算机中最小的单位(bit)进行运算。

1
2
3
4
5
6
$:按位与,两个位都为1,结果位1,否则为0
|:按位或,两个有一个为1,结果为1
~:按位非,如果为1,则变成0,否则反之
^:按位异或,两个相同则为0,不同则为1
<<:按位左移,整个二进制数向左移动一定位数,右边补0,相当于乘以2操作
>>:按位右移,整个二进制数向右移动一定位数,左边补符号位对应值(正数补0,负数补1),相当于除以2操作

注意:

1.系统进行任何位运算时,使用的都是补码

2.运算结束后都必须转换成原码才是最终要显示的数据

六、流程控制

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

(1)控制分类

顺序结构:代码从上向下顺序执行,代码执行的最基本结构

分支结构:给定一个条件,同时有多种可执行代码(块),然后会根据条件执行某一段代码

循环结构:在某个条件控制范围内,指定的代码(块)可以重复执行

(2)分支结构

1.if分支

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
//最简if
if(条件表达式)
{
//满足条件所要执行的代码
}

//基础if
if(条件表达式)
{
//满足条件所要执行的代码
}else{
//不满足条件所要执行的代码
}

//复杂if
if(条件表达式1)
{
//满足条件1所要执行的代码
}elseif(条件表达式2){
//满足条件2所要执行的代码
}elseif(条件表达式...){ //可以使用多个elseif来进行条件筛选

}else{
//所有条件全部不满足所要执行的代码
}

2.swich分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch(条件表达式){
//所有条件判断:逐个执行
case1: //当前表达式的结果与值1相等
//要执行的代码段
break; //中断swich
case2: //当前表达式的结果与值1相等
//要执行的代码段
break; //中断swich

//...设置任意数量匹配值

default:
//匹配失败的代码
}

(3)循环结构

1.for循环

1
2
3
4
5
6
7
8
9
/*
条件表达式1:定义初始化条件
条件表达式2:边界判定,限定循环执行次数
条件表达式3:用来执行条件变化
*/
for(条件表达式1; 条件表达式2; 条件表达式3)
{
//循环体
}

2.while循环

1
2
3
4
5
6
7
/*
条件表达式判断边界条件
条件变化在循环体中实现
*/
while(条件表达式){
//循环体
}

3.do-while循环

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

4.循环控制

中断控制continue; 结束本次循环,重新开始循环.

continue n;对n层嵌套的循环同时执行结束本次循环的操作

终止控制break; 整个循环结束.

break n;对n层嵌套的循环同时执行终止整个循环的操作

5.流程控制(替代语法):

九九乘法表:

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;?0>
</td>
<?php }?>
</tr>
<?php }?>
</table>

使用 for(;;): endfor; ** 替代 **for(;;){ }

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;?0>
</td>
<?php endfor?>
</tr>
<?php endfor;?>
</table>

替代语法:

1
2
3
4
5
ifif():		endif;
switchswitch(): endswitch;
for
while
foreach

七、文件包含

文件包含四种形式:include, require, include_once, require_once

(1)文件加载原理

  1. 在文件加载(include或者require)的时候,系统会自动的将包含文件的代码相当于嵌入到当前文件中
  2. 加载位置:在哪加载,对应的文件中代码嵌入的位置就是对应的include位置
  3. 在PHP中被包含的文件是单独进行编译的

PHP文件在编译过程中如果出现了语法错误,那么会失败(不会执行);但是如果被包含的文件有错误时,系统会执行到包含include这条语句的时候才会报错。

(2)include和include_once的区别:

include :系统碰到一次,执行一次,如果对同一个文件进行多次加载,那么系统会执行多次;

include_once :系统碰到多次,也只会执行一次。

(3)require和include的区别

本质都是包含文件,唯一的区别在于包含不到文件的时候,报错的形式不一样。

include的错误级别较轻(Warning),不会阻止代码执行。

require的错误级别较高(Fatal Error),如果包含出错,require后面的代码不会执行。

(4)文件加载路径

文件在加载的时候需要指定文件路径才能保证PHP正确的找到对应的文件。

1.绝对路径

本地绝对路径:从磁盘的根目录开始

​ Windows:盘符c:/路径/PHP文件

网络绝对路径:从网站根目录开始

​ / : 相对于网站主机名字对应的路径

​ localhost/index.php —> D:/Server/Apache24/htdocs/PHPBasic/index.php

2.相对路径

从当前文件所在目录开始的路径

../. 表示当前文件夹

../ :上级目录(当前文件夹的上一层文件夹)

3.绝对路径与相对路径的加载区别

绝对路径相对效率偏低,但是相对安全(路径不会出问题)。

相对路径相对效率高些,但是容易出错(相对路径会发生改变)。

(5)文件嵌套包含

文件嵌套包含:一个文件包含另一个文件,同时被包含的文件又包含了另外一个文件。

嵌套包含时容易出现相对路径错误,相对路径( ./../ )会因为文件的包含而改变。

八、函数

function:一种语法结构,将实现某一个功能的代码块(多行代码)封装到一个结构中,从而实现代码的重复利用

(1)函数语法

1.函数的定义:

1
2
3
4
function 函数名(参数1,...){
//函数体
return 结果; //返回值
}

2.函数的调用:函数的调用可以在函数定义之前

1
函数名(参数1,...);

3.命名规范:

​ 由字母、数字和下划线组成,但不能以数字开头。

​ 在一个脚本周期中,不允许出现同名函数。(通常在一个系统开发中都不会使用同名函数)

(2)参数详解

1.实参与形参

1.形参:形式参数,不具有实际意义,在函数定义时使用的参数

2.实参:实际参数,具有实际数据的参数,实在函数调用时使用的参数,形参是实参的载体

注意:

1.php中允许实参个数多于形参,但不能少于形参。

2.理论上形参个数没有限制。

2.参数默认值:

default value,指的是形参的默认值,在函数定义的时候,就给形参进行一个初始赋值。如果没有提供实际调用传入的参数(实参),那么形参就会使用定义时的值来进入函数内部参与运算。

1
2
3
function add($num1 = 0, $num2 = 0){
echo $num1 + $num2;
}

注意:

默认值的定义是放在最后面的参数上的,不能左边的形参有默认值而右边的形参没有默认值。

3.值传递与引用传递

值传递:将实参(变量或其他表达式)的结果(值)取出来赋值给形参,形参与外部实际传入的参数本身没有任何关联。

引用传递:在函数定义时,说明希望能够在函数内部改变函数外部的数据,这样函数调用时会主动获取外部数据的内存地址,直接操作外部数据。

1
2
3
function 函数名($值传递形参名, &$引用传递形参名){
//函数体
}

注意:函数调用时,引用传递的形参必须传入变量实参。

(3)函数体

函数体:函数内部(大括号里面)的所有代码。

(4)函数返回值

php中所有的函数都有返回值,默认返回值为NULL。

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

return关键字:

1.return在函数内部使用:返回当前函数的结果,当前函数运行结束,return后的代码不会被执行。

2.return在文件中直接使用(不在函数里面):文件将return后面的内容(代码语句),转交给包含当前文件的位置,同时终止return后面的代码(return之后的内容不会执行),通常在系统配置文件中使用较多。

(5)作用域

作用域:变量(常量)能够被访问的区域。

1.变量可以在普通代码中定义

2.变量也可以在函数内部定义

在php中,作用域(严格来说)分为两种,但php内部还定义了一种严格意义之外的作用域:

1.全局变量:用户普通定义的变量

​ 所属全局空间,在php中只允许在全局空间使用,理论上在函数内部不可访问。

脚本周期:直到脚本运行结束,最后一行代码执行完。

2.局部变量:在函数内部定义的变量

​ 所属当前函数空间,在php中只允许当前函数自己使用。

函数周期:函数执行结束,函数在栈区中开辟独立内存空间运行。

3.超全局变量:系统定义的变量(如预定义变量$_SERVER等)

​ 所属超全局空间,没有访问限制,函数内外都可以访问。

​ 超全局变量会将全局变量自动纳入到$GLOBALS数组里面,而$GLOBALS没有作用域限制,所以能够帮助在局部空间中访问全局变量:但是必须使用数组方式。

1
2
3
4
5
6
$global = 'global area';		//最终会被系统纳入到超全局变量中,$GLOBALS['global'] = 'global area'

function display(){
var_dunp($GLOBALS); //查看数组内容
echo $GLOBALS['global']; //用下标global访问数组内容
}

在php中,还有一种实现变量跨域访问的方式:global关键字

global关键字:是一种在函数里面定义变量的一种方式

1.如果使用global定义的变量名在外部存在(全局变量中已经存在),那么在函数内部定义的变量将指向外部已经定义的全局变量所指向的内存空间(同一个变量)。

2.如果使用global定义的变量名在外部不存在,系统会自动在全局空间定义一个与此变量同名的全局变量。

本质的形式:在函数的内部和外部,对一个同名变量使用同一块内存地址保存数据。

1
2
global 变量名;				//定义时不能赋值
变量名 = 值;

使用global关键字跨域访问:

1
2
3
4
5
6
7
8
9
10
11
12
13
$global = 'global area';

function display1(){
global $global; //对于全局空间存在的变量
echo $global; //打印 global area
}

function display2(){
global $local; //对于全局空间不存在的变量
$local = 'inner';
}

echo $local; //打印 inner

(6)静态变量

静态变量:使用static关键字,用来实现跨函数共享数据的变量,即同一个函数被多次调用时,共享同一个变量同一个数据。

1
2
3
function 函数名(){
static $变量名 = 变量值
}

例子:

1
2
3
4
5
6
7
8
9
function display(){
$local = 1; //局部变量
static $count = 1; //静态变量
echo $local++, ' ', $count++, '<br/>';
}

display(); //1 1
display(); //1 2
display(); //1 3

原理:系统在编译php文件的时候,就会对static变量进行初始化,函数在调用的时候,static变量定义的过程会被跳过。

静态变量的使用:

1.统计当前函数被调用的次数

2.统计函数被多次调用得到的不同结果(递归思想)

(7)可变函数

可变函数:当前有一个变量所保存的值,刚好是一个函数的名字,那么就可以使用 变量+() 来充当函数名使用。

1
2
3
4
5
$func = 'display';
function display(){

}
$func(); //等同于 display();

可变函数的使用:系统函数需要用户在外部定义定义一个自定义函数,但是需要传入到系统函数内部使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
//定义系统函数(假设)
function sys_function($arg1, $arg2){
//给指定的函数(第一个参数),求对应第二个参数值的四次方
//为实际用户输入的数值进行处理
$arg2 = $arg2 + 10;
return $arg1($arg2);
}
//定义一个用户函数:求一个数的四次方
function user_function($num){
return $num * $num * $num * $num;
}
//求10+10的4次方
echo sys_function('user_function', 10);

(8)匿名函数

匿名函数:没有名字的函数

定义与调用:

1
2
3
4
5
$变量名 = function(){
//函数体
};
//调用匿名函数
$变量名();

变量保存匿名函数,本质上得到的是一个对象(Closure类)。

闭包:closure,函数内部有一些局部变量(要执行的代码块)在函数执行之后没有被释放,是因为在函数内部还有对应的函数在引用这些局部变量(函数内部的函数:匿名函数)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//闭包函数
function display(){
//定义变量:局部变量
$name = __FUNCTION__;

//定义匿名函数
//use就是将外部变量(局部变量)保留给内部使用(闭包)
$innerfunc = function() use($name){
//函数内部的函数
//匿名函数调用了局部变量$name
echo $name;
};

//返回内部匿名函数
return $innerfunc;
}

$closure = display();
//display()函数运行结束,但局部变量$name没有被释放,从而在外部调用内部匿名函数的时候可以被使用
$closure();

(9)伪类型

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

伪类型主要有两种(在八小类类型之外):

1.mixed:混合的,可以是多种php中的数据类型

2.number:数值的,可以是任意数值类型(整型和浮点型)

(10)常用系统函数

3.常用数学函数

1
2
3
4
5
6
7
8
9
10
max():指定参数中的最大值
min():指定参数中的最小值
rand():得到一个指定区间的随机整数
mt_rand():与rand一样,只是底层结构不一样,效率比rand高
round():四舍五入
cell():向上取整
floor():向下取整
pow():幂运算
abs():绝对值
sqrt():平方根

4.有关函数的函数

1
2
3
4
function_exist():判断指定的函数名字是否在内存中存在
func_get_arg():在自定义函数中获取指定index对应的参数
func_get_args():在自定义函数中获取所有的参数(数组)
func_num_args():在自定义函数中获取函数的参数数量

注意:func_get_args()和func_num_args()统计的都是实参而非形参

九、错误处理

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

(1)错误分类

1.语法错误:用户书写的代码不符合php语法规范,语法错误会导致代码在编译过程中不通过,所以代码不会执行(parse error)。

2.运行时错误:代码编译通过,但是代码在执行过程中会出现一些条件不满足导致的错误(runtime error)。

3.逻辑错误:程序员在写代码的时候不够规范,出现了一些逻辑性的错误,导致代码正常执行,但是得不到想要的结果。

(2)错误代号

所有看到的错误代号在php中都被定义成了系统常量(可以直接使用)。

所有以 E 开头的错误常量(代号)其实都是由一个字节存储,然后每一种错误占据一个对应的位,错误控制因此可以使用位运算。

1.系统错误

1
2
3
4
E_PARSE:编译错误,代码不会执行
E_ERROR:fatal error,致命错误,会导致代码不能正确继续执行(出错的位置断掉)。
E_WARNING:warning,警告错误,不会影响代码执行,但是可能得到意想不到的结果。
E_NOTICE:notice,通知错误,不会影响代码执行。

2.用户错误

用户在使用自定义错误触发的时候,会使用到的错误代号(系统不会用到)。

1
2
3
E_USER_ERROR
E_USER_WARNING
E_USER_NOTICE

3.其他

1
E_ALL:代表着所有的错误(通常在进行错误控制时候使用),建议在开发过程中(开发环境)使用。

排除通知错误:

1
E_ALL & ~E_NOTICE

(3)错误触发

1.程序运行时触发

系统自动根据错误发生后,对比对应的错误信息,输出给用户。

主要针对代码的语法错误和运行时错误。

2.人为触发

知道某些逻辑可能会出错,从而使用对应的判断代码来触发相应的错误提示。Trigger_error(错误提示);

1
2
3
4
5
6
7
8
9
10
11
12
<?php

//处理脚本,让浏览器按照指定字符集解析
header('Content-type:text/html;charset=utf-8');

$a = 100;
$b = 0;
if($b == 0){
trigger_error('除数不能为0'); //默认notice错误,代码会继续执行
trigger_error('除数不能为0', E_USER_ERROR); //设置为error,代码终止执行
}
echo $a / $b;

(4)错误设置

1.错误显示设置

哪些错误该显示,以及该如何显示。

php中,有两种方式来设置当前脚本的错误处理:

​ a.php的配置文件:全局配置 php.ini 文件

1
2
error_reporting:显示什么级别的错误
display_errors:是否显示错误

​ b.在运行的php脚本中设置:在脚本中定义的配置项函数级别比配置文件高

1
2
int error_reporting([int $level]):设置对应的错误显示级别
ini_set('配置文件中的配置项', 配置值):ini_set('error_reporting', E_ALL);

2.错误日志设置

在实际生产环境中,不会直接将错误展示给用户(不友好、不安全),一般不显示错误,而是将错误保存到日志文件中。

​ a.在php配置文件中或者代码中,设置log_errors配置项,来开启日志功能。

​ b.在php配置文件中或者代码中,设置error_log配置项来指定日志文件路径。

(5)自定义错误处理

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

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

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
38
39
40
<?php
//处理脚本,让浏览器按照指定字符集解析
header('Content-type:text/html;charset=utf-8');

//自定义函数
function my_error($errno, $errstr, $errfile, $errline){
//判断当前会碰到的错误有哪些
//error_reporting()获取当前系统错误处理对应的级别
if(!(error_reporting() & $errno)){
return false;
}
//开始判断错误类型
switch($errno){
case E_ERROR;
case E_USER_ERROR;
echo 'fatal 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;

十、字符串类型

(1)字符串定义语法


引号方式定义


1.单引号字符串

1
$str1 = 'hello';

2.双引号字符串

1
$str2 = "hello";

引号方式:比较适合定义比较短、没有结构要求的字符串

双引号区别于单引号,能识别变量(用此方法识别变量需要保证变量独立性,如:使用变量标识符 {$a} )和更多的转义字符。


结构化方式定义


3.nowdoc字符串:没有单引号的单引号字符串

语法:

1
2
3
$变量名 = <<<'边界符'
字符串内容
边界符;

例子:

1
2
3
4
$str3 = <<<'EOD'
hello
world
EOD;

4.heredoc字符串:没有双引号的双引号字符串

语法:

1
2
3
$变量名 = <<<边界符
字符串内容
边界符;

例子:

1
2
3
4
$str4 = <<<EOD
hello
world
EOD;

(2)字符串转义

转义:在计算机统用协议中,有一些特定的方式定义的字母,系统会特定处理,通常使用反斜杠+字母的特性

\r\n:回车换行

php中常用的转义符号:

1
2
3
4
5
6
7
8
9
10
\':在单引号字符串中显示单引号
\":在双引号字符串中显示双引号
\r:回车(理论上回到当前行的首位置)
\n:代表新一行
\t:类似Tab键,输出4个空格
\$:在php中,$为变量符号,需要在字符串中特殊识别

以上
单引号字符串只能够识别:\'
双引号字符串只不能识别:\'

(3)字符串长度

1.基本函数 strlen():得到字符串的长度,以字节为单位

​ 注意:每个汉字在utf-8字符集下占3个字节

2.多字节字符串扩展模块:mbstring 扩展(mb为Multi Bytes)

​ 加载扩展:php.ini 中 extension=php_mbstring.dll 语句取消注释

​ 使用mb扩展带来的函数:mb_strlen($字符串变量, ‘字符集’)

​ 在 utf-8 字符集中,mb_strlen()对汉字求长度,一个汉字+1

(4)字符串相关函数

1.转换函数

1
2
3
implode():将数组中的元素按照某个规则连接成一个字符串
explode():将字符串按照某种格式进行分割,变成数组
str_split():按照指定长度拆分字符串返回数组

2.截取函数

1
2
3
4
5
trim():默认用来去除字符串首尾的空格,也可以指定要去除的首尾的内容
ltrim():去除字符串首内容
rtrim():去除字符串尾内容
substr():指定位置索引位置开始截取字符串,可以指定长度,不指定长度就截取到字符串尾
strstr():从指定字符串位置开始截取字符串到最后

3.大小写转换

1
2
3
strtolower():全部小写
strtoupper():全部大写
ucfirst():首字母大写

4.查找函数

1
2
strpos():判断字符在目标字符串中首次出现的位置,用===判断是否出现
strrpos():判断字符在目标字符串中最后出现的位置

5.替换函数

1
2
str_replace():将目标字符串中部分字符串进行替换
str_replace('匹配目标', '替换内容', 字符串)

6.格式化函数

1
printf()/sprintf()

7.其他函数

1
2
str_repeat():重复某个字符串N次
str_shuffle():随机打乱字符串(验证码)

十一、数组 array

(1)数组定义语法

1.使用 array 关键字(最常用)

1
$变量 = array(元素1, key => value , ...);

2.使用中括号来包裹数据

1
$变量 = [元素1, 元素2, ...];

3.隐形定义数组:给变量加一个中括号,系统自动变成数组

1
2
$变量[] = 值;				//默认下标为当前最大下标+1
$变量[下标] = 值;

(2)数组特点

1.可以使用整数下标或者字符串下标

​ 索引数组:数组下标都为整数

​ 关联数组:数组下标都为字符串

​ 混合数组:整数下标和字符串下标混合存在

2.数组元素的顺序以放入顺序为准,与下标无关

3.特殊值下标的自动转换

​ 布尔值:true –> 1 , false –> 0

​ 空:NULL –> “”

(3)多维数组

数组里面的元素又是数组

1.二维数组:数组中所有的元素都是一维数组

1
2
3
4
5
6
7
$info = array(
array('name' => 'Jim', 'age' => 30),
array('name' => 'Tom', 'age' => 28),
array('name' => 'Lily', 'age' => 20)
);
echo '<pre>';
print_r($info);

2.多维数组

二维数组的数组元素中可以继续是数组,php中没有维度限制(本质上没有二维数组的定义),不建议使用三维以上的数组,会再增加访问的复杂度,降低访问效率

3.异形数组(不规则数组)

数组中的元素不规则,有数组也有普通基本变量

在实际开发中并不常用,尽量让数组元素规则化,便于访问

(4)数组遍历

1.foreach 遍历

1
2
3
4
foreach($数组变量 as [$下标 =>] $值){
//通过$下标访问元素的下标
//通过$值来访问元素的值
}

如果是关联数组一般需要下标,如果是索引数组一般不需要下标。

例子:

1
2
3
4
5
6
7
8
9
$arr = array(1,2,3,4,5,6,7,8,9,10);

foreach($arr as $v){
echo $v , '<br/>';
}

foreach($arr as $k => $v){
echo 'key:',$k,'==value: ',$v,'<br/>';
}

foreach 遍历原理:

数组内部有一个指针,默认指向数组的第一个元素,foreach利用指针去获取数据,同时移动指针。

1.foreach重置指针,让指针指向第一个元素

2.进入foreach循环,通过指针取得当前第一个元素,将下标和值取出,放入对应的下标变量和值变量中

3.指针下移(+1)

4.进入循环体,执行代码

5.重复2 3 4,直到在第二步中指针取不到内容(指针指向数组最后)

2.for 循环遍历

使用条件:

1.已知边界条件(起始、结束)

2.已知数组长度, count() 函数

3.要求数组元素下标是有条件(规律)的变化

1
2
3
4
5
$arr = array(1,2,3,4,5,6,7,8,9,10);
for($i = 0, $len = count($arr);$i < $len; $i++)
{
echo 'key:',$i,'==value: ',$arr[$i],'<br/>';
}

3.while配合each和list遍历数组

each函数

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

​ 0下标 => 取得元素的下标值

​ 1 下标 => 取得的元素

​ key下标 => 取得元素的下标

​ value下标 => 取得元素的值,

如果each取不到元素,返回false

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
38
39
$arr = array(1,'name'=> 'Tom',3,'age'=>30);
echo '<pre>';
print_r(each($arr));
print_r(each($arr));
print_r(each($arr));
print_r(each($arr));
var_dump(each($arr));

/*结果:
Array
(
[1] => 1
[value] => 1
[0] => 0
[key] => 0
)
Array
(
[1] => Tom
[value] => Tom
[0] => name
[key] => name
)
Array
(
[1] => 3
[value] => 3
[0] => 1
[key] => 1
)
Array
(
[1] => 30
[value] => 30
[0] => age
[key] => age
)
bool(false)
*/

list结构

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

条件:list必须从索引数组中获取数据

1
2
3
$arr = array(3,2 =>1);
list($first) = $arr;
var_dump($first); //int(3)

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

1
2
3
4
5
6
7
8
9
10
11
    $arr = array(3,2 =>1);
list($firs, $second) = $arr;
var_dump($first, $second);

/*
Notice: Undefined offset: 1 in --\arr.php on line --
int(3) NULL
$arr[1]不存在,$arr[2] == 1,
$second变量对应下标为1的元素,
list找不到下标为1的元素,故出错
*/

list与each配合:each一定有两个元素就是0下标和1下标元素

1
2
3
4
5
6
7
8
9
10
11
12
$arr = array(1,'name'=> 'Tom',3,'age'=>30);

while(list($key,$value) = each($arr)){
echo 'key:', $key , '==value: ', $value , '<br/>';
}

/*
key:0==value: 1
key:name==value: Tom
key:1==value: 3
key:age==value: 30
*/

(5)数组相关函数

1.排序函数

都是按照ASCII码进行比较

1
2
3
4
5
6
7
sort():顺序按元素值排序,从低到高,下标重排
rsort():逆序
asort():顺序按元素值排序,下标对应关系保留
arsort()
ksort():顺序按键名(下标)排序,下标对应关系保留
krsort()
shuffle():随机打乱数组元素,下标重排

以上函数返回值均为bool类型,执行后直接修改源数组

2.指针函数

1
2
3
4
5
6
reset():重置指针,将数组指针回到首位,返回元素值
end():重置指针,将数组指针指到最后一个元素,返回元素值
next():将数组中的内部指针+1,返回下一个元素的值
prev():将数组中的内部指针-1,返回上一个元素的值
current():获取当前指针对应的元素值
key():获取当前指针对应的键名(下标)

注意:如果使用next()或prev()导致指针移出数组,将无法再次使用next()和prev()使指针回到正确的位置,此时只能通过reset()或end()重置指针。

3.其他函数

1
2
3
4
5
6
7
8
9
10
11
12
count():统计数组中元素的数量

array_push():在数组尾部加入一个元素
array_pop():从数组尾部取出一个元素
array_unshift():在数组开头加入一个元素
array_shift():从数组开头取出一个元素

array_reverse():将数组元素顺序翻转
in_array():判断一个元素在数组中是否存在

array_keys():获取一个数组的所有下标,返回一个索引数组
array_values():获取一个数组的所有值,返回一个索引数组