Post

Php

Php

•PHP

搭建环境

什么是PHP

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

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

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

安装Apache环境

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

安装Apache软件

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

image-20220118163917725

2.双击安装

image-20220118164142869

3.选择自定义

image-20220118164441771

4.选择安装位置

image-20220118164520946

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

image-20220118175158830

2.解压
1
解压你下载的文件,将解压后的文件,放在相应的目录
3.配置

3_1.进入所在目录

3_2.下载服务器

1
输入httpd -k install -n apache。(该命令的意思是,安装apache服	务器,并将该服务器名称命名为apache)

(若出现localhost拒绝连接则可能是未下载服务器)

image-20220118175615850

3_3.修改httpd.conf 把路径改为自己的安装路径

image-20220118175930118

3_4.配置文件更改权限(可能?)

搜到的教程中说要改,于是跟着改了,不知道不改要不要紧。

image-20220118180455127

Apache 的目录结构说明

image-20220118164614459

Httpd.exe的详细应用

1.服务器进程

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

image-20220118164932789

2.运行httpd

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

image-20220118165013317

2_1.查看使用的模块:httpd -M

image-20220118165308587

2_2.验证配置文件是否有效:httpd -t

image-20220118165448526

配置默认站点

1.Apache确定服务器上访问的位置

网站文件夹所在位置。

Httpd.conf: DocumentRoot

image-20220118170239004

2.方便用户使用名字访问对应的网站

给文件夹对应的取一个别名。

Http.conf: ServerName

image-20220118170310908

端口可以单独实现:httpd.conf: listen

image-20220118170429373

3.重启Apache

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

4. 实现 DNS 域名解析

通常默认站点都是本地 DNS:hosts文件。

image-20220118170804796

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

安装与配置PHP

安装PHP语言

1.获取PHP安装文件

image-20220118171824651

2.解压缩

PHP目录结构说明

image-20220118172151887

PHP.exe的应用

1
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是不需要写的,写了会报错)

image-20220118204508927

1_1.cmd在Apache的bin目录下输入httpd -M确认模块已导入

image-20220118204410974

2.Apache 分配工作给 PHP 模块

如果是PHP 代码就交给PHP处理:文件后缀判断.php 结尾肯定是PHP代码: AddType application/x-httpd-php .php

image-20220118205339294

3. 将PHP的配置文件加载到Apache配置文件中:共同生效。

3_1.在Apache中指定PHP配置文件所在路径。

PHPIniDir php.ini 所在路径

image-20220118224741084

3_2. php.ini文件

php.ini文件默认是不存在的,是以development和production格式存在,需要格式化。

可以将php.ini-development复制后改名为php.ini。

运行时出现问题

image-20220118222929820

解决方式:

原因是PHP 8.0需要用到Visual Studio 2019的Microsoft Visual C ++ Redistributable工具,需要访问下载 Windows 版和 Mac 版 Visual Studio 2019进行下载

image-20220118223048972

PHP连接数据库

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

1.PHP加载MYSQL扩展

MySQL扩展:php.ini文件中。

image-20220118234056762

2.制定扩展路径

PHP中所有的扩展都是在ext文件中,需要制定扩展所在路径:extension_dir

image-20220118231644541

extension_dir 顾名思义他是放php 扩展的目录。 比如我的是:

extension_dir = “D:/Security/Server/php/ext”

当我要添加 redis.dll扩展的时候,我就无需写完整路径比如说

D:/Security/Server/php/ext/redis.dll

只要写 extension=redis.dll了。

3.重启Apache

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

搭建基于域名的虚拟主机

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

1.在主配置文件中搭建

需要手动开启虚拟主机(基于域名): NameVirtualHost *:80

2.在专门的虚拟主机配置文件中配置。
1.加载配置文件

在主配置文件(php.ini)中加载虚拟主机配置文件:虚拟主机配置文件已经开启了虚拟主机 NameVirtualHost

image-20220119153756616

2.配置虚拟主机

虚拟主机配置文件中配置虚拟主机

image-202201191610021782_1.增加一个对应的站点文件夹位置:DocumentRoot

image-20220119160801657

2_2.增加主机名字:文件夹的别名:ServerName image-20220119161312660

2_3.增加域名解析 DNS: hosts

image-20220119161710138

2_4.需要给当前设定的站点(目录)访问权限

Apache2.4会报错不能识别Order,Deny,Allow

<Directory ‘站点目录’>

Order Deny,Allow //没有顺序关系:实际顺序有意义 Deny from 指定的范围 Allow from 指定范围/all

</Directory>

image-20220119163340245

2_5.配置访问列表

当访问是一个目录时候(没有指定具体要访问的文件)。 Options Indexes [FollowSymLinks],如果访问目录,那么列表显示所有文件。

image-20220119165028290

2_6.当用户访问指定目录不指定文件的时候,通常需要系统指定一个默认文件。 Directorylndex 默认的文件列表,使用空格分离。

image-20220119165344330

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

3.localhost配置

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

4.添加样图

image-20220119170301792

PHP基础

PHP语法初步.

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

PHP代码标记

在 PHP 历史发展中,可以使用多种标记来区分 PHP 脚本。 ASP 标记:<% php 代码 %> 短标记:<? Php代码 ?>

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

image-20220119150858480

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

PHP注释

习惯:所有的代码在写的过程中都必须进行注释,对于初学者而言,注释就是个人学习和写代码的一个思路说明。

PHP中注释分为两种:行注释和块注释。

行注释:一次注释一行。

//:后面跟的所有内容都是注释。

#:与//一样。

块注释:一次注释多行。

/*:中间直到 */ 出现之前,全部都是注释。

*/

PHP语句分隔符

语句分隔符:在PHP中,代码是以行为单位,系统需要通过判断行的结束,该结束通常都是一个符号:分号“;”(英文状态下的分号)。

