【PHP】PHP常见语法
PHP简介
PHP定义:一种服务器端的 HTML 脚本/编程语言,是一种简单的、面向对象的、解释型的、健壮的、安全的、性能非常之高的、独立于架构的、可移植的、动态的脚本语言。是一种广泛用于 Open Source(开放源代码)的尤其适合 Web 开发并可以嵌入 HTML 的多用途脚本语言。它的语法接近 C,Java 和 Perl,而且容易学习。该语言让 Web 开发人员快速的书写动态生成的网页。
前置知识了解
静态网站的特点
1.网页内容一经发布到网站服务器上,无论是否有用户访问,每个静态网页的内容都是保存在网站服务器上的,也就是说,静态网页是实实在在保存在服务器上的文件,每个网页都是一个独立的文件;
2.静态网页的内容相对稳定,因此容易被搜索引擎检索;
3.静态网页没有数据库的支持,在网站制作和维护方面工作量较大,因此当网站信息量很大时完全依靠静态网页制作方式比较困难;
4.静态网页的交互性较差,在功能方面有较大的限制。
动态网站特点
1.交互性:网页会根据用户的要求和选择而动态地改变和响应,浏览器作为客户端,成为一个动态交流的桥梁,动态网页的交互性也是今后Web发展的潮流。
2.自动更新:即无须手动更新HTML文档,便会自动生成新页面,可以大大节省工作量。
3.因时因人而变:即当不同时间、不同用户访问同一网址时会出现不同页面。
此外动态网页是与静态网页相对应的,也就是说,网页URL的后缀不是.htm、.html、.shtml、.xml等静态网页的常见形式,而是以.asp、.jsp、.php、.perl、.cgi等形式为后缀。在动态网页网址中有一个标志性的符号——“?”
PHP基础语法
首先:PHP是一种运行在服务器端的脚本语言,可以嵌入到HTML中
为了防止显示中文出现乱码,建议加上下面的这句话
//处理脚本让浏览器按照指定字符集解析的方法
header('Content-type:text/html;charset=utf-8');
代码标记
在PHP历史发展中,可以使用多种标记来区分PHP脚本
- ASP标记:<% php代码 %>
- 短标记:<? Php代码 ?>
以上两种基本弃用,更加常用的标志是:<?php php代码?>
注释
PHP中注释分为两种:行注释和块注释
- 行注释:一次注释一行 。写法1:
#
写法2://
- 块注释:一次注释多行
/* 中间直到*/出现之前,全部都是注释 */
语句分隔(结束)符
在PHP中,代码是以行为单位,系统需要通过判断行的结束,该结束通常都是一个符号分号;
特殊说明:
1.PHP中标记结束符?>有自带语句结束符的效果,最后一行PHP代码可以没有语句结束符
<?php
echo "hello I am Mango ! PHP yyds!";
echo "我可以没有分号"
?>
2.PHP中其实很多代码的书写并不是嵌入到HTML中,而是单独存在,通常书写习惯中就不建议使用标记结束符?>,PHP会自动从开始到最后全部认为是PHP代码,从而解析
<?php
echo "hello I am Mango ! PHP yyds!";
echo "hello world";
变量
变量的基本概念
变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。变量可以通过变量名访问。在指令式语言中,变量通常是可变的
1.变量是用来存储数据的
2.变量是存在名字的
3.变量是通过名字来访问的(数据)
4.变量是可以改变的(数据)
变量的使用
PHP中的所有变量都必须使用“$”符号
1.定义:在系统中增加对应的变量名字(内存)
2.赋值:可以将数据赋值给变量名(可以在定义的同时完成)
3.可以通过变量名访问存储的数据
4.可以将变量从内存中删除
变量命名规则
1.在PHP中变量名字必须以“$”符号开始;
2.名字由字母、数字和下划线“_”构成,但是不能以数字开头;
3.在PHP中本身还允许中文变量(不建议)
$1var;//err
$中国 = 'China'; #中文变量 ok
预定义变量
预定义变量:提前定义的变量,系统定义的变量,存储许多需要用到的数据(预定义变量本质是数组)
- $_GET:获取所有表单以get方式提交的数据
- $_POST:POST提交的数据都会保存在此
- $_REQUEST:GET和POST提交的都会保存
- $GLOBALS:PHP中所有的全局变量
- $_SERVER:服务器信息
- $_SESSION:session会话数据
- $_COOKIE:cookie会话数据
例子:
可变变量
可变变量:如果一个变量保存的值刚好是另外一个变量的名字,那么可以直接通过访问一个变量得到另外一个变量的值:在变量前面再多加一个$符号
$a = 'b';
$b = 'I am b';
echo $$a; # $$a == > $b ==> 'I am b'
- 1.先找到$a,解析出结果为b
- 2.将前面的$符号和b进行绑定,就是$b,然后输出
变量传值
将一个变量赋值给另外一个变量:变量传值
- 变量传值一共有两种方式:值传递,引用传递
值传递:将变量保存的值赋值一份,然后将新的值给另外一个变量保存(两个变量没有关系)
例子:
<?php
$a = 1;
$b = $a; //值传递
$b = 2;
echo $a,'<hr/>',$b; //输出1,2
引用传递:将变量保存的值所在的内存地址,传递给另外一个变量:两个变量指向同一块内存空间(两个变量是同一个值)
$新变量 = &$老变量
<?php
$a = 1;
$b = &$a; //值传递
$b = 2;
echo $a,'<hr/>',$b; //输出2,2
内存分区
在内存中,通常有以下几个分区
栈区:程序可以操作的内存部分(不存数据,运行程序代码),少但是快
代码段:存储程序的内存部分(不执行)
数据段:存储普通数据(全局区和静态区)
堆区:存储复杂数据,大但是效率低
常量
基本概念
常量与变量一样,都是用来保存数据的。
常量:const/constant,是一种在程序运行当中,不可改变的量(数据)。常量一旦定义,通常数据不可改变(用户级别)
常量定义形式
在PHP中常量有两种定义方式(5.3之后才有两种)
- 1.使用定义常量的函数:define(‘常量名’,常量值);
- 2.5.3版本之后才有的:const 常量名 = 值;
define('PI',3.14);
const PII = 3.14;
命名规则
1.常量不需要使用“$”符号,一旦使用系统就会认为是变量;
2.常量的名字组成由字母、数字和下划线组成,不能以数字开头;
3.常量的名字通常是以大写字母为主(与变量以示区别);
4.常量命名的规则比变量要松散,可以使用一些特殊字符,该方式只能使用define定义;
细节:
1.define和const定义的常量是有区别:在于访问权限区别
2.定义常量通常不区分大小写,但是可以区分,可以参照define函数的第三个参数
第一个参数规定常量的名称,也叫标识符
第二个参数规定常量的值,就是一个不希望被改变的标量数据类型的数据
第三个参数是可选参数,用来规定常量名是否区分大小写
使用形式
常量的使用与变量一样:不可改变值**(在定义的时候必须赋值)**。常量不需要使用“$”符号,一旦使用系统就会认为是变量
echo PI;
echo PII;
有的时候还需要使用另外一种形式来访问(针对的是特殊名字的常量),需要用到另外一个访问常量的函数:constant(‘常量名’)
<?php
define('-_-','smile');
//echo '-_-';// 特殊符号不能直接使用
echo constant('-_-');
?>
说明:常量和变量的使用
1.凡是数据会可能变化的,那么肯定是用变量
2.数据不一定会变的,可以使用常量或者变量(变量居多)
3.数据不允许被修改的,一定用常量
系统常量
系统常量:系统帮助用户定义的常量,用户可以直接使用
常用的系统常量:
- PHP_VERSION:PHP版本号
- PHP_INT_SIZE:整形大小
- PHP_INT_MAX:整形能表示的最大值(PHP中整形是允许出现负数:带符号)
echo '<hr/>',PHP_VERSION,'<hr/>',PHP_INT_SIZE,'<hr/>',PHP_INT_MAX; #5.4.8 4 2147483647
魔术常量
在PHP中有一些特殊的常量,他们有双下划线开始+长两名+双下划线结束,这种常量称之为系统魔术常量:魔术常量的值通常会跟着环境变化,但是用户不能改变
- _DIR_:当前被执行的脚本所在电脑的绝对路径
- _FILE_:当前被执行的脚本所在的电脑的绝对路径(带自己文件的名字)
- _LINE_:当前所属的行数
- __NAMESPACE__:当前所属的命名空间
- __CLASS__:当前所属的类__
- _METHOD_:当前所属的方法
- __FUNCTION__:当前函数的名字
数据类型
数据类型:data type,在PHP中指的是存储的数据本身的类型,而不是变量的类型。**PHP是一种弱类型语言,变量本身没有数据类型。**在PHP中将数据分为三大类八小类:
简单(基本)数据类型:4个小类
整型:int/integer,系统分配4个字节存储,表示整数类型(有前提)
浮点型:float/double,系统分配8个字节存储,表示小数或者整型存不下的整数
字符串型:string,系统根据实际长度分配,表示字符串(引号)
布尔类型:bool/boolean,表示布尔类型,只有两个值:true和false
复合数据类型:2个小类
对象类型:object,存放对象(面向对象)
数组类型:array,存储多个数据(一次性)
特殊数据类型:2个小类
资源类型:resource,存放资源数据(PHP外部数据,如数据库、文件)
空类型:NULL,只有一个值就是NULL(不能运算)
类型转换
类型转换:在很多的条件下,需要指定的数据类型,需要外部数据(当前PHP取得的数据),转换成目标数据类型
在PHP中有两种类型转换方式:
1.自动转换:系统根据需求自己判定,自己转换(用的比较多,效率偏低)
2.强制(手动)转换:认为根据需要的目标类型转换
强制转换规则:在变量之前增加一个括号(),然后在里面写上对应类型:int/integer….其中NULL类型用到unset()。在转换过程中,用的比较多的就是
- 转布尔类型(判断)和转数值类型(算术运算)
- 其他类型转布尔类型:true或者false,在PHP中比较少类型换变成false
其他类型转数值的说明
1.布尔true为1,false为0;
2.字符串转数值有自己的规则
2.1 以字母开头的字符串,永远为0;
2.2 以数字开头的字符串,取到碰到字符串为止(不会同时包含两个小数点)
$a = 'abc1.1.1';
$b = '1.1.1.abc';
echo $a + $b; //自动转化 1.1
echo '<hr/>',(float)$a,'<br/>',(float)$b; #0 1.1
类型判断
通过一组类型判断函数,来判断变量,最终返回这个变量所保存数据的数据类型(相同结果为true,失败为false):是一组以is_开头后面跟类型名字的函数:is_XXX(变量名)
bool类型不能用echo来查看,可以使用var_dump结构查看
- var_dump(变量1,变量2…)
$a = 'abc1.1.1';
$b = '1.1.1.abc';
var_dump(is_int($a)); #bool(false)
var_dump(is_string($b));#bool(true)
还有一组函数可以用来获取以及设定数据(变量)的类型
-
Gettype(变量名):获取类型,得到的是该类型对应的字符串
-
Settype(变量名,类型):设定数据类型:与强制转换不同
- 1.强制转换(类型)变量名,是对数据值复制的内容进行处理(不会处理实际存储的内容)
- 2.settype会直接改变数据本身
$a = 'abc1.1.1';
$b = '1.1.1.abc';
echo gettype($a); #string
var_dump(settype($b,'int')); #bool(true) #settype设置类型成功,返回true
echo gettype($b); #integar
整数类型
整数类型:保存整数数值(范围限制),4个字节存储数据,最大就是32位:2^32 = 42亿多(无符号数)。但是在PHP中默认是有符号类型(区分正负数)
在PHP中提供了四种整型的定义方式:十进制定义,二进制定义,八进制定义和十六进制定义
$a1 = 120; //10进制
$a2 = 0b110; //2进制
$a3 = 0120; //8进制
$a4 = 0x120; //16进制
echo $a1,'<hr/>', $a2,'<hr/>', $a3,'<hr/>', $a4,'<hr/>'; #120 6 80 288
进制转换
十进制:逢10进1,能够出现的数字是0-9
二进制:逢2进1,能够出现的数字是0-1
八进制:逢8进1,能够出现的数字是0-7
十六进制:逢16进1,能够出现的数字是0-9以及a-f,a表示10,依次类推
PHP中不需要用户这么复杂的去计算,提供了很多的函数进行转换 (二进制:bin 八进制:oct 十进制:dec 十六进制:hex )
- decbin():十进制转二进制
- decoct():十进制转八进制
- dechex():十进制转十六进制
- bindec():二进制转十进制
浮点类型
浮点型:小数类型以及超过整型所能存储范围的整数(不保证精度),精度范围大概在15个有效数字左右
浮点型定义有两种方式
-
$f = 1.23;
-
$f = 1.23e10; //科学计数法,其中e表示底10
$f1 = 1.23;
$f2 = 1.23e10;
var_dump($f1,$f2); #float(1.23) float(12300000000)
尽量不用用浮点数做精确判断:浮点数保存的数据不够精确,而且在计算机中凡是小数基本上存的都不准确
$f1 = 0.7;
$f2 = 2.1 / 3;
var_dump($f1 == $f2); #bool(false)
布尔类型
布尔类型:两个值true和false,通常是用于判断比较。在进行某些数据判断的时候,需要特别注意类型转换
- empty():判断数据的值是否为“空”,不是NULL,如果为空返回true,不为空返回false
- isset():判断数据存储的变量本身是否存在,存在变量返回true,不存在返回false
$a;
var_dump(isset($a)); //bool(false)
var_dump(empty($a)); //bool(true)
$x = NULL;
var_dump(isset($x)); //bool(false)
var_dump(empty($x)); //bool(true)
运算符
运算符:operator,是一种将数据进行运算的特殊符号
赋值运算符
赋值运算:符号是“=”,表示将右边的结果(可以是变量、数据、常量和其它运算出来的结果),保存到内存的某个位置,然后将位置的内存地址赋值给左侧的变量(常量)。
算术运算符
算术运算:基本算术操作
- +:执行数据累加
- -:数据相减
- * :键盘上没有乘法符号,使用*代替,两个数相乘
- /:正斜杠代替,表示两个数相除
- %:取余(模)运算,两个数(整数)相除,保留余数
在进行除法运算或者取余运算的时候,对应的除数(第二个数)不能为0
比较运算符
比较运算:比较两个数据的大小,或者两个内容是否相同,返回的结果都是布尔类型:满足返回true,不满足返回false
- >:左边大于右边,返回结果true
- >=:左边大于等于右边
- <:左边小于右边
- <=:左边小于或者等于右边
- ==:左边的与右边的相同(大小相同)
- !=:左边的与右边的不同(大小不同)
- ===:全等于,左边与右边相同:大小以及数据的类型都要相同
- !==:不全等于,只有大小或者类型不同
$a = 123; //整形
$b = '123';//字符串
var_dump($a == $b); #bool(true)
var_dump($a === $b); #bool(false) 大小和类型都要相同
逻辑运算符
逻辑运算:针对不同的结果进行匹配。满足条件返回true,不满足返回false
- &&:逻辑与,左边的条件与右边的条件同时成立(两边结果都为true)
- ||:逻辑或,左边的条件或者右边的条件只要有一个满足即可
- !:逻辑非,对已有条件进行取反,本身为true,取反结果就是false
逻辑与和逻辑或又称之为短路运算:如果第一个表达式结果已经满足条件了,那么就不会运行逻辑运算符后面的表达式
连接运算符
连接运算:是PHP中将多个字符串拼接的一种符号
- 使用
.
可以将两个字符串连接到一起 -
.=
复合运算,将左边的内容与右边的内容连接起来,然重新赋值给左边变量
例如:A .= B
==> A = A.b
$a = 'hello';
$b = 'Mango';
echo $a.$b; #helloMango
echo '<hr/>';
$a .= $b;
echo $a; #helloMango
错误抑制符
在PHP中有一些错误可以提前预知,但是这些错误可能无法避免,但是又不望报错给用户看,可以使用错误抑制符处理。
@
:在可能出错的表达式前面使用@符号即可。
- 错误抑制符通常在生产环境(上线)会用到,在开发的时候不会用:系统本身最好没有任何错误。
$a = 10;
$b = 0;
@($a / $b); //如果没有错误抑制:报错Warning: Division by zero in D:\apache\htdocs\index.php on line 86
三目运算符
三目运算:有三个表达式参与的运算(简单的的分支结构缩写)
格式:表达式1 ? 表达式2 :表达式3;
- 如果表达式1成立,那么执行表达式2,否则执行表达式3
注意:如果表达式本身比较复杂,建议使用括号包起来
$a = 10;
$b = $a >= 10 ? 20 : 10;
echo $b ; //20
可以得知三目运算符的优先级比赋值运算符高
自操作运算符
后置自操作:先把自己所保存的值留下来,然后改变自己,自己给别人的值是原来的值;
前置自操作:先把自己改变,然后把改变后的值给别人。
$a = 0;
$b = 0;
echo $a++,'<br/>',++$b; // 0 1
echo '<br/>',$a,'<br/>',$b;// 1 1
衍生符号:类似自操作
+=:左边的结果与右边结果相加,然后赋值给左边
-=:左边的减去右边的结果,然后复制给左边
*=:乘法操作
/=:除法操作
%=:模操作
注意:
1.右侧的内容是一个整体
$a = 10;
$b = 5;
$a -= $b-1; //相当于:$a = $a - ($b-1)
echo $a;//6
2.如果进行除法或者取余运算,那么要考虑右边表达式的结果是否为0(为0出错)
计算机码
计算机码:计算机在实际存储数据的时候,采用的二进制编码规则
- 计算机码:原码、反码和补码
- 数值本身最左边一位是用来充当符号位:正数为0,负数为1
位运算
&:按位与,两个位都为1,结果为1,否则为0
|:按位或,两个有一个为1,结果为1
~:按位非,一个位如果为1则变成0,否则反之
^:按位异或,两个相同则为0,不同则为1
<<:按位左移,整个位(32位),向左移动一位,右边补0 (乘以2的操作)
>>:按位右移,整个位向右移动一位,左边补符号位对应内容(正数补0,负数补1) (除以2的操作(不完全正确,因为整数除2会出现小数)
注意:
1.系统进行任何位运算的时候都是使用的补码
2.运算结束之后都必须转换成原码才是最终要显示的数据
运算符优先级问题
运算符优先级:在多种运算符同时存在的时候,如何结合运算
流程控制
顺序结构:代码从上往下,顺序执行。(代码执行的最基本结构)
分支结构:给定一个条件,同时有多种可执行代码(块),然后会根据条件执行某一段代码
循环结构:在某个条件控制范围内,指定的代码(块)可以重复执行
顺序结构
顺序结构:最基本结构,所有代码默认都是从上往下依次执行
分支结构
在PHP中,分支结构主要有两种:if分支和switch分支
if分支
版本1:
if(条件表达式){
//满足条件所要执行的内容; //顺序结构
}
版本2:
if(条件表达式){
//满足条件后执行的代码段;
}else{
//不满足条件执行的代码段;
}
版本3:
if(条件表达式1){
//满足条件表达式1的代码段;
}elseif(条件表达式2){
//不满足表达式1条件,但是满足表达式2的代码;
}… //可以使用多个elseif来进行再次条件筛选
else{
//全部不满足要执行的代码;
}
注意:如果条件特别多才会采用复合if形式
1.如果条件比较单一(同一个条件),会采用elseif复合方式
2.如果判断条件不一致,建议使用嵌套语法(不宜有太多层嵌套:影响代码美观)
If分支,适用于所有的条件判断(分支结构)
switch分支
switch分支:有一组情形存在,同过一条件,通常有多个值,但是每一个值都会有对应不同的代码要执行
基本语法:
switch(条件表达式){
//所有条件判断:逐个进行
case 值1:
//当前条件表达式的结果与值1相等要执行的代码段;
break;//在switch中,如果条件匹配成功,那么系统就不会再次匹配条件,会自动顺序执行向下的所有代码(case代码除外),需要中断执行
case 值2:
//要执行的代码段;
break;
//....
default:
//匹配失败的代码;
break;
}
if和switch的选择
1.if能做所有的分支结构事情
2.switch处理的是条件比较多,同时比较单一,而且是固定值匹配的分支结构
循环结构
在PHP中循环结构有以下几种:
- for循环:通过条件、起始和终止判断执行
- while循环:通过判断条件终止
- do-while循环:跟while差不多
- foreach循环:专门针对数组
for循环
基本语法
//条件表达式1:定义初始化条件,可以有多种赋值语句存在,使用逗号分隔即可
//条件表达式2:边界判定,限定循环执行的次数
//条件表达式3:用来执行条件变化(自操作)
for(条件表达式1;条件表达式2;条件表达式3){
//循环体
}
例子1:从1输出到10
for($i = 0;$i <= 10;$i++) echo " ".$i;
例子2:死循环
for(;;)
while循环
基本语法
//条件表达式就是判断边界条件
while(条件表达式){
循环体; //循环条件的变化
}
例子1:从1输出到10
$i = 0;
while($i <= 10)
{
echo $i." ";
$i++;
}
例子2:死循环
while(1){}
for与while的选择
1.如果是基于固定已知条件(数值而且是有规律的变化),使用for循环
2.while可以做灵活的条件判定(while使用的比较多)
do-while循环
do-while:看着很像while,while首先进行条件判定然后执行循环体,有可能出现第一次就条件不满足,那么就会直接失败(循环体一次都不执行)
- do-while就是先干了再说(执行循环体),后判断条件(至少会执行一次循环体)
基本语法
do{
//循环体
}while(条件表达式);
continue和break
continue:跳过本轮循环,执行下一轮循环
break:跳出本次循环,不再执行
文件包含
文件包含:在一个PHP脚本中,去将另外一个文件(PHP)包含进来,去合作完成一件事情。
意义:
1.要么使用被包含文件中的内容,实现代码的共享(重用):向上包含(索要)
- 向上包含:在当前脚本要用某个代码之前包含别的文件
2.要么自己有东西可以给别的文件使用,实现代码的共享(重用):向下包含(给予)
- 向下包含:在自己有某个东西的时候,需要别的脚本来显示(自己代码写完之后包含其他文件)
最大的作用:分工协作,每个脚本做的事情不一样,因此可以使用协作方式,让多个脚本共同完成一件事情。
四种形式
在PHP中文件的包含有四种形式(两种大形式):
- include:包含文件
- include_once:系统会自动判断文件包含过程中,是否已经包含过。(是否被重复包含,因为一个文件最多被包含一次)
- require:作用和include相同
- require_once:作用和include_once相同
基本语法
include '文件名字'
include('文件名字')
文件加载原理
1.在文件加载(include或者require)的时候,系统会自动的将被包含文件中的代码相当于嵌入到当前文件中
2.加载位置:在哪加载,对应的文件中的代码嵌入的位置就是对应的include位置
3.在PHP中被包含的文件是单独进行编译的
PHP文件在编译的过程中如果出现了语法错误,那么会失败(不会执行);但是如果被包含文件有错误的时候,系统会在执行到包含include这条语句的时候才会报错。
include和require的区别
include和include_once的区别:
- include系统会碰到一次,执行一次;如果对同一个文件进行多次加载,那么系统会执行多次
- include_once:系统碰到多次,也只会执行一次。
使用include
使用include_once
require和include的区别:本质都是包含文件,唯一的区别在于包含不到文件的时候,报错的形式不一样
- include的错误级别比较轻:不会阻止代码执行
- require要求较高:如果包含出错代码不再执行(require后面的代码)
使用include
使用require
文件的加载路径
文件在加载的时候需要指定文件路径才能保证PHP正确的找到对应的文件。
文件的加载路径包含两大类:
- 绝对路径、:从磁盘的根目录开始(本地绝对路径)
- Windows:盘符C:/路径/PHP文件
- Linux:/路径/PHP文件
- 从网站根目录开始(网络绝对路径)
- /:相对于网站主机名字对应的路径
- 相对路径:从当前文件所在目录开始的路径
-
.
:当前目录 -
..
:上级目录
-
绝对路径和相对路径的加载区别
1.绝对路径相对效率偏低,但是相对安全(路径不会出问题)
2.相对路径相对效率高些,但是容易出错(相对路径会发生改变)
文件嵌套包含
文件嵌套包含:一个文件包含另外一个文件,同时被包含的文件又包含了另外一个文件。
嵌套包含的时候就很容易出现相对路径出错的问题:相对路径会因为文件的包含而改变(.和…的含义会变)
函数
函数:function,是一种语法结构,将实现某一个功能的代码块(多行代码)封装到一个结构中,从而实现代码的重复利用(复用)。
定义&使用
function 函数名(参数){
//函数体
//返回值:return 结果;
}
定义函数的目的:是为了实现代码的重复利用,一个功能一个函数(简单明了)
函数的使用:通过 函数名()
的方式进行函数访问
注意:
- 如果函数在定义的过程中有参数,那么在调用的时候就必须传入对应的参数:函数是一种结构不会自动运行,必须通过调用才会执行
- 函数是在代码执行阶段,碰到函数名字的时候才会调用,不是在编译阶段。
- 函数的调用特点:只要系统在内存中能够找到对应的函数,就可以执行(函数的调用可以在函数定义之前)
display(20); //20hello Mango
function display($val)
{
echo $val;
echo "hello Mango";
}
命名规则
命名规范:由字母、数字和下划线组成,但是不能以数字开头
函数作为一种常用的结构,一般遵循以下规则:函数通常名字代表着函数的功能,而有些功能会比较复杂,可能一个单词不足以表达,需要多个组合。
1.驼峰法:除了左边第一个单词外,后面所有的单词首字母都大写:showParentInfo()
2.下划线法:单词之间通过下划线连接,单词都是小写:show_parent_info()
函数名字:在一个脚本周期中,不允许出现同名函数(通常在一个系统开发中都不会使用同名函数)
参数种类
函数的参数分为两种:形参和实参
- 形参:形式参数,不具有实际意义的参数,是在函数定义时使用的参数
- 实参:实际参数,具有实际数据意义的参数,是在函数调用时使用的参数
形参是实参的载体:实参在调用时通常是需要传入到函数内部参与计算(运算),那么需要在函数内部去找到实际数据所在的位置才能找到数据本身:需要实际调用的时候,将数据以实参的形式传递给形参:给形参赋值,从而使得函数内部可以用到外部数据。
例子:
注意:
1.在PHP中允许实参多于形参(个数):函数内部不用而已
2.在PHP中理论上形参个数没有限制(实际开发不会太多)
3.实参不能少于形参个数
默认值
默认值指的是形参的默认值,在函数定义的时候,就给形参进行一个初始赋值:如果实际调用传入的参数(实参)没有提供,那么形参就会使用定义时的值来进入函数内部参与运算。
通常默认值是用在一些一定会有某个数据参与,但是可能通常是某个我们知道的值。
注意事项:
1.默认值的定义是放在最右边的(多个),不能左边形参有默认值,但是右边没有 (必须从右往左缺省,而且要连续)
2.函数外部定义的变量名字与函数定义的形参名字冲突(同名)是没有任何关联关系的,如果多个函数使用同样的形参名字也不冲突。
引用传递
实参在调用时会将值赋值给形参,那么实际上使用的方式就是一种简单的值传递:将实参(如果是变量或者常量或者其他表达式)的结果(值)取出来赋值给形参:形参与外部实际传入的参数本身没有任何关联关系:只是结果一样。
如果希望在函数内部拿到的外部数据,能够在函数内部改变,那么就需要明确告知函数(定义时),函数才会在调用的时候去主动获取外部数据的内存地址。以上这种定义形式参数的方式叫作引用传值。
function 函数名(形参1,&形参2){ //此时形参1是值传递 形参2是引用传递
//函数体
}
在调用的时候,必须给引用传值的参数位置传入实际参数,而且参数本身必须是变量。(变量才有指向的数据的内存地址)
$a = 1;
$b = 1;
function AddMyself($a,&$b)
{
$a++;
$b++;
}
AddMyself($a,$b);
echo $a,'<br/>',$b; // 1 2
引用传值注意事项:在传入实参的时候,必须传入变量
函数返回值
返回值:return,指的是将函数实现的结果,通过return关键字,返回给函数外部(函数调用处):在PHP中所有的函数都有返回值。(如果没有明确return使用,那么系统默认返回NULL)
function display()
{
echo "hello world";
}
var_dump(display()); //NULL
函数的返回值可以是任意数据类型
return关键字
- return在函数内部存在的价值:返回当前函数的结果(当前函数运行结束,后续return的代码不会执行)
- return还可以在文件中直接使用(不在函数里面):代表文件将结果return后面跟的内容,转交给包含当前文件的位置。(通常在系统配置文件中使用较多),在文件中也代表中终止文件后面的代码:return之后的内容不会执行
$res = include_once 'func.hpp'; //假设该文件return 'hello world'
echo $res;//hello world
作用域
作用域:变量(常量)能够被访问的区域
1.变量可以在普通代码中定义
2.变量也可以在函数内部定义
在PHP中作用域严格来说分为两种:但是PHP内部还定义一些在严格意义之外的一种,所以总共算三种:
1.全局变量:就是用户普通定义的变量(函数外部定义)
- 所属全局空间:在PHP中只允许在全局空间使用:理论上函数内部不可访问
- 脚本周期:直到脚本运行结束(最后一行代码执行完)
$glo = 'global area';
function func()
{
$inner = __FUNCTION__;
echo $glo;//err,函数内部不可访问外部全局变量
}
2.局部变量:就是在函数内部定义的变量
- 所属当前函数空间:在PHP中只允许在当前函数自己内部使用
- 函数周期:函数执行结束(函数是在栈区中开辟独立内存空间运行)
3.超全局变量:系统定义的变量(预定义变量:$_SERVER、$_POST等)
- 所属超全局空间:没有访问限制(函数内外都可以访问)
超全局变量会将全局变量自动纳入到$GLOBALS里面,而$GLOBALS没有作用域限制,所以能够帮助局部去访问全局变量:但是必须使用数组方式
$glo = 'global area';
function func()
{
echo $GLOBALS['glo'];
}
func(); //global area
echo '<hr/>';
echo $glo; //global area
如果想函数内部使用外部变量:除了$GLOBALS之外,通过参数传值(如果要统一战线还可以使用引用传值)。
global关键字
在PHP中,其实还有一种方式,能够实现全局访问局部,同时局部也可以访问全局:global关键字
global关键字:是一种在函数里面定义变量的一种方式
1、 如果使用global定义的变量名在外部存在(全局变量),那么系统在函数内部定义的变量直接指向外部全局变量所指向的内存空间(同一个变量);
2、 如果使用global定义的变量名在外部不存在(全局变量),系统会自动在全局空间(外部)定义一个与局部变量同名的全局变量
本质的形式:在函数的内部和外部,对一个同名变量(全局和局部)使用同一块内存地址保存数据,从而实现共同拥有。
语法规则
global 变量名;//不能赋值
$变量名 = 值;
例子:
$global = 'global area';
function func()
{
//外部存在同名的global变量
//函数内部定义的变量直接指向外部全局变量所指向的内存空间
global $global;
echo $global;
//定义全局不存在变量
global $local;
$local = 'inner func';
}
func(); //global area
echo '<hr/>';
echo $local;//访问"局部"变量 inner func
以上方式可以实现局部与全局的互访,但是通常不会这么用。一般如果会存在特殊使用,也会使用参数的形式来访问。(还可以使用常量:define定义的常量)
define('PI', 3.14);
function func()
{
echo PI;
}
func(); //3.14
echo PI;//3.14
静态变量
静态变量:static,是在函数内部定义的变量,使用static关键字修饰,用来实现跨函数共享数据的变量:函数运行结束所有局部变量都会清空,如果重新运行一下函数,所有的局部变量又会重新初始化,而静态变量不会
语法
function 函数名(){
//定义变量
static $变量名 = 值; //通常会在定义的时候就直接赋值
}
例子
function func()
{
$local = 0;
static $count = 0;
$count++;
$local++;
echo $local," ",$count;
}
func(); echo '<hr/>';//1 1
func(); echo '<hr/>';//1 2
func(); echo '<hr/>';//1 3
静态变量的作用是为了跨函数共享数据(同一个函数被多次调用)
使用
1、 为了统计:当前函数被调用的次数
2、 为了统筹函数多次调用得到的不同结果(递归思想)
可变函数
可变函数:当前有一个变量所保存到值,刚好是一个函数的名字,那么就可以使用$变量()
来充当函数名使用
- 该变量相当于是C语言当中的函数指针
语法
$变量名 = '函数名'
function 函数名(函数参数){
//...
}
$变量名(函数参数)
使用例子
$func = 'display';
function display()
{
echo "hell I am function display()" ;
}
$func();//hell I am function display()
可变函数在系统使用的过程中还是比较多的,尤其是使用很多系统函数的时候:需要用户在外部定义一个自定义函数,但是是需要传入到系统函数内部使用 (回调函数)
//假设是系统函数 -求第二个参数的4次方
function sys_func($arg1,$arg2)
{
return $arg1($arg2);//user_func($agr2)
}
function user_func($num)
{
return pow($num,4);
}
echo sys_func('user_func',10);//求10^4 ==> 10000
匿名函数
匿名函数==>没有名字的函数
基本语法
变量名 = function(函数参数){
//函数体
}
使用一个变量保存匿名函数,本质该变量是一个对象(Closure)
使用例子
$func = function(){
echo "hello world";
};
$func();//hello world
var_dump($func);//object(Closure)#1 (0) { }
闭包
简单来说:函数内部有一些局部变量在函数执行之后没有被释放,是因为在函数内部还有对应的函数在引用(函数的内部函数:匿名函数)
证明:函数内部的局部变量在函数使用完之后没有被释放
1、 使用内部匿名函数;
2、 匿名函数使用外部局部变量:use;
3、 匿名函数被返回给外部使用
function func()
{
$name = "HELLO WORLD";
//定义匿名函数
//use就是将外部局部变量保留给内部使用
$innerFunction = function() use($name)
{
echo $name;
}; //注意分号!
return $innerFunction;//返回内部匿名函数
}
$get = func(); //$get = $innerFunction
$get();//HELLO WORLD
常用系统函数
输出函数
print()
:类似于echo输出提供的内容,本质是一种结构(不是函数),但是有返回值,始终返回1,可以不需要使用括号
print_r()
:类似于var_dump,但是比var_dump简单,不会输出数据的类型,只会输出值(数组打印使用比较多)
时间函数
date():按照指定格式对对应的时间戳(从1970年格林威治时间开始计算的秒数),如果没有指定特定的时间戳,那么就是默认解释当前时间戳
time():获取当前时间对应的时间戳
microtime():获取微秒级别的时间
strtotime():按照规定格式的字符串转换成时间戳
echo time(),'<br/>';
echo microtime(),'<br/>';
echo strtotime('tomorrow 10 hours');
数学函数
max():指定参数中最大的值
min():比较两个数中较小的值
rand():得到一个随机数,指定区间的随机整数
mt_rand():与rand一样,只是底层结构不一样,效率比rand高(建议使用)
round():四舍五入
ceil():向上取整
floor():向下取整
pow():求指定数字的指定指数次结果:pow(2,8) == 2^8 == 256
abs():绝对值
sqrt():求平方根
与函数相关函数
function_exists():判断指定的函数名字是否在内存中存在(帮助用户不去使用一个不存在的函数,让代码安全性更高)
func_get_arg():在自定义函数中去获取指定数值对应的参数
func_get_args():在自定义函数中获取所有的参数(以数组形式返回)
func_num_args():获取当前自定义函数的参数数量(个数)
function testFunc($a,$b)
{
//获取指定参数 --获取第一个参数
var_dump(func_get_arg(1));
//获取所有参数
var_dump(func_get_args());
//获取参数数量
var_dump(func_num_args());
}
echo '<pre>';
//短路运算,该函数存在才调用
function_exists('testFunc') && testFunc(1,'2',3.14);
输出:
string(1) "2"
array(3) {
[0]=>
int(1)
[1]=>
string(1) "2"
[2]=>
float(3.14)
}
int(3)
注意:参数的标识是从0开始的,func_get_args和func_num_args都是统计的对应实参的数量
错误处理
错误处理:指的是系统(或者用户)在对某些代码进行执行的时候,发现有错误,就会通过错误处理的形式告知程序员。
错误分类
1)语法错误:用户书写的代码不符合PHP的语法规范,语法错误会导致代码在编译过程中不通过,所以代码不会执行(Parse error)
2)运行时错误:代码编译通过,但是代码在执行的过程中会出现一些条件不满足导致的错误(runtime error)
3)逻辑错误:程序员在写代码的时候不够规范,出现了一些逻辑性的错误,导致代码正常执行,但是得不到想要的结果
错误代号
所有看到的错误代号在PHP中都被定义成了系统常量(可以直接使用)
1)系统错误:
- E_PARSE:编译错误,代码不会执行
- E_ERROR:fatal error,致命错误,会导致代码不能正确继续执行(出错的位置断掉)
- E_WARNING:warning,警告错误,不会影响代码执行,但是可能得到意想不到的结果
- E_NOTICE:notice,通知错误,不会影响代码执行
2)用户错误:E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE
- 用户在使用自定义错误触发的时候,会使用到的错误代号(系统不会用到)
3)其他:E_ALL,代表着所有从错误(通常在进行错误控制的时候使用比较多),建议在开发过程中(开发环境)使用
注意:所有以E开头的错误常量(代号)其实都是由一个字节存储,然后每一种错误占据一个对应的位,如果想进行一些错误的控制,可以使用位运算进行操作
- 排除通知级别notice:E_ALL & ~E_NOTICE
- 只要警告和通知:E_WARNING | E_NOTICE
错误触发
程序运行时触发:系统自动根据错误发生后,对比对应的错误信息,输出给用户:主要针对代码的语法错误和运行时错误。
- 比如说:代码最后忘记写分号
;
人为触发:知道某些逻辑可能会出错,从而使用对应的判断代码来触发响应的错误提示trigger_error(错误提示)
$a = 10;
$b = 0;
if($b == 0)
{
trigger_error('被除数不能为0');
}
可以通过第二个参数进行严格性控制错误提示,默认是notice:通知错误,不会影响代码执行
字符串类型
定义语法
引号方式:比较适合定义那些比较短(不超过一行)或者没有结构要求的字符串
1)单引号字符串:使用单引号包裹
2)双引号字符串:使用双引号包裹
$str = "hello world";
$str2 = 'hello world'
3)nowdoc字符串:没有单引号的单引号字符串
$str = <<<’边界符’
字符串内容
边界符;
4)heredoc字符串:没有双引号的双引号字符串
$str = <<<边界符
字符串内容
边界符;
例子:
//heredoc结构
$str3 = <<<EOD
hello
EOD;
//nowdoc结构
$str4 = <<<'EOD'
hello
EOD;
var_dump($str3,$str4);
?>
Heredoc和nowdoc比引号还是要区别多一点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WV9Dr8WX-1692673869657)(C:/Users/Mango/AppData/Roaming/Typora/typora-user-images/image-20230801110215945.png)]
字符串转义
转义的含义:在计算机通用协议中,有一些特定的方式定义的字母,系统会特定处理:通常这种方式都是使用反斜杠+字母(单词)的特性:
在PHP中系统常用的转义符号:
\’:在单引号字符串中显示单引号
\”:在双引号字符串中显示双引号
\r:代表回车(理论上是回到当前行的首位置)
\n:代表新一行
\t:类似tab键,输出4个空格
$:在PHP中使用$符号作为变量符号,因此需要特定识别
单引号和双引号的区别
1、 其中单引号中能够识别\’,而双引号中就不能识别\’(下图浏览器查看的是页面源代码)
2、 双引号因为能够识别$符号,所以双引号中可以解析变量,而单引号不可以
//变量识别:
$str1 = 'abcd {$a} dfg';
$str2 = "abcd {$a} dfg";
var_dump($str1,$str2);//string(13) "abcd {$a} dfg" string(14) "abcd hello dfg"
双引号中变量识别的规则
1)变量本身系统能够与后面的内容区分:应该保证变量的独立性,不要让系统难以区分
$a = 'hello';
$str = "abc$afd";//系统会将afd作为一个变量,而现在没有该变量的定义,所以会出错
2)使用变量专业标识符(区分),变量加上一组大括号{}
$a = 'hello';
$str = "abc{$a}fd";//系统会将afd作为一个变量,而现在没有该变量的定义,所以会出错
字符串相关函数
1)基本函数strlen():得到字符串的长度(字节为单位)
$str1 = 'abcde';
$str2 = '你好中国';
echo strlen($str1)," ",strlen($str2); //5 12
在utr8字符集下,一个中文占3字节
2)转换函数:implode(), explode(), str_split()
- implode(连接方式,数组):将数组中的元素按照某个规则连接成一个字符串
- explode(分割字符,目标字符串):将字符串按照某个格式进行分割,变成数组
- 中国|北京|顺义 == array(‘中国’,‘北京’,’顺义’);
- str_split(字符串,字符长度):按照指定长度拆分字符串得到数组
3)截取函数:trim(), ltrim(), rtrim()
trim(字符串[,指定字符]):本身默认是用来去除字符串两边的空格(中间不行),但是也可以指定要去除的内容,是按照指定的内容循环去除两边有的内容:直到碰到一个不是目标字符为止
ltrim():去除左边的 rtrim():去除右边的
4)截取函数:substr(), strstr()
substr(字符串,起始位置从0开始[,长度]):指定位置开始截取字符串,可以截取指定长度(不指定到最后)
strstr(字符串,匹配字符):字符串匹配函数,从指定位置开始,截取到最后(可以用来去文件后缀名)
$str = ' abcd e f';
echo substr($str,1,3),"<br/>"; //abc
echo strstr($str,'c');//cd e f
5)大小转换函数:strtolower(), strtoupper(), ucfirst()
strtolower:全部小写
strtoupper:全部大写
ucfirst:首字母大写
6)查找函数:strpos(), strrpos()
strpos(字符串,匹配字符):判断字符在目标字符串中出现的位置(首次)
strrpos(字符串,匹配字符):判断字符在目标字符串中最后出现的位置
7)替换函数:str_replace()
str_replace(匹配目标,替换的内容,字符串本身):将目标字符串中部分字符串进行替换
8)格式化函数:printf(), sprintf()
printf/sprintf(输出字符串有占位符,顺序占位内容…):格式化输出数据
$age = 10;
printf("hello I am Mango,My age:%d",$age);
echo sprintf("hello I am Mango,My age:%d\n",$age);
9)其他:str_repeat(), str_shuffle()
str_repeat():重复某个字符串N次
str_shuffle():随机打乱字符串
数组
数组:array,数据的组合,指将一组数据(多个)存储到一个指定的容器中,用变量指向该容器,然后可以通过变量一次性得到该容器中的所有数据。
定义方式
在PHP中系统提供多种定义数组的方式:
1、 使用array关键字:最常用的
$变量 = array(元素1,元素2,元素3..);
$arr = array('1',2,'hello');
var_dump($arr);//array(3) { [0]=> string(1) "1" [1]=> int(2) [2]=> string(5) "hello" }
2、 可以使用中括号来包裹数据:
- $变量 = [元素1,元素2…];
$arr =['1',2,'hello',3.14];
var_dump($arr);//array(4) { [0]=> string(1) "1" [1]=> int(2) [2]=> string(5) "hello" [3]=> float(3.14) }
3、 隐形定义数组:给变量增加一个中括号,系统自动变成数组
$变量[] = 值1; //如果不提供下标也可以,系统自动生成(数字:从0开始)
$变量[下标] = 值; //中括号里面的内容称之为下标key,该下标可以是字母(单词)或者数字,与变量命名的规则相似
$arr[] = 1;
$arr[10] = 'ten';
$arr[] = 'what number'; //默认下标是从当前前面最大的数字下标开始递增,所以这里的下标是11
$arr['key'] = 'value';
var_dump($arr);//array(4) { [0]=> int(1) [10]=> string(3) "ten" [11]=> string(11) "what number" ["key"]=> string(5) "value" }
数组特点
1)可以整数下标或者字符串下标
-
如果数组下标都为整数:索引数组
-
如果数组下标都为字符串:关联数组
2)不同下标可以混合存在:混合数组
3)数组元素的顺序以放入顺序为准,跟下标无关
4)数字下标的自增长特性:从0开始自动增长,如果中间手动出现较大的,那么后面的自增长元素从最大的值+1开始
5)特殊值下标的自动转换
-
布尔值:true和false
-
空:NULL
$arr[false] = false;
$arr[true] = true;
$arr[NULL] = NULL;
var_dump($arr);//array(3) { [0]=> bool(false) [1]=> bool(true) [""]=> NULL }
6)PHP中数组元素没有类型限制
7)PHP中数组元素没有长度限制
补充:PHP中的数组是很大的数据,所以存储位置是堆区,为当前数组分配一块连续的内存。
二维数组
多维数组:数组里面的元素又是数组。在第二维的数组元素中可以继续是数组,在PHP中没有维度限制(PHP本质并没有二维数组),但是:不建议使用超过三维以上的数组,会增加访问的复杂度,降低访问效率。
- 二维数组:数组中所有的元素都是一维数组
$info = array(
array('name' => 'Mango','age' => 20),
array('name' => 'Lemon','age' => 10),
array('orange' => '','age' => 30),
);
echo '<pre>';
var_dump($info);
//输出
array(3) {
[0]=>
array(2) {
["name"]=>
string(5) "Mango"
["age"]=>
int(20)
}
[1]=>
array(2) {
["name"]=>
string(5) "Lemon"
["age"]=>
int(10)
}
[2]=>
array(2) {
["orange"]=>
string(0) ""
["age"]=>
int(30)
}
}
数组遍历
数组遍历:普通数组数据的访问都是通过数组元素的下标来实现访问,如果说数组中所有的数据都需要依次输出出来,就需要我们使用到一些简化的规则来实现自动获取下标以及输出数组元素。
$arr = array(0=>array('name' => 'Tom'), 1=>array('name' => 'Jim')); //二维数组
//访问一维元素:$arr[一维下标]
$arr[0]; //结果:array(‘name’ => ‘Tom’);
//访问二维元素:$arr[一维下标][二维下标
$arr[1]['name']; //Jim
foreach遍历语法
基本语法
foreach($数组变量 as [$下标 =>] $值){
//通过$下标访问元素的下标;通过$值访问元素的值
}
通常:如果是关联数组(字母下标),就需要下标,如果是数字下标就直接访问值
$arr = array(1,2,3,4,5,6,7,8,9,10);
foreach($arr as $key => $val)
{
echo 'key:',$key,'====value:',$val,'<br/>';
}
//输出
key:0====value:1
key:1====value:2
key:2====value:3
key:3====value:4
key:4====value:5
key:5====value:6
key:6====value:7
key:7====value:8
key:8====value:9
key:9====value:10
原理:
foreach遍历的原理:本质是数组的内部有一颗指针,默认是指向数组元素的第一个元素,foreach就是利用指针去获取数据,同时移动指针。
for循环遍历数组
for循环:基于已知边界条件(起始和结束)然后有条件的变化(规律)。因此:for循环遍历数组有对应条件
1、 获取数组长度:count(数组)得到数组元素的长度
2、 要求数组元素的下标是规律的数字
$arr = array(1,2,3,4,5,6,7);
for($i = 0,$len = count($arr);$i < $len ;$i++)
{
printf("key:%d val:%d",$i,$arr[$i]);
echo '<pre>';
}
相关函数
1)排序函数:对数组元素进行排序,都是按照ASCII码进行比较,可以进行英文比较
-
sort():顺序排序(下标重排)
-
rsort():逆序排序(下标重排)
-
shuffle():随机打乱数组元素,数组下标会重排
2)指针函数
- reset():重置指针,将数组指针回到首位
- end():重置指针,将数组指针指导最后一个元素
- next():指针下移,取得下一个元素的值
- prev():指针上移,取得上一个元素的值
- current():获取当前指针对应的元素值
- key():获取当前指针对应的下标值
注意事项:next和prev会移动指针,有可能导致指针越界,导致数组不能使用,通过next和prev不能回到真确的指针位置。只能通过end或者reset进行指针重置
$arr = array(3,1,5,2,0);
echo next($arr)," ",next($arr),'<br/>'; //1 5
echo prev($arr),'<br/>';//1
echo current($arr),'<br/>';//1
echo key($arr),'<br/>';//下标:1
3)其他函数
- count():统计数组中元素的数量
- array_push():往数组中加入一个元素(尾插)
- array_pop():从数组中取出一个元素(尾删)
- array_shift():从数组中取出一个元素(头删)
- array_unshift():从数组中加入一个元素(头插)
- array_reverse():数组元素反过来 --逆置数组
- in_array(数值,数组):判断一个元素在数组中是否存在
- array_keys():获取一个数组的所有下标,返回一个索引数组
- array_values():获取一个数组的所有值,返回一个索引数组
相关题目
求斐波那契数
//求第n个斐波那契数
// 1 1 2 3 5 8 13...
function Fib_recursion($n)
{
if($n == 1 || $n == 2)
return 1;
else
return Fib($n-1) + Fib($n-2);
}
function Fib_cycle($n)
{
$f1 = 1;
$f2 = 1;
$f3 = 0;
for($i = 3;$i<=$n;$i++)
{
$f3 = $f2 + $f1;
$f1 = $f2;
$f2 = $f3;
}
return $f2;
}
echo Fib_cycle(6);