特殊说明: 1.PHP 中标记结束符 ?>有自带语句结束符的效果,最后一行 PHP代码可以没有语句结束符“;”。

2.PHP中其实很多代码的书写并不是嵌入到HTML中,而是单独存在,通常书写习惯中就不建议使用标记结束符 ?>,PHP 会自动从开始到最后全部认为是PHP 代码,从而解析。

变量

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

变量基本概念

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

1.变量是用来存储数据的;

2.变量是存在名字的;

3.变量是通过名字来访问的:数据;

4.变量是可以改变的:数据;

变量的使用

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

2.赋值:可以将数据赋值给变量名(可以在定义的同时完成)

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

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

image-20220119190424980

变量命名规则

  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’

变量传值

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

变量传值一共有两种方式:值传递,引用传递

值传递:将变量保存的值赋值一份,然后将新的值给另外一个变量保存(两个变量没有关系)

image-20220119192720376

引用传递:将变量保存的值所在的内存地址,传递给另外一个变量:两个变量指向同一块内存空间(两个变量是同一个值)

1
2
//$新变量=&$老变量
$a=&$b

image-20220119192910519

在内存中,通常有以下几个分区:

栈区:程序可以操作的内存部分(不存数据,运行程序代码),少但是快

代码段:存储程序的内存部分(不执行)。

数据段:存储普通数据(全局区和静态区)。

堆区:存储复杂数据,大但是效率低。

常量

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

常量基本概念

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

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

常量定义形式

在 PHP 中常量有两种定义方式(5.3之后才有两种)。

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

常量名字的命名规则:

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



注意细节:

1. Define 和const定义的常量是有区别:在于访问权限区别

2. 定义常量通常不区分大小写,但是可以区分,可以参照 define 函数的第三个参数(参考文档)



#### 常量使用形式

常量的使用与变量一样:不可改变值(在定义的时候必须赋值)

有的时候还需要使用另外一种形式来访问(针对的是特殊名字的常量),需要用到另外一个访问常量的函数:constant("常量名“);

```php
//定义特殊常量
define('-_-','smile');
//const -_- = 'smile'; //错误
//使用常量
echo PI;
//echo -_-  //特殊符号不能直接使用
echo constant('-_-');

说明:常量和变量的使用:

  1. 凡是数据会可能变化的,那么肯定是用变量。
  2. 数据不一定会变的,可以使用常量或者变量(变量居多)
  3. 数据不允许被修改的,一定用常量

系统常量

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

PHP_YERSION:PHP 版本号

PHP_INT_SIZE:整形大小(表示整型所占用的字节数)

PHP_INT_MAX:整形能表示的最大值(整型中是允许出现负数:带符号)

在 PHP中还有一些特殊的常量,他们由下划线开始+常量名+下划线结束,这种常量称之为系统魔术常量:魔术常量的值通常会跟着环境变化,但是用户改变不了。

_DIR__:当前被执行的脚本所在电脑的绝对路径

_FILE__:当前被执行的脚本所在的电脑的绝对路径(带自己文件的名字)

_LINE__:当前所属的行数。

_NAMESPACE__:当前所属的命名空间。

_CLASS__:当前所属的类

_METHOD__:当前所属的方法

数据类型

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

PHP的八种数据类型

在 PHP 中将数据分为三大类八小类:

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

1
2
3
4
5
6
7
1. 整型:int/integer,系统分配4个宇节存储,表示整数类型(有前提)。

2. 浮点型:float/double,系统分配8个字节存储,表示小数或者整型存不下的整数。

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

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

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

1
2
3
1. 对象类型:object,存放对象(面向对象)。

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

特殊数据类型:2个小类:

1
2
3
1. 资源类型:resource,存放资源数据(PHP外部数据,如数据库、文件)。

2. 空类型:NULL,只有一个值就是NULL(不能运算)。

类型转换

类型转换:在很多的条件下,需要指定的数据类型,需要外部数据(当前PHP取得的数据),转换成目标数据类型。

在 PHP 中有两种类型转换方式:

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

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

其他类型转布尔类型:true或者 false,在 PHP 中比较少类型换变成 false

image-20220119201655626

其他类型转数值的说明:

  1. 布尔true为1,false为0;
  2. 字符串转数值有自己的规则

    2_1. 以字母开头的字符串,永远为 0; 2_2. 以数字开头的字符串,取到碰到字符串为止(不会同时包含两个小数点)。

类型判断

通过一组类型判断函数,来判断变量,最终返回这个变量所保存数据的数据类型(相同结果为 true,失败为 false):是一组以 is_开头后面跟类型名字的函数:is_XXX(变量名)

Bool 类型不能用 echo 来查看,可以使用var_dump结构查看

Var dump(变量 1,变量 2…)

1
2
3
4
$a = '123asdf';
//判断数据类型
var_dump(is_int($a));	//false
var_dump(is_string($a));	//true

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

Gettype(变量名):获取类型,得到的是该类型对应的字符串。

Settype(变量名,类型):设定数据类型:与强制转换不同。

  1. .强制转换(类型)变量名,是对数据值复制的内容进行处理(不会处理实际存储的内容)。
  2. settype 会直接改变数据本身。

    1
    2
    3
    4
    5
    6
    7
    
    $a = 'sad123';
    //强制转换
    echo (float)$a;
    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输出数值都会自动转换成10进制输出
echo $a,$b,$c,$d;//输出分别为110_6_72_272

PHP中不需要用户这么复杂的去计算,提供了很多的函数进行转换

Decbin():十进制转二进制。

Decoct():十进制转八进制。

Dechex():十进制转十六进制。

Bindec()::二进制转十进制。

1
2
//利用进制函数运算
var_dump(decbin(10));	//得到1010

浮点类型

浮点型:小数类型以及超过整型所能存储范围的整数(不保证精度),精度范围大概在15个有效数字左右

浮点型定义有两种方式: $f = 1.23;

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

尽量不用用浮点数做精确判断:浮点数保存的数据不够精确,而且在计算机中凡是小数基本上存的都不准确。

布尔类型

布尔类型:两个值 true 和 false,通常是用于判断比较。

在进行某些数据判断的时候,需要特别注意类型转换。 Empty():判断数据的值是否为“空”,不是NULL,如果为空返回true,不为空返回falses

Isset():判断数据存储的变量本身是否存在,存在变量返回 true,不存在返回 false

运算符

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

赋值运算符

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

算术运算符

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

+:执行数据累加。

-:数据相减。

*:键盘上没有乘法符号,使用 * 代替,两个数相乘。

/:正斜杠代替,表示两个数相除。

%:取余(模)运算,两个数(整数)相除,保留余数。

在进行除法运算或者取余运算的时候,对应的被除数(第二个数)不能为 0。

比较运算符

比较运算:比较两个数据的大小,或者两个内容是否相同,返回的结果都是布尔类型:满足返回 true,不满足返回 false

  • ,>:左边大于右边,返回结果true
  • ,>=:左边大于等于右边。
  • <:左边小于右边
  • <=:左边小于或者等于右边。
  • ==:左边的与右边的相同(大小相同)。
  • !=:左边的与右边的不同(大小不同)。
  • ===:全等于, 左边与右边相同:大小以及数据的类型都要相同
  • !==:不全等于,只有大小或者类型不同。

逻辑运算符

逻辑运算:针对不同的结果进行匹配。满足条件返回 true,不满足返回 false

&&:逻辑与,左边的条件与右边的条件同时成立(两边结果都为 true)。

  :逻辑或,左边的条件或者右边的条件只要有一个满足即可。

!:逻辑非,对已有条件进行取反,本身为 true,取反结果就是 false

1
2
3
4
5
6
7
8
9
$a = '123';
$b = '456';
//逻辑与
var_dump($a == '123' && $b == '45');//返回bool(false)
//逻辑或
var_dump($a == '123' || $b == '456');//返回bool(true)
//逻辑非
var_dump($b == '456');//返回bool(true)
var_dump(!($b == '456'));//返回bool(false)

逻辑与和逻辑或又称之为短路运算:如果第一个表达式结果已经满足条件了,那么就不会运行逻辑运算符后面的表达式:在书写代码的时候,尽量将出现概率最高的(能够直接判断出结果)的表达式放到第一位。

连接运算符

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

. :将两个字符串连接到一起。

.= :复合运算,将左边的内容与右边的内容连接起来,然后重新赋值给左边变量。

A .= b == A=A . b

1
2
3
4
5
6
$a = 'hello ';
$b = 123;
echo $a . $b;//将a变量和b变量连接起来 //得到hello 123

$a .= $b; //等价于$a = $a . $b
echo $a; //得到hello 123

错误抑制符

在 PHP 中有一些错误可以提前预知,但是这些错误可能无法避免,但是又不希望报错给用户看,可以使用错误抑制符处理。 @:在可能出错的表达式前面使用@符号即可。

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;//得到$b的值为0

三木运算可以进行复合三木运算:三木运算中的表达式2和3都是可以是另外一个三目运算。

表达式1 ? (表达式2 ? 表达式4 : 表达式5) : (表达式3 ? 表达式5 : 表达式6);

自操作运算符

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

++:在原来的值上+1

–:在原来的值上-1。

在 PHP中自操作符是可以放到变量前或者后:前置自操作和后置自操作。

前置或者后置如果本身只有自操作,不参与其他运算(自操作同时),那么效果是一样的。但是如果自操作同时还参与别的运算,那么效果就不一样。

后置自操作:先把自己所保存的值留下来,然后改变自己,自己给别人的值是原来的值。

前置自操作:先把自己改变,然后把改变后的值给别人。

$a = $b = 1;

$a++;	++$b;//独立运算,不参与其他运算
echo $a,$b;//输出	2,2

$a = $b = 1;
echo $a++,++$b;//不只是独立运算,还参与了输出操作
//得到的结果为 1,2

衍生符号:类似自操作。

+=:左边的结果与右边结果相加,然后赋值给左边。

-=:左边的减去右边的结果,然后复制给左边。

*=:乘法操作。

/=:除法操作。

%=:模操作

注意:右边是一个整体 $a += $b; == $a = $a + ($b);

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

如果进行除法或者取余运算,那么要考虑右边表达式的结果是否为 0(为 0 出错)

位运算符

计算机码

计算机码:计算机在实际存储数据的时候,采用的编码规则(二进制规则)。

计算机码:原码、反码和补码,数值本身最左边一位是用来充当符号位:正数为 0,负数为1

原码:数据本身从十进制转换成二进制得到的结果。

1
2
3
正数:左边符号位为0(正数的原码、反码和补码就是原码本身)。

负数:左边符号位为 1

反码:针对负数,符号位不变,其他位取反。

补码:针对负数,反码+1

系统中存在两个0:+0 和 -0

+0:00000000

-0:10000000 //原码

取反: 11111111

补码 :00000000

位运算

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

&:按位与,两个位都为1,结果为1,否则为 0 。

:按位或,两个有一个为1,结果为1 。

~:按位非,二个位如果为1则变成0,否则反之。

^;按位异或,两个相同则为O,不同则为 1 。

«:按位左移,整个位(32位),向左移动一位,右边补 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的操作。

4.按位右移:除以 2 的操作(不完全正确):整数除 2 会出现小数。

运算符优先级

运算符优先级:在多种运算符同时存在的时候,如何结合运算。

image-20220120163828606

流程控制

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

控制分类

顺序结构:代码从上往下,顺序执行。(代码执行的最基本结构);

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

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

顺序结构

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

分支结构

在 PHP 中,分支结构主要有两种:if 分支和 switch 分支。

If分支

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

基本语法:if 分支 PHP 也提供多种方式来实现。

最简if:只有一段代码,但是可以选择是否执行。

1
2
3
if(条件表达式){
//满足条件所要执行的内容 //顺序结构
}

基础if:有两面性,满足条件或者不满足条件都有对应的执行代码。

1
2
3
4
5
if(条件表达式){
//满足条件后执行的代码段;
}else{
//不满足条件执行的代码段;
}

复杂 if 结构:在判断条件之后,通常就有两种结果:满足或者不满足,在不满足之后还可以再次进行条件判断

1
2
3
4
5
6
7
8
9
if(条件表达式 1){
//满足条件表达式 1 的代码段:
}else if(条件表达式2){
//不满足表达式1条件,但是满足表达式 2 的代码;
}...
//可以使用多个else if来进行再次条件筛选
else{
//全部不满足要执行的代码
}

注意:如果条件特别多才会采用复合if形式。

1.如果条件比较单—(同一个条件),会采用 else if复合方式。 2.如果判断条件不一致,建议使用嵌套语法(不宜有太多层嵌套:影响代码美观)。

If 分支,适用于所有的条件判断(分支结构)。

Switch分支

Switch 分支:有一组情形存在,同过一条件,通常有多个值,但是每一个值都会有对应不同的代码要执行。

Switch 判断方式:是将条件放到分支结构内部判断。

Switch 基本语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
switch(条件表达式){	//所有条件判断:逐个进行
	case 值1://当前条件表达式的结果与值 1相等==)。
		//要执行的代码段;
		break;
/*
	在 switch 中,如果条件匹配成功,那么系统就不会再
	次匹配条件,会自动顺序执行向下的所有代码(case 代码	除外),需要中断执行:break 表示中断 switch(结		束)。
*/
	case 值2
		//要执行的代码段;
		break;
	...
	//可以使用类似 else 的语法:都不匹配
	default:
		//匹配失败时的代码;
		break;
}
选择

If和switch的选择

  1. if 能做所有的分支结构事情。
  2. switch 处理的是条件比较多,同时比较单一,而且是固定值匹配的分支结构。
循环结构

循环结构:代码段在一定的控制下,可以多次执行。

在 PHP 中循环结构有以下几种:

For 循环:通过条件、起始和终止判断执行。

While 循环:通过判断条件终止。

Do-while 循环:跟 while 差不多。

Foreach 循环:专门针对数组。

For循环

For 循环基本语法:

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

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

For 循环执行原理:

  1. 执行条件表达式 1:定义初始化条件(执行一次)。
  2. 执行条件表达式 2:判断条件(N次)。

    2_1. 满足条件:执行循环体。 2_2. 不满足条件:循环结束。

  3. 执行循环体:(N次)。
  4. 执行条件表达式 3:循环变量变化(N次)。
  5. 执行条件表达式 2:判断条件(N次)。
  6. 重复执行 3-4-2 步骤:直到第2步不满足条件结束循环。
While循环

while 循环基本语法:

条件初始化; while(条件表达式){ //条件表达式就是判断边界条件。 循环体; //循环条件的变化。 }

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

do-while:看着很像while,while 首先进行条件判定然后执行循环体,有可能出现第一次就条件不满足,那么就会直接失败(循环体一次都不执行)。Do-while 就是先运行一次(执行 循环体),后判断条件。(至少会执行一次循环体)。

do while 基本语法

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

For 与 while 的选择

  1. 如果是基于固定已知条件(数值而且是有规律的变化),使用 for 循环。
  2. while 可以做灵活的条件判定(while 使用的比较多)。
循环控制

循环控制:在循环内部对循环本身进行控制。

中断控制:重新开始循环,循环体中还有其他内容,也再执行。

  • Continue层级://默认是1(循环可以多层嵌套)

终止控制:循环直接结束。

  • Break 层级://默认是 1
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 />';
}

流程控制替代语法

流程控制替代语法:分支和循环结构的替代语法。

PHP 本身是嵌入到HTML中的脚本语言,需要在HTML中书写一些关于判断或者循环的结构语法,必须符合PHP标签规范,需要HTML与PHP进行混搭,如果使用原始的PHP代码那么会非常不美观。

需求:打印一个九九乘法表,使用表格来展示

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

在 PHP 书写到 HTML 中的这些大括号{}非常不美观,所以PHP提 供—种替代机制,让其可以不用书写大括号:

for( ; ; ){ == for( ; ; ): —— } == endfor;

<?php	for($i = 1; $i < 5; $i++):	?>
<!-- html -->
<?php	endfor;	?>

PHP应该在HTML中只做数据输出,输出通常伴有条件判断和循环操作,因此 PHP 提供了对应分支结构和循环结构的替代语法:全部都是对应的一个模式:

左大括号 { 使用冒号替代 :

右大括号 } 使用 end+对应的起始标记替代

1
2
3
4
5
/*if*/	if():	endif;
/*switch*/	switch():	endswitch;
/*for*/
/*while*/
/*foreach*/

文件包含

文件包含:在一个 PHP 脚本中,去将另外一个文件(PHP)包含 含进来,去合作完成一件事情。

文件包含的作用

文件包含的意义:

  1. 要么使用被包含文件中的内容,实现代码的共享(重用):向上包含(素要)。

    向上包含:在当前脚本要用某个代码之前包含别的文件。

  2. 要么自己有东西可以给别的文件使用,实现代码的共享(重用):向下包含(给予)。

    向下包含:在自己有某个东西的时候,需要别的脚本来显示(自己代码写完之后包含其他文件)。

  3. 最大的作用:分工协作,每个脚本做的事情不一样,因此可以使用协作方式,让多个脚本共同完成一件事情。

文件包含四种形式

在 PHP 中文件的包含有四种形式(两种大形式)。

Include:包含文件。

Include_once:系统会自动判断文件包含过程中,是否已经包含过(一个文件最多被包含一次) 。

Require:与 include 相同

Require_once:以include_once 相同。

包含基本语法: Include ‘文件名字’; Include(‘文件名字’); //文件名字:有路径问题

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

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";
?>
<!-- 文件4	//include4.php -->
<table>
    <tr><td> <?php echo $a; ?> </td></tr>
    <tr><td> <?php echo PI; ?> </td></tr>
</table>

文件加载原理

PHP 代码的执行流程:

  1. 读取代码文件(PHP 程序)
  2. 编译:将 PHP 代码转换成字节码(生成opcode)
  3. zendengine 来解析 opcode,按照字节码去进行逻辑运算。
  4. 换成对应的 HTML 代码

文件加载原理:

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

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

Include和require区别

Include和include_once的区别:

1
2
3
4
5
//文件1	//include1.php
<?php
    $a = 10;
	define('PI',3.14);
?>

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

1
2
3
4
5
6
7
8
//文件2	//include2.php
<?php
    echo "hello";//正常执行
	include "include1.php";//正常执行
	echo $a;//正常执行
	//再次包含
	include "include1.php";//报错,变量不可重复定义
?>

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

1
2
3
4
5
6
7
8
//文件2	//include3.php
<?php
    echo "hello";//正常执行
	include "include1.php";//正常执行
	echo $a;//正常执行
	//再次包含
	include_once "include1.php";//已包含,不在执行
?>

require 和 include 的区别:本质都是包含文件,唯一 一的时候,报错的形式不一样。

Include 的错误级别比较轻:不会阻止代码执行。

image-20220122193045252

Reequire 要求较高:如果包含出错代码不再执行(require后面的代码)

image-20220122193441945

文件加载路径

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

文件的加载路径包含两大类:

  1. 绝对路径

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

    Windows:盘符 C:/路径/PHP 文件。

    Linux:/路径/PHP文件。

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

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

    Localhost/index.php -> E:/server/apache/htdocs/index.php

  2. 相对路径:从当前文件所在目录开始的路径,

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

绝对路径和相对路径的加载区别

  1. 绝对路径相对效率偏低,但是相对安全(路径不会出问题)。
  2. 相对路径相对效率高些,但是容易出错(相对路径会发生改变)
1
2
3
4
5
6
7
8
9
10
11
<?php
	//PHP文件加载路径
	//相对路径加载
	include_once 'include1.php';//默认当前文件本身
    include_once "./include1.php";
	//复杂相对路径
	include_once "../htdocs/include1.php";

	//绝对路径
	include_once "D:/sever/apache/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
?>

嵌套包含的时候就很容易出现相对路径出错的问题:相对路径会因为文件的包含而改变( / 和 ../ ):windows 下,每一个文件夹下都有 . 和 .. 的文件夹。

函数

函数的基本概念

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

函数定义语法

函数有几个对应的关键点:function 关键字、函数名、参数(形参和实参)、函数体和返回值

基本语法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
    /*Function 函数名 ([参数]){
		//函数体
		//返回值:return 结果;
	  }*/
  
    //也可以在这里(函数定义之前)调用函数
    dispaly();

    //定义函数
    function dispaly(){
    	//函数体
    	echo "hello";
    	//没有返回值
	}

	//调用函数
	dispaly();
?>
  • 函数的使用:通过访问函数的名字+();
  • 如果函数在定义的过程中有参数,那么在调用的时候就必须传入对应的参数:函数是一种结构不会自动运行,必须通过调用才会执行。
  • 函数是在代码执行阶段,碰到函数名字的时候才会调用,不是在编译阶段。
  • 函数的调用特点:只要系统在内存中能够找到对应的函数,就可以执行(函数的调用可以在函数定义之前)。

函数执行的内存分析:

  1. 读取代码进入到代码段(编译:将代码编程字节码存储到内存)。
  2. 根据代码进行执行。
  3. 以上原因:编译和执行是分开的(先编译后执行)。

函数命名规范

命名规范:由字母,数字和下划线组成,但是不能以数字开头。

函数作为一种常用的结构,一般遵循以下规则:函数通常名字代表看函数的功能,而有些功能会比较复杂,可能一个单词不足以表单,需要多个组合。

  1. 驼峰法:除了左边第一个单词外,后面所有的单词首字母者大写:showParentlnfoll
  2. 下划线法:单词之间通过下划线连接,单词程是小写:Show_porent.infoll)

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

函数的参数

参数详解

函数的参数分为两种:形参和实参。·形参·

形参

形参:形式参数,不具有实际意义的参数,是在必数定义时使用的参数。

实参

实参:实际参数,具有实际数据意义的参数,是在函数调用时使用的参数。

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

注意:

  1. 在PHP中允许实参多余形参(个数):函数内部不用而已。
  2. 在PHP中理论上形参个数没有限制(实际开发不会太多)。
  3. 实参不能少于形参个数。
默认值

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

通常默认值是用在一些,一定会有某个数据参与,但是可能通常是某个我们知道的值。

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

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

注意事项:

  1. 默认值的定义是放在最后边的(多个),不能左边形参有默认值,但是右边没有。
  2. 函数外部定义的变量名字与函数定义的形参名字冲突(同名)是没有任何关联关系的,如果多个函数使用同样的形参名字也不冲突。
引用传递

实参在调用时会将值赋值给形参,那么实际上使用的方式就是一种简单的值传递:将实参(如果是变量或者常量或者其他表达式)的结果(值)取出来赋值给形参:形参与外部实际传入的参数本身没有任何关联关系;只是结果一样。

有的时候,希望在函数内部拿到的外部数据,能够在函数内部改变,那么就需要明确告知函数(定义时),函数才会在调用的时候去主动获取外部数据的内存地址。以上这种定义形式参数的方式叫作引用传值。

基本定义语法:

&:取地址符:指向的数据的内存地址

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改变自己的同时也改变了外部
*/

引用传值注意事项:在传入实参的时候,必须传入变量。

函数体

函数体:函数内部(大括号{}里面)的所有代码都称之为函数体。

函数体:基本上所有的代码都可以实现。

  1. 定义变量
  2. 定义常量
  3. 使用流程控制(分支、循环)。
  4. 可以调用函数。

函数返回值

返回值:return,指的是将函数实现的结果,通过 return关键字,返回给函数外部(函数调用处)。在PHP中所有的函数都有返回值。(如果没有明确return使用,那么系统默认返回NULL)

返回值作用:将计算结果返回给调用处:

image-20220122211657823

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

Return关键字:

  1. return在函数内部存在的价值:返回当前函数的结果(当前函数运行结束)。

image-20220122212030835

  1. return 还可以在文件中直接使用(不在函数里面):代表文件将结果 return 后面跟的内容,转交给包含当前文件的位置。(通常在系统配置文件中使用较多),在文件中也代表中终

    止文件后面的代码:return之后的内容不会执行。

  2. image-20220122212725313

作用域

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

  1. 变量可以在普通代码中定义。
  2. 变量也可以在函数内部定义。

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

  1. 全局变量:就是用户普通定义的变量(函数外部定义)

    • 所属全局空间:在 PHP 中只允许在全局空间使用:理论上函数内部不可使用。
    • 脚本周期:直到脚本运行结束(最后一行代码执行完)。
    • image-20220122214222524
  2. 局部变量:就是在函数内部定义的变量。

    • 所属当前函数空间:在 PHP 中只允许在当前函数自己内部使用。
    • 函数周期:函数执行结束(函数是在栈区中开辟独立内存空间运行)。
    • image-20220122214428317
  3. 超全局变量:系统定义的变量(预定义变量:$_SERVER、S_POST等)

    • 所属超全局空间:没有访问限制(函数内外都可以访问)
    • 超全局变量会将全局变量自动纳入到$GLOBALS 里面,而$GLOBALS 没有作用城限制,所以能够帮助局部去访问全局变量:但是必须使用数组方式。
    • image-20220122215011845
    • image-20220122215320562

如果想函数内部使用外部变量:除了$GLOBALS 之外,还可以通过参数传值(如果要统一战线还可以使用引用传值)。

在 PHP 中,其实还有一种方式,能够实现全局访问局部,同时局部也可以访问全局:global 关键字。 Global 关键字:是一种在函数里面定义变量的一种方式。

  1. 如果使用 global 定义的变量名在外部存在(全局变量),那么系统在函数内部定义的变量直接指向外部全局变量所指向的内存空间(同一个变量);
  2. 如果使用 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
3
4
  function 函数名(){
    //定义变量
    static $变量名 = ;//通常会在定义的时候就直接赋值
}

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

image-20220122221752626

静态变量的使用:

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

可变函数

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

1
2
3
4
5
6
$变量 = "display";

function display(){
	//可变函数
    $变量();
}

image-20220122222640027

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

image-20220122223050266

匿名函数

基本概念

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

基本语法:

1
2
3
变量名 = function(){
	//函数体。
}; 

image-20220122223454813

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

image-20220122223608545

闭包

闭包:closure,一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域):

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

image-20220122224256874

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

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

image-20220122224659290

伪类型

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

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

Mixed:混合的,可以是多种 PHP 中的数据类型。

Number:数值的,可以是任意数值类型(整形和浮点型)。 image-20220122225144593

常用系统函数

有关输出的函数

处理脚本让浏览器按照指定字符集解析的方法:

  • header(‘Content-type:text/html;charset=utf-8’) ;
    • Content-type:text/html:表明为超文本语言。
    • charset=utf-8:表示以 utf-8 来解析。

print():类似于 echo 输出提供的内容,本质是一种结构(不是函数),返回 1,可以不需要使用括号

print_r():类似于 var_dump,但是比 var_dump简单,不会输出数据的类型,只会输出值(数组打印使用比较多)。

image-20220123152941816

有关时间的函数

dated:按照指定格式对对应的时间戳(从 1970 年格林威治时间开始计算的利数),如果没有指定特定的时间戳,那么就是默认解释当前时间戳。

time():获取当前时间对应的时间戳。

microtime():获取微秒级别的时间。

strtotime():按照规定格式的字符串转换成时间戳。

image-20220123170113659

有关数学的函数

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():获取当前自定义函数的参数数量。

image-20220123172234340

错误处理

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

错误分类

  1. 语法错误:用户书写的代码不符合PHP的语法规范,语法错误会导致代码在编译过程中不通过,所以代码不会执行(Parse error)。
  2. 运行时错误:代码编译通过,但是代码在执行的过程中会出现一些条件不满足导致的错误(runtime error)。
  3. 逻辑错误:程序员在写代码的时候不够规范,出现了一些逻辑性的错误,导致代码正常执行,但是得不到想要的结果。

    1
    2
    3
    4
    
    $a = 10;
    if($a = 1){//最常见把比较符号写成赋值符号。
    	//执行代码
    }
    

错误代号

所有看到的错误代码在 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

错误触发

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

image-20220123194505244

人为触发:知道某些逻辑可能会出错,从而使用对应的判断代码来触发响应的错误提示。

Trigger_error(错误提示);

image-20220123195249237

可以通过第二个参数进行严格性控制。

image-20220123195357201

错误显示设置

错误显示设置:

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

在 PHP 中,其实有两种方式来设置当前脚本的错误处理。

  1. PHP的配置文件:全局配置:php.ini文件

    • Display_errors:是否显示错误。
    • Error_reporting: 显示什么级别的错误。
    • image-20220123200341000
  2. 可以在运行的 PHP 脚本中去设置:在脚本中定义的配置项级别比配置文件高(通常在开发当中都会在代码中去进行控制和配置)。

    • error_reporting():设置对应的错误显示级别。
    • ini_set(“配置文件中的配置项“,配置值)。
    • ini_set(‘‘error_reporting”,E__ALL);
    • ini_set(“display_errors”,1);

错误日志设置

在实际生产环境中,不会直接让错误赤裸裸的展示给用户:

  1. 不友好
  2. 不安全:错误会暴露网站很多信息(路径、文件名)。

所以在生产环境中,一般不显示错误(错误也比较少),但是不可能避免会出现错误(测试的时候不会发现所有的问题),这个时候不希望看到,但是又希望捕捉到可以让后台程序员去修改:需要保存到日志文件中,需要在 PHP 配置文件中或者代码中(ini_set)设置对应error_log配置项。

  1. 开启日志功能

    • image-20220123201440520
  2. 指定路径

    • image-20220123201720775

自定义错误处理

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

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

  1. 如何将用户自定义的函数放到系统中:set_error_handler()

    • image-20220123202333327
  2. 自定义错误处理函数,系统有要求。

    • 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

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

字符串

字符串定义语法

  1. 单引号字符串:使用单引号包裹。
  2. 双引号字符串:使用双引号包裹。
  3. image-20220123210328294

    • 引号方式:比较适合定义那些比较短(不超过一行)或者没有结构要求的字符串。
    • 如果有结构要求,或者内容超过一行,可以使用以下两种结构定义。
  4. nowdoc字符串:没有单引号的单引号字符串。

    • $str = «<’边界符’ //字符串内容。 边界符;
  5. heredoc字符串:没有双引号的双引号字符串。

    • $str = «<边界符。 //字符串内容 边界符;

image-20220123210620988

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

image-20220123211103379

字符串转义

转义的含义:在计算机通用协议中,有一些特定的方式定义的字母,系统会特定处理:通常这种方式都是使用反斜杠+字母(单词)来表示。

PHP在识别转义字符的时候也是使用同样的模式:反斜杠+字母。 在 PHP 中系统常用的转义符号:

  • \‘:在单引号字符串中显示单引号。
  • \“:在双引号字符串中显示双引号。
  • \r:代表回车(理论上是回到当前行的首位置)。
  • \n:代表新一行。
  • \t:类似 tap 键,输出4个空格
  • \$:在PHP中使用$符号作为变量符号,因此需要特定识别

单引号和双引号的区别:

  1. 其中单引号中能够识别\‘,而双引号中就不能识别\‘。

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

    • image-20220123214008395

双引号中变量识别的规则:

  1. 变量本身系统能够与后面的内容区分:应该保证变量的独立性,不要让系统难以区分。

    • image-20220123214049607
  2. 使用变量专业标识符(区分),给变量加上一组大括号{};

    • image-20220123214236432

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

  1. 结构化定义字符串对应的边界符有条件:
  2. 上边界符后面不能跟任何内容;
  3. 下边界符必须顶格:最左边;
  4. 下边界同样后面只能跟分号,不能跟任何内容;
  5. 结构化定义字符串的内部(边界符之间)的所有内容都是字符串本身。
    • image-20220123215145582

字符串长度问题

  1. 基本函数 strlen():得到字符串的长度(字节为单位)
  2. 多字节字符串的长度问题:包含中文的长度。
  3. 多字节字符串扩展模块:mbstring扩展(mb: Multi Bytes):

    • 首先需要加载 PHP的mbstring扩展。

      • image-20220124193745363
    • 可以使用 mb 扩展带来很多函数
    • Mbstring 扩展针对的是一些关于字符的统计:strlen 只是针对标准交换码 ASCII,mbstring 会针对不同的字符集

      • image-20220124193952759
  4. //定义字符串 $str1 = “abc12346”; $str2 = “你好中国123”;//中文在utf8字符集下占3个字节

    echo strlen($str1);//得到 9 echo strlen($str2);//得到 15 echo mb_strlen($str2);//得到 15 echo mb_strlen($sre2,”utf-8”);//得到 7

字符串相关函数

  1. 转换函数:implode(), explode(), str_split()

    • implode(连接方式,数组):将数组中的元素按照某个规则连接成一个字符串。
    • Explode(分割字符,目标字符串):将字符串按照某个格式进行分割,变成数组。
      • 中国 北京 顺义 == array(“中国,北京”顺义);
    • Str_split(字符串,字符长度):按照指定长度拆分字符串得到数组。
  2. 截取函数:trim(), ltrim(), rtrim()

    • Trim(字符串[,指定字符]):本身默认是用来去除两边的空格(中间不行),但是也可以指定要去除的内容,是按照指定的内容循环去除两边有的内容:直到碰到一个不是目标字符为止。
    • Ltrim():去除左边的。
    • Rtrim():去除右边的。

    $str = “ abc d e “;//10个字符

    var_dump(trim($str)); //得到 string(7)”abc d e” ,去除了三个空格

  3. 截取函数:substr(), strstr()

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

    $str = “abcdefg”;

    //字符串截取 echo substr($str,0,3);//得到 abc,从第0个到第3个字符 echo strstr($str,”c”);//得到 cdefg,从 c 开始到最后

  4. 大小转换函数:strtolower(),strtoupper(), ucfirst()

    • Strtolower:全部小写。
    • Strtoupper:全部大写。
    • Ucfirst:首字母大写。

    $str = “abc”; echo strtoupper($str);//得到 ABC echo ucfirst($str);//得到 Abc

  5. 查找函数:strpos(), strrpos()

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

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

    • Printf/sprintf(输出字符串有占位符,顺序占位内容..):格式化输出数据。
    • 1
      2
      3
      4
      5
      
        $age = 10;
        $name = "tom";
        //格式化输出
        echo printf("我叫%s,我%d岁了",$name,$age);
        //得到 我叫tom,我10岁了
      
  8. 其他:str_repeat(), str_shuffle()

    • Str_repeat():重复某个字符串N次。
    • Str_shuffle():随机打乱字符串。
    • 1
      2
      3
      
        $str = "abcd";
        echo str_repeat($str,2);//得到 abcdabcd
        echo str_shuffle($str);//得到一个打乱了的字符串
      

数组

数组的概念

数组:array,数据的组合,指将一组数据(多个)存储到一个指定的容器中,用变量指向该容器,然后可以通过变量一次性得到该容器中的所有数据。

数组定义语法

在 PHP 中系统提供多种定义数组的方式:

  1. 使用array关键字:最常用的
1
$变量 = array(元素 1,元素 2,元素 3);
  • image-20220124202727304
  1. 可以使用中括号来包裹数据:
1
$变量 = [元素 1,元素2] 
  • image-20220124202820101
  1. 隐形定义数组:给变量增加一个中括号,系统自动变成数组。
1
2
3
$变量[] = 值1://如果不提供下标也可以系统自动生成数字 0 开始
$变量[下标] = ;//该下标可以是字母(单词)或者数
	与变量命名的规则相似
  • image-20220124202947455

PHP数组特点

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

    • 如果数组下标都为整数:索引数组。
    • 如果数组下标都为字符串:关联数组。
  2. 不同下标可以混合存在:混合数组。
  3. 数组元素的顺序以放入顺序为准,跟下标无关。

    • image-20220124203100250
  4. 数字下标的自增长特性:从0开始自动增长,如果中间手动出现较大的,那么后面的自增长元素从最大的值+1开始。
  5. 特殊值下标的自动转换。

    • 布尔值:true 和 false
    • 空:NULL
    • image-20220124205150037
  6. PHP中数组元素没有类型限制。
  7. PHP中数组元素没有长度限制。
  8. 补充:PHP中的数组是很大的数据,所以存储位置是堆区,为当前数组分配一块连续的内存。

多维数组

多维数组:数组里面的元素又是数组

二维数组

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

image-20220124210551281

多维数组

在第二维中的数组元素也可以继续是数组,在 PHP 中没有维度限制(PHP 本质并没有二维数组)

但是:不建议使用超过三维以上的数组,会增加访问的复杂度,降低访问效率。

异形数组(不规则数组)

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

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

数组遍历

遍历的基本含义

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

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 遍历语法

基本语法如下:

Foreach($数组变量 as [$下标 =>] $值){

1
//通过$下标访问元素的下标:通过$值访问元素的值。

}

通常:如果关联数组(字母下标),就需要下标,如果是数字下标就直接访问值。

image-20220124213058637

在进行数据存储定义的时候,通常二维数组不会两个维度的 key下标都为数字,一般是一维为数字(无意义),二维为字符串(数据库表字段),所以在进行遍历的时候,通常是只需要针对一维进行遍历,取得二维数组元素,然后二维数组元素通过下标去访问。

image-20220124213853569

Foreach 遍历原理

Foreach 遍历的原理:本质是数组的内部有一个指针,默认是指向数组元素的第一个元素。

foreach 就是利用指针去获取数据,同时移动指针。

1
2
3
foreach($arr as $key => $value){
	//循环体
}
  1. foreach 会重置指针:让指针指向第一个元素;
  2. 进入 foreach 循环:通过指针取得当前第一个元素,然后将下标取出放入对应的下标变量 $key 中(如果存在),将值取出来放入对应的值变量 $value 中;(指针下移)。
  3. 进入到循环内部(循环体),开始执行;
  4. 重复 2和 3,直到在 2 的时候遇到指针取不到内容(指针指向数组最后 ‘/0’)。
For 循环遍历

For 循环:基于已知边界条件(起始和结束)且有条件(规律)的变化。

因此:for 循环遍历数组有对应条件。

  1. 获取数组长度:count(数组) 得到数组元素的长度。
  2. 要求数组元素的下标是规律的数字。
  3. 1
    2
    3
    4
    5
    6
    
     $arr = array(1,2,3,4,5,6,7,10);
     //for 循环遍历
     for($i = 0,$len = count($arr);$i < $len;$i++){
         echo 'key: ',$i,", value: ",$arr[$i];
     }
    
while 遍历
while 自身遍历

While 是在外部定义边界条件,如果要实现可以与 for 循环相同。

While配合 each和 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

数组相关函数

排序函数

排序函数:对数组元素进行排序,都是按照ASCII 码进行比较,可以进行英文比较!

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

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

    • image-20220126151916972
  • ksort():顺序排序:按照键名(下标)。
  • krsort():逆序排序

    • image-20220126152034820
  • shuffle():随机打乱数组元素。
指针函数
  • reset():重置指针,将数组指针回到首位。
  • end():重置指针,将数组指针指到最后一个元素。
    • image-20220126153216584
  • next():指针下移,取得下一个元素的值。
  • prex():指针上移,取得上一个元素的值。
    • image-20220126153157775
  • current():获取当前指针对应的元素值。
  • key():获取当前指针对应的下标值。
    • image-20220126153014420

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

其他函数
  • count():统计数组中元素的数量
  • array_push():往数组中加入一个元素(数组后面)。
  • array_pop():从数组中取出一个元素(数组后面)。
  • array_shift():从数组中取出一个元素(数组前面)。
  • array_unshift0;从数组中加入一个元素(数组前面)。
  • PHP 模拟数据结构:

    • 栈:压栈,先进去后出来(FILO)。
    • 队列:排队,先进去的先出去(FIFO)。
  • array_reverse():将数组元素反过来
  • in_array():判断一个元素在数组中是否存在
  • array_keys():获取一个数组的所有下标,返回一个索引数组。
  • array_values():获取一个数组的所有值,返回一个索引数组。
This post is licensed under CC BY 4.0 by the author.