1.2 PHP简介

1.2.1 概述

PHP是Hypertext Preprocessor的缩写,(超文本预处理器)是一种在服务器端运行的开源的脚本语言。

LAMP组合(Linux,Apache,MySQL,PHP),这四个产品都是公开源代码的产品

php是一门语言,用来做业务逻辑

apache为PHP提供了运行环境

linux为Apache的运行提供了平台

mysql数据库用来存储数据

多学一招:什么是wamp组合

windows+apche+mysql+php

1.2.2 五个基本概念

1、静态页面和动态页面

静态页面:服务器不执行的页面

动态页面:服务器执行的页面

问题:动态网站中是否可以存放静态页面

答:可以

2、客户端和服务器端

浏览者这段是客户端

服务器端:给浏览者提供服务

3、端口和端口号 端口号的范围: 0-65535

4、BS架构和CS架构

BS:通过浏览器去访问服务器

b:browser(浏览器)

s:sever(服务器)

优点:

1、只要有浏览器就可以访问

2、开发低

缺点:

2、开发的代码都放在服务器上 胖服务器-瘦客户端

所有的web都是BS架构的

CS:通过客户端软件去访问服务器

c:client(客户端)

s:server(服务器)

优点:

1、可以开发客户端和服务器端,这时候就可以实现负载的均衡

缺点:

1、必须要安装一个软件才能去访问

2、开发成本高

例如:QQ、炒股软件

5、前台和后台

前台:浏览器看到的界面

后台:管理员看到的界面

1.2.3 PHP的优点

跨平台,既能在windows上运行,也能在linux上运行源码开放:不会涉及到版权问题语法简单:PHP入门简单运行在服务器端,只要在服务器部署环境就可以了。

1.3 Web介绍

1.3.1 web时代的变迁

从互联网开始崛起到现在,经历了从web1.0、2.0到web3.0的过程

Web1.0(信息共享)的主要特点在于用户单纯的获取信息

Web2.0(信息共建)更注重用户的交互作用,用户既是网站内容的浏览者,也是网站内容的制造者。

Web3.0(信息传承)通过第三方信息平台对多家网站的信息进行整合,用户在互联网上拥有自己的数据,并能在不同网站上使用

举例:

Web1.0:来到一个餐馆,老板给你上了一盘番茄炒蛋;

Web2.0:来到一个餐馆,你跟老板主动点了一份番茄炒蛋;

Web3.0:来到一个餐馆,老板见到你就问,老规矩,还要番茄炒蛋?

1.3.2 Web服务原理

静态网站原理(浏览器-服务器)

动态网站原理(浏览器-服务器-数据库)

智能网站原理(浏览器-服务器【分析推荐】-数据库)

1.4 搭建Web服务器

1.4.1 安装phpstudy

直接解压即可

1.4.2 目录结构

启动服务

1.4.3 访问服务器

在www目录下创建demo.php页面

phpinfo();

访问服务器

访问规则:http://服务器ip地址/php页面

比如:

http://localhost/demo.php

http://127.0.0.1/demo.php

1.4.4 常用的命令

补充DOS命令

切换盘符 盘符+冒号

进入目录 cd 目录地址

Apache的命令

httpd -v 查看apache版本号 version

httpd -t 检测运行环境 test

PHP的命令

php -v PHP版本号

1.4.5 互联网通讯原理

本质一台电脑访问另外一台电脑资源、寻址过程(IP地址、端口、域名、DNS)

在互联网上,IP地址是用来区分每台计算机的标识,但是IP记忆不友好,我们将IP地址取一个名字,一个IP对应一个名字,这个名字就称为域名。

访问过程:

步骤:

1、客户端输入域名(网址),在最近的机房做DNS解析(Domain Name Server),DNS解析就是将域名转化成IP地址

2、通过IP地址访问服务器

1.4.6 DNS解析

目标:ip地址访问服务器不方便,通过域名来访问。

hosts文件

测试

小结:

hosts文件用来做DNS解析

1.5 服务器配置

1.5.1 虚拟目录配置

1、更改虚拟目录

要更改虚拟目录的位置,需要到apache的配置文件中更改(conf/httpd.conf)

在phpstudy中,httpd.conf和vhost.conf都有配置虚拟目录的指令,并且两个配置文件中都有配置虚拟目录的指令,为了测试,我们注释掉vhost.conf的引入

更改虚拟目录

提醒:项目上线以后,不可以显示目录结构

权限的练习

例题一:

Order allow,deny

Allow from all

# 允许所有请求访问

例题二:

Order allow,deny

Allow from all

Deny from all

# 拒绝所有请求访问

练习三:

Order allow,deny

Deny from all

Allow from all

# 拒绝所有请求访问

练习四:

Order deny, allow

Allow from 192.168.101.50

Deny from 192.168

# 拒绝192.168开头,但除去(192.168.101.50)的IP的访问

练习五:

Order deny, allow

Allow from 192.168.101.50

Deny from all

# 只允许192.168.101.50访问

练习六:

Order allow,deny

Allow from 192.168

Deny from 192.168.101.50

# 只允许192.168开头的,但要去除192.168.101.50 的IP访问

2、更改默认首页

在httpd.conf配置文件中

默认首页的查找顺序,从前往后。

3、更改监听端口

在httpd.conf配置文件中设置

通过Listen指令设置监听的端口

可以设置多个监听端口

访问:

http://域名:端口号/demo.php

补充:查看端口的占用情况

在命令行下使用 netstat -ano查看

在结果中查找字符串

1.5.3 虚拟主机配置

需求:

输入www.baidu.com 打开web1的网站

输入www.sina.com打开web2的网站

配置过程:

要配置虚拟主机,需要在httpd.conf中引入虚拟主机的培训文件(vhosts.conf)

vhosts.conf配置如下

DocumentRoot "C:\web1" #指定虚拟目录路径

ServerName www.baidu.com # 虚拟目录绑定的域名

DirectoryIndex aa.php # 默认首页

Options -Indexes -FollowSymLinks +ExecCGI

AllowOverride All

Order allow,deny

Allow from all

Require all granted

DocumentRoot "C:\web2"

ServerName www.sina.com

DirectoryIndex bb.php

Options -Indexes -FollowSymLinks +ExecCGI

AllowOverride All

Order allow,deny

Allow from all

Require all granted

在host文件中做dns解析

访问结果

补充:站点、虚拟目录、虚拟主机的区别

站点:站点就是一个文件夹,用来保存与网站有关的所有素材

虚拟目录:站点+权限

虚拟主机:虚拟目录+域名

1.6 PHP语法入门

1.6.1 PHP是编译型语言

编译语言和解释语言的区别在于是否保存最终的可执行程序。

PHP执行过程

1.6.2 PHP定界符

因为PHP是脚本语言,所以需要定界符

1、标准风格(推荐使用)

?>

例题

echo 'i am a boy!';

?>

提醒,如果整个页面都是PHP代码,PHP结束符是可以省略的(推荐)

echo 'i am a boy!';

2、短标记风格(默认情况下不支持,需要在php配置文件中开启支持段标记)

?>

例题:

echo '锄禾日当午';

?>

小结:

httpd.conf是apache的配置文件

php.ini是php的配置文件

1.6.3 注释

单行注释: //和#

多行注释: /* */

1.6.4 PHP输出语句

echo:输出

print:输出,输出成功返回1

print_r():输出数组

var_dump():输出数据的详细信息,带有数据类型和数据长度

var_dump('abc'); //string(3) "abc"

?>

1.7 变量

变量的本质就是内存中的一段空间

1.7.1 变量的命名规则

变量必须以

开头,

开头,符不是变量的一部分,仅表示后面的标识符是变量名。除了$以外,以字母、下划线开头,后面跟着数字、字母、下划线变量名区分大小写,

a

a

aa和

aa和Aa是两个空间

下列变量是否合法

$a 合法

$a1 合法

$1a 不合法

$_1a 合法

注意:PHP语句必须以分号结尾

$a=10;

$name='Tom';

?>

1.7.2 可变变量

变量名可以变,将变量名存储在另外一个变量中

例题

$a=10;

$b='a';

echo $$b; //10

例题

$name1='tom';

$name2='berry';

if(rand(1,10)%2){

$name='name1'; //将变量名存储在$name中

}else{

$name='name2';

}

echo $$name;

小结:

1、rand(1,10):获取1-10的随机整数

1.7.3 变量传递

变量的传递有值传递和地址传递(引用传递)

//值传递

$num1=10; //将10付给$num1

$num2=$num1; //将$num1的值付给$num2

$num2=20; //更改$num2

echo $num1; //10

//地址传递

$num1=10; //将10付给$num1

$num2=&$num1; //将$num1的地址付给$num2

$num2=20; //更改$num2

echo $num1; //20

小结:

1、参数的传递有两种,值传递和地址传递

2、&表示获取变量的地址

3、值传递中,一个变量变了,另一个变量没有影响,因为是两个空间

4、地址传递中,一个变量变了,另一个也变了,因为两个变量指向同一个空间

1.7.4 销毁变量

用unset()来销毁变量,销毁的是变量名,变量值由PHP垃圾回收机制销毁

$num1=10;

$num2=&$num1;

unset($num1); //销毁的是变量名

echo $num2; //10

没有变量引用的值是垃圾。

1.8 作业

phpstudy安装完毕后,有一个phpmyadmin的管理数据库软件,默认情况下,放在虚拟目录下,这样不合理,请重新配置虚拟主机访问phpmyadmin

输入phpmyadmin.com打开phpmyadmin管理软件

1.2 常量

在整个运行过程中,固定不变的值

1.2.1 定义常量

1、用define()函数定义常量

define(常量名,值,[是否区别大小写]) true表示不区分大小写,默认是false

常量名前没有$符

常量名推荐使用大写

例题:

define('NAME','tom'); //定义常量

define('PI',3.14,true); //定义常量,不区分大小写

echo NAME,'
',Pi;

//true表示不区分大小写,默认是区分大小写的。

2、定义常量可以用特殊字符,但是在调用的时候必须用constant关键字调用

define('%-%','tom');

echo constant('%-%'); //通过constant获取特殊字符作为常量名的常量

3、判断常量是否定义,通过defined()判断常量是否已经定义

if(!defined('NAME')){

define('NAME','berry');

}

echo NAME; //berry

4、还可以使用const关键字定义常量

const NAME='tom';

echo NAME; //tom

小结:

1、定义常量有两种方式,define()和const

2、常量在整个运行过程中值保持不变,常量不能重新定义

3、使用constant获取特殊字符做的常量名的值

4、defined()用来判断常量是否被定义

1.2.2 预定义常量

PHP预先定义好的常量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KekuV6zj-1669803084213)(C:/Users/SUNJIANSONG/AppData/Roaming/Typora/typora-user-images/1559355891156.png)]

例题

echo PHP_VERSION,'
'; //PHP版本号

echo PHP_OS,'
'; //PHP操作系统

echo PHP_INT_MAX,'
'; //PHP中整型的最大值

1.2.3 魔术常量

魔术常量它们的值随着它们在代码中的位置改变而改变

echo __LINE__,'
'; //获取当前行号

echo __FILE__,'
'; //文件的完整路径和文件名

echo __DIR__,'
'; //文件所在的目录

1.3 数据类型

数据类型有两种:强类型和弱类型

PHP是弱类型

1.3.1 基本类型(标量类型)

1、整型

存整数,PHP_INT_MAX获取整形最大值

PHP支持8、10、16机制的整数

$num1=10; //十进制

$num2=010; //八进制(数字前面加0)

$num3=0x10; //十六进制(数字前面加0x)

echo $num1,'
'; //10

echo $num2,'
'; //8

echo $num3; //16

进制转换

机制缩写单词十进制decdecimalist二进制binbinary八进制octoctonary十六进制hexhexdecimalist

例题

PHP提供了进制转换函数

echo decbin(123),'
'; //十进制转二进制

echo bindec(1111011),'
'; //二进制转十进制

echo dechex(123),'
'; //十进制转十六进制

echo hexdec('7b'),'
'; //十六进制转十进制

echo decoct(123); //十进制转八进制

2、浮点型

浮点数在内存中保存的是近似值

浮点数不能参与比较

var_dump(0.9==(1-0.1)); //bool(true)

echo '
';

var_dump(0.1==(1-0.9)); //bool(false)

如果浮点数要比较,必须确定比较的位数

var_dump(0.9==(1-0.1)); //bool(true)

echo '
';

var_dump(0.1==(1-0.9)); //bool(false)

echo '
';

var_dump(bccomp(0.1,1-0.9,5)); //比较小数点后面5位 int(0) 0表示相等

提醒:如果一个整数超出了整形的范围,会自动的转成浮点型

3、布尔型

不能使用echo 和print输出布尔型,要使用var_dump()输出

$flag=false;

var_dump($flag); //bool(false)

4、字符串型

在PHP中单引号字符串和双引号字符串是有区别的

单引号字符串是真正的字符串

双引号字符串要解析字符串中的变量

例题

$name='tom';

echo '我的名字叫$name','
'; //我的名字叫$name

echo "我的名字叫$name",'
'; //我的名字叫tom

例题:{ }取变量值

$name='tom';

echo '$name是我的名字','
'; //$name是我的名字

echo "{$name}是我的名字",'
'; //{}表示获取变量的值(tom是我的名字)

echo "${name}是我的名字",'
'; //$和{只要挨着一起就可以(tom是我的名字)

输出特殊字符

echo '毛主席说:\'上课不要睡觉\'','
'; //转义字符 毛主席说:'上课不要睡觉'

echo '文件保存在c:\\'; //文件保存在c:\

字符串定界符

1、有<<<开头,后面跟的是标识符

2、字符串定界符的结束符必须顶格写,前面不能有任何的空白字符

3、字符串定界符分为两种,heredoc(双引号),nowdoc(单引号)

1.3.2 复合类型

1、数组

在PHP中数组有两种形式,索引数组和关联数组

索引数组:用整数做下标,默认从0开始,后面依次加一

关联数组:用字符串做下标,通过=>符号将下标和值关联起来

例题:数组的声明

//1、索引数组的声明

$stu=array('tom','berry','ketty'); //索引数组

print_r($stu); //输出数组 Array ( [0] => tom [1] => berry [2] => ketty )

echo '


';

echo $stu[0],'
'; //tom

echo $stu[1],'
'; //berry

echo $stu[2],'


'; //ketty

------------------------------------------

//2、关联数组

$emp=array('name'=>'李白','sex'=>'男','age'=>22);

print_r($emp); //Array ( [name] => 李白 [sex] => 男 [age] => 22 )

echo '


';

echo $emp['name'],'
'; //李白

echo $emp['sex'],'
'; //男

echo $emp['age']; //22

练习:写出数组的下标

$array=array(1=>'a','b','c','d');

print_r($array); //Array ( [1] => a [2] => b [3] => c [4] => d )

echo '
';

--------------------------

$array=array('a',2=>'b','c',5=>'d');

print_r($array); //Array ( [0] => a [2] => b [3] => c [5] => d )

echo '
';

----------------------------

$array=array('a','name'=>'b','c','sex'=>'d');

print_r($array); //Array ( [0] => a [name] => b [1] => c [sex] => d )

echo '
';

------------------------------

$array=array(1=>'a',1=>'b',1=>'c','d');

print_r($array); //Array ( [1] => c [2] => d )

数组的下标只能是正整数和字符串

思考如下下标

$stu[true]='tom'; //转成1

$stu[false]='berry'; //转成0

$stu[12.9]='aa'; //转成12(取整数部分)

$stu[-10]='bb'; //负数可以做下标

$stu[-12.3]='cc'; //取负整数

$stu['10']='dd'; //字符串数字转成数字

$stu['']='ee'; //空字符串也可以做下标

$stu[null]='ff'; //转成空字符串做下标

print_r($stu);

短数组语法,可以直接通过中括号声明数组

$stu=['tom','berry','ketty'];

print_r($stu); //Array ( [0] => tom [1] => berry [2] => ketty )

多学一招:在PHP7.1中可以支持数组的赋值

//例题,两个数交换

$num1=10;

$num2=20;

[$num1,$num2]=[$num2,$num1];

echo $num1,'
',$num2;

二维数组的声明

$stu=[

['name'=>'tom','sex'=>'男','age'=>22],

['name'=>'berry','sex'=>'女','age'=>23]

];

echo '

';

print_r($stu);

//运行结果

Array

(

[0] => Array

(

[name] => tom

[sex] => 男

[age] => 22

)

[1] => Array

(

[name] => berry

[sex] => 女

[age] => 23

)

)

多学一招:字符串可以通过数组的方式去调用

echo 'abc'[0],'
'; //a

echo 'abc'[-1],'
'; //c,从右边开始取第一个 7.1开始支持

小结:

1、数组在内存中一段连续的空间

2、如果要保存同一类型的多个数据就使用数组

2、对象

对象在后面专门讲解(面向对象编程)

1.3.3 特殊类型

1、资源

2、null

提醒:在PHP中 null和NULL是一样的,不区分大小写

1.3.4 类型转换

1、自动类型转换:当提供的类型和需要的类型不一致的时候会自动进行类型转换

$num=10;

if($num){ //自动将数字转成布尔型

echo 'aa';

}else{

echo 'bb';

}

---------------------------------

echo '20'-10; //自动的将字符串转成数字

2、强制类型转换

语法:(数据类型)数据

$num1='12';

var_dump($num1,(int)$num1,(float)$num1); //string(2) "12" int(12) float(12)

其他类型和布尔之间的转换

规则:0、空为假,非0非空为真

var_dump((bool)'abc'); echo '
'; //bool(true)

var_dump((bool)''); echo '
'; //bool(false)

var_dump((bool)'0'); echo '
'; //bool(false)

var_dump((bool)'0.0'); echo '
'; //bool(true)

var_dump((bool)'00'); echo '
'; //bool(true)

var_dump((bool)'false'); echo '
'; //bool(true)

var_dump((bool)'null'); echo '
'; //bool(true)

var_dump((bool)1); echo '
'; //bool(true)

var_dump((bool)0); echo '
'; //bool(false)

var_dump((bool)-10); echo '
'; //bool(true)

var_dump((bool)0.0); echo '
'; //bool(false)

var_dump((bool)array()); echo '
'; //bool(false)

var_dump((bool)array(1)); echo '
'; //bool(true)

var_dump((bool)array(false)); echo '
';//bool(true)

var_dump((bool)null); echo '
'; //bool(false)

1.4 运算符

1.4.1 算术运算符

一元运算符二元运算符+++–-*/% (取模)

注意:在PHP中,算术运算符只能做数学运算。

echo '10'+'20','
'; //30

echo '10ab'+'20cd','
'; //30

echo 'ab10'+'cd20','
'; //0

++前置:先自增再运算

++后置:先运算再自增

练习

$num=10;

$num++;

echo $num; //11

-------------------------

$num=10;

echo $num++; //10

------------------------

$num=10;

echo ++$num; //11

练习

$num=5;

echo (++$num)+(++$num)+(++$num); //21

-------------------------

$num=5;

echo ($num++)+($num++)+($num++); //18

1.4.2 关系运算符(比较运算符)

>

>=

<

<=

==

!=

===

!==

比较运算符的运算结果是布尔值

1.4.3 逻辑运算符

& 与:运算符两边的表达式都要计算

| 或:运算符两边的表达式都要计算

&& 短路与:如果前面的条件不满足,后面的条件就不用计算了

|| 短路或

! 非

例题

$a=5;

$b=10;

if($a>10 && ++$a>20)

echo '你好吗';

echo $a; //5

//分析:$a>10为false, 与中只要有一个是false,另一个不用计算结果肯定是false,所以短路与++a就不计算了,结果是5

----------------------------

$a=5;

$b=10;

if($a<10 || ++$a>20)

echo '你好吗';

echo $a; //5

//分析:短路或只要有一个为true,结果肯定是true,$a<10结果是true,后面++$a就不用计算了。

1.4.4 赋值运算符

= //赋值

+= //a+=b a=a+b

-=

*=

/=

%=

1.4.5 字符串连接符(.)

echo 'aa'.'bb'; //字符串链接 aabb

1.4.6 错误抑制符(@)

错误抑制符只对表达式有效

echo @($aa+$bb); //错误抑制

1.4.7 三元运算符(?

语法:

表达式?值1:值2

//表达式的值为true,返回值1,否则返回值2

练习

$num=11;

echo $num%2?'奇数':'偶数';

1.4.8 null合并运算符(??)

PHP7.0以后才支持

例题

echo $name??'姓名不详'; //姓名不详

多学一招:两个用来判断的函数

isset():判断变量是否被设置,并且设置的不是null

empty():检查一个变量是否为空,能转成false全部是空,['',0,0.0,array(),null]

例题

echo isset($name)?$name:'姓名不详'; //姓名不详

echo '


';

$stu=array();

echo empty($stu)?'空':'非空'; //空

1.5 判断

1.5.1 语法

单分支

if(条件){

}

双分支

if(条件){

//代码块1

}else{

//代码块2

}

多分支

if(条件){

}elseif(条件){ //注意:elseif之间没有空格

}else{

}

多路选择

switch(表达式){

case 常量:

//代码块

break;

case 常量:

//代码块

break;

default:

//代码块

}

1.5.2 例题

例题一、判断闰年(练习双分支)

步骤:

1、创建表单

2、提交数据

3、在服务器获取提交的数据,并判断

代码实现

if(!empty($_POST)){ //$_POST不为空说明有post提交的数据

//var_dump($_POST);

$year=$_POST['year']; //获取年份

if($year==''){

echo '您没有输入年份';

}else{

if(is_numeric($year)){ //判断$year是否是数字或字符串数字

$year+=0; //将字符串数字转成数字型

if(is_int($year)){ //is_int用来检测变量是否是整型

if($year<1){

echo '年份必须正整数';

}else{

if($year%4==0 && $year%100!=0 || $year%400==0)

echo "{$year}是闰年";

else

echo "{$year}是平年";

}

}else{

echo '您输入的不是整数';

}

}else{

echo '您输入的不是数字';

}

}

}

?>

请输入年份:

运行结果

小结:

1、$_POST是一个变量,用来保存post提交的数据

2、action=''表示将数据提到本页面

3、is_numeric()判断变量是否是数字或字符串数字

4、is_int()判断变量是否是整型

5、if、else后面如果只是一句代码,大括号可以省略

例题二:判断成绩(练习多分支)

目标:输入语文和数学,判断等级

代码实现

if(isset($_POST['button'])){ //点击了提交按钮

$ch=$_POST['ch']; //获取语文成绩

$math=$_POST['math']; //获取数学成绩

if($ch=='' || !is_numeric($ch) || $ch<0 || $ch>100){

echo '语文成绩必须在0-100之间';

}

elseif($math=='' || !is_numeric($math) || !($math>=0 && $math<=100)){

echo '数学成绩必须在0-100之间';

}else{

$avg=($ch+$math)/2; //求平均值

echo "您的平均分是:{$avg}
";

if($avg>=90)

echo 'A';

elseif($avg>=80)

echo 'B';

elseif($avg>=70)

echo 'C';

elseif($avg>=60)

echo 'D';

else

echo 'E';

}

}

?>

语文:

数学:

运行结果

例题三:更改颜色(switch-case)

目标:将文字的颜色改成选择的颜色

if(isset($_POST['button'])) {

switch($_POST['color']){

case '1':

$color='#FF0000'; //红色

break;

case '2':

$color='#009900'; // 绿色

break;

case '3':

$color='#0000FF'; //蓝色

break;

default:

$color='#000000'; //黑色

}

echo <<

str;

}

?>

锄禾日当午,

汗滴禾下土。

谁知盘中餐,

粒粒皆辛苦。

运行结果

1.6 作业

计算器

1.2 循环

1.2.1 for

for(初始值;条件;增量){

//循环体

}

注意:循环中千万不能出现死循环

思考:如下代码输出什么

例题一:

for($i=1;$i<=10;$i+=2){

echo "{$i}:锄禾日当午
";

}

/*

1:锄禾日当午

3:锄禾日当午

5:锄禾日当午

7:锄禾日当午

9:锄禾日当午

*/

例题二:

for($i=1;$i<=10;){

}

//死循环,$i永远等于1,1永远小于10,条件永远为true

例题三

for($i=1;;$i++){

}

//死循环,只要没有条件都是死循环

例题四

for(;;){

}

//这是一个经典的死循环

1.2.3 思考题

1、如下代码循环了几次?

for($i=1;$i!=5;$i++){

}

//循环了4次

2、在循环N次循环体中,初始值执行了几次?条件执行了几次?增量执行了几次?

初始值执行了1次

条件执行了N+1次

增量执行了N次

3、在循环执行完毕后,$i的值是存在的。

for($i=1;$i<=3;$i++){

}

echo $i; //4

1.2.4 while、do-while

语法

while(条件){

}

-------------------------

do{

}while(条件)

小结:

1、for、while、do-while可以相互替换

2、如果明确知道循环多少次首先for循环,如要要循环到条件不成立为止选while或do-while

3、先判断再执行选while,先执行再判断选do-while

4、while循环条件不成立就不执行,do-while至少执行一次

1.2.5 例题

1、使用三种循环实现从1加到100

//1、for循环实现

$sum=0;

for($i=1;$i<=100;$i++){

$sum+=$i; //$sum=$sum+$i;

}

echo $sum;

//分析

/**

*

$i $sum

1 1

2 1+2

3 1+2+3

4 1+2+3+4

...

100 1+2+3+++100

*/

-------------------------------------------------

//2、while循环

$i=1;

$sum=0; //保存和

while($i<=100){

//方法一

/*

$sum+=$i;

$i++;

*/

//方法二

$sum+=$i++;

}

echo $sum;

--------------------------------------------------

//3、do-while循环

$i=1;

$sum=0;

do{

$sum+=$i;

$i++;

}while($i<=100);

echo $sum,'
'; //5050

//可以有如下更改

$i=1;

$sum=0;

do{

$sum+=$i++; //++后置

}while($i<=100);

echo $sum,'
'; //5050

//可以做如下更改

$i=1;

$sum=0;

do{

$sum+=$i;

}while(++$i<=100); //++前置

echo $sum,'
'; //5050

小结:

1、for、while、do-while可以相互替换

2、结合++前置和++后置考虑逻辑

1.2.6 多语句表达式

初始值、增量可以由多条语句组成

例题:数字分解

for($i=1,$j=9;$i<=$j;$i++,$j--){

echo "10可以分成{$i}和{$j}
";

}

//运行结果

/*

10可以分成1和9

10可以分成2和8

10可以分成3和7

10可以分成4和6

10可以分成5和5

*/

小结:初始值、增量可以写多个表达式,但是条件一般只写一个,如果条件写多个,只是最后一个条件起作用

1.2.7 双重循环

1、打印阶梯数字

for($i=1;$i<=9;$i++){ //循环行

for($j=1;$j<=$i;$j++){ //循环列

echo $j,' ';

}

echo '
';

}

//运行结果

1

1 2

1 2 3

1 2 3 4

1 2 3 4 5

1 2 3 4 5 6

1 2 3 4 5 6 7

1 2 3 4 5 6 7 8

1 2 3 4 5 6 7 8 9

2、打印九九乘法表

for($i=1;$i<=9;$i++){ //行

echo '

';

for($j=1;$j<=$i;$j++){ //列

echo "

';

}

echo '

';

}

?>

{$j}*{$i}=".($j*$i).'

运行结果

小结:规则:当前列*当前行

1.28 foreach

foreach循环是用来遍历数组

语法

//语法一

foreach(数组 as 值){

}

//语法二

foreach(数组 as 键=>值){

}

例题

$stu=['tom','berry','ketty'];

foreach($stu as $v){

echo $v,'
';

}

/**

tom

berry

ketty

*/

echo '


';

-----------------------------------------------------------

foreach($stu as $k=>$v){

echo "{$k}:{$v}
";

}

/**

0:tom

1:berry

2:ketty

*/

1.3 跳转语句

1.3.1 语法

break:中断循环

continue:中断当前循环,进入下一个循环

例题:

for($i=1; $i<=10; $i++) {

if($i==5)

break; //中断循环

echo "{$i}:锄禾日当午
";

}

//结果

1:锄禾日当午

2:锄禾日当午

3:锄禾日当午

4:锄禾日当午

--------------------------------------------------

for($i=1; $i<=10; $i++) {

if($i==5)

continue; //跳出5,进入6循环

echo "{$i}:锄禾日当午
";

}

1:锄禾日当午

2:锄禾日当午

3:锄禾日当午

4:锄禾日当午 //注意,没有打印第5句

6:锄禾日当午

7:锄禾日当午

8:锄禾日当午

9:锄禾日当午

10:锄禾日当午

1.3.2 中断多重循环

break和continue默认中断、跳出1重循环,如果调中断、跳出多重循环,在后面加一个数字。

for($i=1; $i<=10; $i++) {

for($j=1;$j<=$i;$j++){

echo $j.' ';

if($j==5){

break 2; //中断2重循环

}

}

echo '
';

}

//运行结果

1

1 2

1 2 3

1 2 3 4

1 2 3 4 5

练习

for($i=1; $i<=10; $i++) {

switch($i){

case 5:

break 2;

}

echo $i,'
';

}

//结果

1

2

3

4

小结:switch的本质是循环了一次的循环

1.4 替代语法

php中除了do-while以外,其他的语法结构都有替代语法

规则:左大括号变冒号,右大括号变endXXX

//if的替代语法

if():

elseif():

else:

endif;

//switch替代语法

switch():

endswitch;

//for

for():

endfor;

//while

while():

endwhile;

//foreach

foreach():

endforeach;

例题:在混编的时候用替代语法

for($i=1;$i<=10;$i++):

if($i%2==0):

?>

:锄禾日当午

endif;

endfor;

?>

//运行结果

2:锄禾日当午

4:锄禾日当午

6:锄禾日当午

8:锄禾日当午

10:锄禾日当午

小结:可以通过替代语法证明else if之间如果有空格是嵌套if语句。

$score=80;

if($score>=90):

echo 'A';

elseif($score>=80): //elseif之间没有空格,如果有空格是嵌套if语句

echo 'B';

else:

echo 'C';

endif;

----------------------------------------

$score=80;

if($score>=90):

echo 'A';

else:

if($score>=80):

echo 'B';

else:

echo 'C';

endif;

endif;

1.5 函数

1、函数就是一段代码块

2、函数可以实现模块化编程

1.5.1 函数定义

function 函数名(参数1,参数2,...){

//函数体

}

通过函数名()调用函数

//定义函数

function show() {

echo '锄禾日当午
';

}

//调用

show(); //锄禾日当午

SHOW(); //锄禾日当午 函数名不区分大小写

小结:

1、变量名区分大小写

2、关键字、函数名不区分大小写

1.5.2 可变函数

将函数名存储到变量中

function show($args) {

echo $args,'
';

}

$str='show'; //将函数名保存到变量中

$str('锄禾日当午');

例题:随机调用函数

//中文显示

function showChinese() {

echo '锄禾日当午
';

}

//英文显示

function showEnglish() {

echo 'chu he re dang wu
';

}

//测试

$fun=rand(1,10)%2?'showChinese':'showEnglish'; //可变变量

$fun();

1.5.3 匿名函数

匿名函数就是没有名字的函数

//匿名函数

$fun=function(){

echo '锄禾日当午
';

};

//匿名函数调用

$fun();

1.5.4 参数传递

函数的参数有形式参数和实际参数

形式参数是定义函数时候的参数,只起形式的作用,没有具体的值

实际参数的调用函数时候的参数,有具体的值

function fun($num1,$num2) {

echo $num1+$num2;

}

fun(10,20); //30

默认情况下,参数的传递是值传递

$num=10;

function fun($args) {

$args=100;

}

fun($num);

echo $num; //10

地址传递

$num=10;

//地址传递

function fun(&$args) { //&符表示取地址

$args=100;

}

fun($num);

echo $num; //100

小结

1、函数的参数默认是值传递

2、如果要传递地址,在参数前面加&

3、如果是地址传递,不能直接写值

function fun(&$args) {

$args=100;

}

fun(10); //Fatal error: Only variables can be passed by reference (只有变量才能传递引用)

1.5.5 参数默认值

1、在定义函数的时候给形参赋值就是参数的默认值

//参数的默认值

function fun($name,$add='地址不详') {

echo '姓名:'.$name,'
';

echo '地址:'.$add,'


';

}

//测试

fun('tom','北京');

fun('berry');

2、默认值必须是值,不能用变量代替

$str='地址不详'

function fun($name,$add=$str) { //错误,默认值可以使用变量

echo '姓名:'.$name,'
';

echo '地址:'.$add,'


';

}

3、默认值可以使用常量

define('ADD','地址不详');

function fun($name,$add=ADD) { //默认值可以使用常量

echo '姓名:'.$name,'
';

echo '地址:'.$add,'


';

}

//测试

fun('berry');

4、有默认值的写在后面,没有默认值的写在前面

//没有默认值的写在前面,有默认值写在后面

function fun($name,$age='未知',$add='地址不详') {

echo "姓名:{$name}
";

echo "年龄:{$age}
";

echo "地址:{$add}
";

}

fun('tom');

//运行结果

姓名:tom

年龄:未知

地址:地址不详

1.5.6 参数个数不匹配

function fun($num1,$num2) {

echo $num1,'
';

echo $num2,'
';

}

//fun(10); //实参少于形参(报错)

fun(10,20,30); //实参多于形参,只取前面对应的值

获取所有传递的参数

function fun() {

//echo func_num_args(),'
'; //获取参数的个数

$args=func_get_args(); //获取参数数组

print_r($args);

}

fun(10);

fun(10,20);

fun(10,20,30);

1.5.7 参数约束

1、定义变长参数(了解)

// ...$hobby包含了除了前面两个参数以外的所有参数

function fun($name,$age,...$hobby) {

echo '姓名:'.$name,'
';

echo '年龄:'.$age,'
';

print_r($hobby);

echo '


';

}

fun('tom',22);

fun('berry',25,'读书','睡觉');

运行结果

多学一招:

function fun(...$args) {

print_r($args);

echo '
';

}

$num=[10,20];

echo '

';

fun(...$num); //将数组中的参数展开

//运行结果

/*

Array

(

[0] => 10

[1] => 20

)

*/

2、参数类型约束

//类型约束

function fun(string $name,int $age) {

echo "姓名:{$name},'
'";

echo "年龄:{$age}
";

}

fun('tom',22);

//约束$name是字符串型,$age是整型

3、返回值约束

function fun(int $num1,int $num2):int { //必须返回整型

return $num1+$num2;

}

echo fun(10,20); //30

可以约束:string、int、float、bool、数组

//约束返回类型是数组

function fun():array {

}

//约束return后面不能有返回值 必须在7.1以后的版本中才支持

function fun():void { //void是空的意思

return;

}

fun();

1.6 return

1.6.1 终止脚本执行

echo '锄禾日当午
';

return; //终止脚本执行

echo '汗滴禾下土
'; //不执行

提醒:return只能中断当前页面,如果有包含文件,只能中断包含文件

例题:

6-demo.php

echo '锄禾日当午
';

require './test.php'; //包含文件

echo '汗滴禾下土
';

test.php

echo 'aaa
';

return; //只能中断test.php

echo 'bbb
';

运行结果

如果要完全终止脚本执行,使用exit()、或die()

echo 'aaa
';

exit(); //die()

echo 'bbb
';

1.6.2、返回页面结果

test.php

return array('name'=>'tom','sex'=>'男');

6-demo.php

$stu=require './test.php';

print_r($stu); //Array ( [name] => tom [sex] => 男 )

小结:在项目中引入配置文件就使用这种方法

1.6.3 函数的返回和终止

return在函数中使用作用有二 1、终止函数执行

2、返回值

function fun() {

echo 'aaa';

return ; //终止函数执行

echo 'bbb';

}

fun(); //aaa

----------------------------------

function fun() {

return 10; //返回值

}

echo fun(); //10

1.7 作业讲解

计算器

$num1=''; //$num1的初始值

$num2=''; //$num2的初始值

$op=''; //操作符

$result=''; //结果

if(!empty($_POST)) {

$num1=$_POST['num1'];

$num2=$_POST['num2'];

$op=$_POST['op']; //操作符

switch($op){

case '+':

$result=$num1+$num2;

break;

case '-':

$result=$num1-$num2;

break;

case '*':

$result=$num1*$num2;

break;

case '/':

$result=$num1/$num2;

break;

}

}

?>

运行结果

1.8 作业

1、 通过for循环将数组中值求和、求平均值

2、数组翻转

3、遍历二维数组

4、 循环输出1-100,其中3的倍数输出A,5的倍数输出B,15输出C。

5、 打印水仙花数

6、 打印100以内的斐波那契数(迭代法) 1 1 2 3 5 8 13 21 …

7、 打印星星

8、 生成颜色面板

1.2 作用域

1.2.1 变量作用域

1、全局变量:在函数外面

2、局部变量:在函数里面,默认情况下,函数内部是不会去访问函数外部的变量

3、超全局变量:可以在函数内部和函数外部访问

$num=10;

function fun() {

echo $num; //Notice: Undefined variable: num

}

fun();

//函数内部默认不能访问函数外部的值

---------------------

$_POST['num']=10; //将值付给超全局变量

function fun() {

echo $_POST['num']; //获取超全局的值 10

}

fun();

----------------------------

function fun() {

$_GET['num']=10; //将值付给超全局变量

}

fun();

echo $_GET['num']; //打印超全局变量的值 10

在函数内部访问全局变量

$num=10; //全局变量

function fun() {

echo $GLOBALS['num']; //输出全局的$num

}

fun();

练习:如下代码输出什么

function fun() {

$GLOBALS['num']=10; //将值付给全局的$num

}

fun();

echo $num; //10

global关键字

$num=10;

function fun() {

global $num; //将全局变量的$num的地址引入到函数内部 相当于$num=&GLOBALS['num']

echo $num; //10

$num=100;

}

fun();

echo '
';

echo $num; //100

-----------------------------------

$num=10;

function fun() {

global $num;

unset($num); //销毁的是引用,不是具体的值

}

fun();

echo $num; //10

小结:

1、$GLOBALS保存的是全局变量的所有的值

$a=10;

$b=20;

function show() {

echo '

';

var_dump($GLOBALS); //是一个数组,保存的是全局变量的所有的值

}

show();

2、global用于创建一个全局变量的引用

注意:常量没有作用域的概念

/*

define('PI',3.14);

function fun() {

echo PI; //3.14

}

fun();

echo '
';

*/

-------------------------------------

function fun() {

define('PI',3.14);

}

fun();

echo PI; //3.14

1.2.2 静态变量(static)

静态变量一般指的是静态局部变量。

静态变量只初始化一次

function fun() {

$num=10; //普通变量每调用一次初始化一次,调用完毕销毁

$num++;

echo $num,'
';

}

fun(); //11

fun(); //11

--------------------------------

function fun() {

static $num=10; //静态变量只初始化一次,调用完毕吧不销毁,第二次调用的时候就不再初始化

$num++;

echo $num,'
';

}

fun(); //11

fun(); //12

常量和静态变量的区别

1、常量和静态变量都是初始化一次

2、常量不能改变值,静态变量可以改变值

3、常量没有作用域,静态变量有作用域

function fun1() {

define('num',10);

}

function fun2() {

echo num; //10

}

fun1();

fun2();

------------------------------------------------------------

function fun1() {

static $num=10;

}

function fun2() {

echo $num; //Notice: Undefined variable: num 因为静态变量是有作用域的

}

fun1();

fun2();

1.2.3 匿名函数use()

默认情况下,函数内部不能访问函数外部的变量,但在匿名函数中,可以通过use将外部变量引入匿名函数中

$num=10;

$fun=function() use($num) { //将$num引入到匿名函数中

echo $num;

};

$fun(); //10

思考:如何在函数内部访问函数外部变量

1、使用超全局变量

2、$GLOBALS

3、global

4、use将函数外部变量引入到匿名函数内部

练习:如果代码输出什么

$num=10;

function test() {

$num=20;

$fun=function() use($num) { //只能引入一层

echo $num;

};

$fun();

}

test(); //20

多学一招:use可以引入值,也可以引入地址

$num=10;

$fun=function()use(&$num){ //use可以传地址

$num=100;

};

$fun();

echo $num; //100

1.3 递归

函数内部自己调用自己

递归有两个元素,一个是递归点(从什么地方递归),第二递归出口

例题1:输出9 8 7 6 …

function printer($num) {

echo $num,' ';

if($num==1) //递归出口

return;

printer($num-1); //递归点

}

printer(9); //9 8 7 6 5 4 3 2 1

例题2:从1加到100

function cal($num) {

if($num==1)

return 1;

return $num+cal($num-1);

}

echo cal(100);

//分析

/**

第$i次执行 结果

cal(100) 100+cal(99)

= 100+99+cal(98)

= 100+99+98+cal(97)

= 100+99+98+++++cal(1)

= 100+99+98++++1

*/

例题:打印前10个斐波那契数列

//打印第5个斐波那契数

function fbnq($n) {

if($n==1 || $n==2)

return 1;

return fbnq($n-1)+fbnq($n-2); //第n个斐波那契数等于前两个数之和

}

echo fbnq(5),'
';

/**

*分析:

fbnq(5) =fbnq(4)+fbnq(3)

=fbnq(3)*2+fbnq(2)

=(fbnq(2)+fbnq(1))*2+fbnq(2)

=(1+1)*2+1

=5

*/

//打印前10个斐波那契数

for($i=1;$i<=10;$i++)

echo fbnq($i),' '; //1 1 2 3 5 8 13 21 34 55

小结:递归尽量少用,因为递归需要用到现场保护,现场保护是需要消耗资源的

1.4 包含文件

场景:

1.4.1 包含文件的方式

1、require:包含多次

2、include:包含多次

3、require_once: 包含一次

4、include_once: 包含一次

小结:

1、require遇到错误抛出error类别的错误,停止执行

2、include遇到错误抛出warning类型的错误,继续执行

3、require_once、include_once只能包含一次

4、HTML类型的包含页面中存在PHP代码,如果包含到PHP中是可以被执行的

5、包含文件相当于把包含文件中的代码拷贝到主文件中执行,魔术常量除外,魔术常量获取的是所在文件的信息。

6、包含在编译时不执行、运行时加载到内存、独立编译包含文件

1.4.2 包含文件的路径

./ 当前目录

../ 上一级目录

区分如下包含:

require './head.html'; //在当前目录下查找

require 'head.html'; //受include_path配置影响

include_path的使用场景:

如果包含文件的目录结构比较复杂,比如:在c:\aa\bb\cc\dd中有多个文件需要包含,可以将包含的路径设置成include_path,这样包含就只要写文件名就可以了

set_include_path('c:\aa\bb\cc\dd'); //设置include_path

require 'head1.html'; //受include_path配置影响

require 'head2.html';

include_path可以设置多个,路径之间用分号隔开

set_include_path('c:\aa\bb\cc\dd;d:\\');

多学一招:

正斜(/) web中目录分隔用正斜 http://www.sina.com/index.php

反斜(\)物理地址的分隔用反斜,(windows中物理地址正斜和反斜都可以) c:\web1\aa

1.5 错误处理

1.5.1 错误的级别

notice:提示warning:警告error:致命错误

notice和warning报错后继续执行,error报错后停止执行

1.5.2 错误的提示方法

方法一:显示在浏览器上

方法二:记录在日志中

1.5.3 与错误处理有关的配置

在php.ini中

1. error_reporting = E_ALL:报告所有的错误

2. display_errors = On:将错误显示在浏览器上

3. log_errors = On:将错误记录在日志中

4. error_log=’地址’:错误日志保存的地址

在项目开发过程中有两个模式,开发模式,运行模式

开发模式:错误显示在浏览器上,不要记录在日志中

运行模式:错误不显示在浏览器上,记录是日志中

例题

$debug=false; //true:开发模式 false:运行模式

ini_set('error_reporting',E_ALL); //所有的错误有报告

if($debug){

ini_set('display_errors','on'); //错误显示是浏览器上

ini_set('log_errors','off'); //错误不显示在日志中

}else{

ini_set('display_errors','off');

ini_set('log_errors','on');

ini_set('error_log','./err.log'); //错误日志保存的地址

}

//测试

echo $num;

提示:ini_set()设置PHP的配置参数

1.5.4 自定义错误处理(了解)

通过trigger_error产生一个用户级别的 error/warning/notice 信息

$age=100;

if($age>80){

//trigger_error('年龄不能超过80岁'); //默认触发了notice级别的错误

//trigger_error('年龄不能超过80岁',E_USER_NOTICE); //触发notice级别的错误

//trigger_error('年龄不能超过80岁',E_USER_WARNING);

trigger_error('年龄不能超过80岁',E_USER_ERROR); //错误用户error错误

}

注意:用户级别的错误的常量名中一定要带有USER。

定义错误处理函数

function error() {

echo '这是自定义错误处理';

}

set_error_handler('error'); //注册错误处理函数,只要有错误就会自动的调用错误处理函数

echo $num;

运行结果

处理处理函数还可以带有参数

/**

*自定义错误处理函数

*@param $errno int 错误类别

*@param $errstr string 错误信息

*@param $errfile string 文件地址

*@param $errline int 错误行号

*/

function error($errno,$errstr,$errfile,$errline) {

switch($errno){

case E_NOTICE:

case E_USER_NOTICE:

echo '记录在日志中,上班后在处理
';

break;

case E_WARNING:

case E_USER_WARNING:

echo '给管理员发邮件
';

break;

case E_ERROR:

case E_USER_ERROR:

echo '给管理员打电话
';

break;

}

echo "错误信息:{$errstr}
";

echo "错误文件:{$errfile}
";

echo "错误行号:{$errline}
";

}

set_error_handler('error');

echo $num;

//运行结果

记录在日志中,上班后在处理

错误信息:Undefined variable: num

错误文件:F:\wamp\www\4-demo.php

错误行号:50

1.6 文件编程

1.6.1 文件夹操作

**1 、**创建文件夹【mkdir(路径,权限,是否递归创建)】

make:创建

directory:目录,文件夹

例题

//1、创建目录

//mkdir('./aa'); //创建aa文件夹

//mkdir('./aa/bb'); //在aa目录下创建bb(aa目录必须存在)

mkdir('./aa/bb/cc/dd',0777,true); //递归创建

小结:

1、0777表示是文件夹的权限,在Linux中会详细讲解

2、true表示递归创建,默认是false

**2、**删除文件夹【rmdir()】

//remove:移除

rmdir('./aa/bb/cc/dd'); //删除dd文件夹

提醒:

1、删除的文件夹必须是空的

2、PHP基于安全考虑,没有提供递归删除。

**3、**重命名文件夹【rename(旧名字,新名字)】

rename('./aa','./aaa'); //将aa改为aaa

**4、**是否是文件夹【is_dir()】

echo is_dir('./aaa')?'是文件夹':'不是文件夹';

**5、**打开文件夹、读取文件夹、关闭文件夹

$folder=opendir('./'); //打开目录

//var_dump($folder); //resource(3) of type (stream)

while($f=readdir($folder)){ //读取文件夹

if($f=='.' || $f=='..')

continue;

echo iconv('gbk','utf-8',$f),'
'; //将gbk转成utf-8

}

closedir($folder); //关闭文件夹

小结:

1、opendir()返回资源类型

2、每个文件夹中都有.和..

3、iconv()用来做字符编码转换

1.7 作业讲解

1、 通过for循环将数组中值求和、求平均值

//1、求数组的和、平均值

$num=[1,20,53,23,14,12,15];

$sum=0;

for($i=0,$n=count($num);$i<$n;$i++){

$sum+=$num[$i];

}

echo '和是:'.$sum,'
'; //和是:138

echo '平均值:'.number_format($sum/count($num),1); //精确到小数点后面1位 平均值:19.7

echo '


';

2、数组翻转

$stu=['tom','berry','ketty','rose','jake'];

for($i=0,$j=count($stu)-1;$i<$j;$i++,$j--){

[$stu[$i],$stu[$j]]=[$stu[$j],$stu[$i]]; //元素交换

}

print_r($stu); //Array ( [0] => jake [1] => rose [2] => ketty [3] => berry [4] => tom )

3、遍历二维数组

$stu=[

[1,2,3,4],

[10,20,30,40]

];

for($i=0;$i

for($j=0;$j

echo $stu[$i][$j],' ';

}

echo '
';

}

//运行结果

1 2 3 4

10 20 30 40

4、 循环输出1-100,其中3的倍数输出A,5的倍数输出B,15输出C。

for($i=1; $i<=100; $i++) {

if($i%15==0) //先写%15,,因为可以%15的值一定可以%3和%5

echo 'C';

elseif($i%3==0)

echo 'A';

elseif($i%5==0)

echo 'B';

else

echo $i;

echo ' ';

}

5、 打印水仙花数

for($i=100;$i<=999;$i++){

$a=(int)($i/100); //百位数

$b=(int)(($i%100)/10); //十位数

$c=$i%10; //个位数

if($i==pow($a,3)+pow($b,3)+pow($c,3))

echo $i,'
';

}

//pow($a,3) 表示$a的三次方

//运行结果

153

370

371

407

6、 打印100以内的斐波那契数(迭代法)1 1 2 3 5 8 13 21 …

$num1=1; //第一个数

$num2=1; //第二个数

echo $num1,' ',$num2,' ';

while(true){

$num3=$num1+$num2; //第三个数是前面两个数的和

if($num3>100) //超过100就终止循环

break;

echo $num3,' ';

$num1=$num2; //将$num2移给$num1

$num2=$num3; //将$num3移给$num2

}

//1 1 2 3 5 8 13 21 34 55 89

1.8 作业

1、一只猴子看守一堆桃子,第一天吃了一半后又多吃了1个,第二天一样,到第十天的时候就剩下一个桃子,请问原来有几个桃子?

2、递归遍历整个文件夹

1.2 文件操作

**1、**将字符串写入文件

$str="床前明月光,\r\n疑是地上霜。\r\n举头望明月,\r\n低头思故乡。";

file_put_contents('./test.txt',$str); //将字符串写到文本中

小结:

1、 所有的“写”操作都是清空重写

2、在文本中换行是\r\n

\r:回车 光标移动到当前行的最前面

\n:换行 将光标下移动一行

按键盘的回车键做了两步,第一步将光标移动到当前行的最前面,第二步下移一行。

3、\r\n是特殊字符,必须放在双引号内

**2、**将整个文件读入一个字符串

//方法一:

echo file_get_contents('./test.txt'); //将整个文件读入一个字符串

//方法二:

readfile('./test.txt'); //读取输出文件内容

//注意:echo file_get_contents()==readfile()

**3、**打开文件并操作

fopen(地址,模式) 打开文件

模式:

r:读 read

w:写 write

a:追加 append

例题:

//3.1、打开文件写入

/*

$fp=fopen('./test.txt','w'); //打开文件返回文件指针(文件地址)

//var_dump($fp); //resource(3) of type (stream)

for($i=1;$i<=10;$i++)

fputs($fp,'关关雎鸠'."\r\n"); //写一行

fclose($fp); //关闭文件

*/

//3.2 打开文件读取

/*

$fp=fopen('./test.txt','r'); //打开文件读取

while($line=fgets($fp)){

echo $line,'
';

}

*/

//3.3 打开文件追加

$fp=fopen('./test.txt','a'); //打开文件追加

fputs($fp,'在河之洲'); //在文件末尾追加

小结:

1、打开文件,返回文件指针(文件指针就是文件地址),资源类型

2、打开文件写、追加操作,如果文件不存在,就创建新的文件

3、打开文件读操作,文件不存在就报错

4、fputs()写一行,fgets()读一行,fclose()关闭文件

5、追加是在文件的末尾追加

**4、**是否是文件【is_file()】

echo is_file('./test.txt')?'是文件':'不是文件';

**5、**判断文件或文件夹是否存在【file_exists()】

echo file_exists('./test.txt')?'文件存在':'文件不存在';

**6、**删除文件【unlink】

$path='./test.txt';

if(file_exists($path)){ //文件存在

if(is_dir($path)) //如果是文件夹用rmdir()删除

rmdir($path);

elseif(is_file($Path)) //如果是文件用unlink()删除

unlink($path);

}else{

echo '文件夹或文件不存在';

}

**7、**二进制读取【fread(文件指针,文件大小)】

文件的存储有两种:字符流和二进制流

二进制流的读取按文件大小来读的。

$path='./face.jpg';

$fp=fopen($path,'r');

header('content-type:image/jpeg'); //告知浏览器下面的代码通过jpg图片方式解析

echo fread($fp,filesize($path)); //二进制读取

多学一招:file_get_contents()也可以进行二进制读取

header('content-type:image/jpeg');

echo file_get_contents('./face.jpg');

小结:

1、文本流有明确的结束符,二进制流没有明确的结束符,通过文件大小判断文件是否读取完毕

2、file_get_contents()既可以进行字符流读取,也可以进行二进制读取。

1.3 表单提交数据的两种方式

1.3.1 两种方式

1、get

2、post

1.3.2 区别

1、外观上看

​ get提交在地址上可以看到参数

​ post提交在地址栏上看不到参数

2、安全性

​ get不安全

​ post安全

3、提交原理

​ get提交是参数一个一个的提交

​ post提交是所有参数作为一个整体一起提交

4、提交数据大小

​ get提交一般不超过255个字节

​ post提交的大小取决于服务器

// 在php.ini中,可以配置post提交的大小

post_max_size = 8M

5、灵活性

​ get很灵活,只要有页面的跳转就可以传递参数

​ post不灵活,post提交需要有表单的参与

1、 html跳转

跳转

2、JS跳转

3、PHP跳转

header('location:index.php?name=tom&age=22')

小结:

GETPOST外观上在地址上看到传递的参数和值地址栏上看不到数据提交数据大小提交少量数据,不同的浏览器最大值不一样,IE是255个字符提交大量数据,可以通过更改php.ini配置文件来设置post提交数据的最大值安全性低高提交原理提交的数据和数据之间在独立的将提交的数据变成XML格式提交灵活性很灵活,只要有页面的跳转就可以get传递数据不灵活

1.4 服务器接受数据的三种方式

通过名字获取名字对应的值

$_POST:数组类型,保存的POST提交的值

$_GET:数组类型,保存的GET提交的值

$_REQUEST:数组类型,保存的GET和POST提交的值

例题:

HTML页面

语文:

数学:



跳转



PHP页面

//post数组中不为空

if(!empty($_POST)) {

echo '这是post提交的数据
';

echo '语文:'.$_POST['ch'],'
';

echo '数学:'.$_POST['math'],'
';

}

echo '


';

//获取get提交的数据

if(!empty($_GET)){

echo '这是get提交的数据
';

echo '语文:'.$_GET['ch'],'
';

echo '数学:'.$_GET['math'],'
';

}

echo '


';

//既能获取get又能获取post提交的数据

echo $_REQUEST['ch'],'
';

echo $_REQUEST['math'];

思考题

在一个请求中,既有get又有post,get和post传递的名字是一样的,这时候通过$_REQUET获取的数据是什么?

答:结果取决于配置文件

request_order = "GP" # 先获取GET,在获取POST值

例题

if(!empty($_POST)){

echo '姓名:'.$_REQUEST['username'],'
';

}

?>

姓名:

分析:先获取GET的username,再获取post的username,后面的将前面的值覆盖

小结:

1、在开发的时候,如果明确是post提交就使用$_POST获取,如果明确get提交就用$_GET获取

2、request获取效率低,尽可能不要使用,除非提交的类型不确定的情况下才使用。

1.5 参数传递

1.5.1 复选框值的传递

复选框的命名要注意带’[]'。

if(isset($_POST['button'])) {

print_r($_POST['hobby']);

}

?>

爱好:

爬山

抽烟

喝酒

烫头

小结:

1、表单提交到本页面需要判断一下是否有post提交

2、数组的提交表单元素的名字必须带有[]。

1.5.2 例题

if(isset($_POST['button'])) {

echo '姓名:'.$_POST['username'].'
';

echo '密码:'.$_POST['pwd'].'
';

echo '性别:'.$_POST['sex'].'
';

echo '爱好:',isset($_POST['hobby'])?implode(',',$_POST['hobby']):'没有爱好','
';

echo '籍贯:'.$_POST['jiguan'],'
';

echo '留言:'.$_POST['words'];

}

?>

姓名:

密码:

性别:


爱好:

爬山

抽烟

喝酒

烫头

籍贯:


留言:

运行结果

1.6 文件上传

开发中需要上传图片、音乐、视频等等,这种上传传递是二进制数据。

1.6.1 客户端上传文件

文件域

表单的enctype属性

​ 默认情况下,表单传递是字符流,不能传递二进制流,通过设置表单的enctype属性传递复合数据。

enctype属性的值有:

application/x-www-form-urlencoded:【默认】,表示传递的是带格式的文本数据。multipart/form-data:复合的表单数据(字符串,文件),文件上传必须设置此值text/plain:用于向服务器传递无格式的文本数据,主要用户电子邮件

单词

multipart:复合

form-data:表单数组

1.6.2 服务器接受文件

超全局变量$_FILES是一个二维数组,用来保存客户端上传到服务器的文件信息。二维数组的行是文件域的名称,列有5个。 1、$_FILES[][‘name’]:上传的文件名 2、$_FILES[][‘type]:上传的类型,这个类型是MIME类型(image/jpeg、image/gif、image/png) 3、$_FILES[][‘size’]:文件的大小,以字节为单位 4、$_FILES[][‘tmp_name’]:文件上传时的临时文件 5、$_FILES[][‘error’]:错误编码(值有0、1、2、3、4、6、7)0表示正确

$_FILES[][‘error’]详解

值错误描述0正确1文件大小超过了php.ini中允许的最大值 upload_max_filesize = 2M2文件大小超过了表单允许的最大值3只有部分文件上传4没有文件上传6找不到临时文件7文件写入失败

注意:MAX_FILE_SIZE必须在文件域的上面。

只要掌握的错误号:0和4

1.6.3 将上传文件移动到指定位置

函数:

move_uploaded_file(临时地址,目标地址)

代码

if(!empty($_POST)) {

if($_FILES['face']['error']==0){ //上传正确

//文件上传

move_uploaded_file($_FILES['face']['tmp_name'],'./'.$_FILES['face']['name']);

}else{

echo '上传有误';

echo '错误码:'.$_FILES['face']['error'];

}

}

?>

小结:上传的同名的文件要给覆盖

1.6.4 与文件上传有关的配置

post_max_size = 8M:表单允许的最大值

upload_max_filesize = 2M:允许上传的文件大小

upload_tmp_dir =F:\wamp\tmp:指定临时文件地址,如果不知道操作系统指定

file_uploads = On:是否允许文件上传

max_file_uploads = 20:允许同时上传20个文件

1.7 优化文件上传

1.7.1 更改文件名

方法一:通过时间戳做文件名

$path='face.stu.jpg';

//echo strrchr($path,'.'); //从最后一个点开始截取,一直截取到最后

echo time().rand(100,999).strrchr($path,'.');

方法二:通过uniqid()实现

$path='face.stu.jpg';

echo uniqid().strrchr($path,'.'),'
'; //生成唯一的ID

echo uniqid('goods_').strrchr($path,'.'),'
'; //带有前缀

echo uniqid('goods_',true).strrchr($path,'.'),'
'; //唯一ID+随机数

1.7.2 验证文件格式

方法一:判断文件的扩展名(不能识别文件伪装)

操作思路:将文件的后缀和允许的后缀对比

if(!empty($_POST)) {

$allow=array('.jpg','.png','.gif'); //允许的扩展名

$ext=strrchr($_FILES['face']['name'],'.'); //上传文件扩展名

if(in_array($ext,$allow))

echo '允许上传';

else

echo '文件不合法';

}

?>

注意:比较扩展名不能防止文件伪装。

方法二:通过$_FIELS[]['type']类型(不能识别文件伪装)

if(!empty($_POST)) {

$allow=array('image/jpeg','image/png','image/gif'); //允许的类别

$mime=$_FILES['face']['type']; //上传文件类型

if(in_array($mime,$allow))

echo '允许上传';

else

echo '文件不合法';

}

?>

注意:比较$_FIELS[]['type']不能防止文件伪装。

方法三:php_fileinfo扩展(可以防止文件伪装)

​ 在php.ini中开启fileinfo扩展

extension=php_fileinfo.dll

注意:开启fileinfo扩展以后,就可以使用finfo_*的函数了

if(!empty($_POST)) {

//第一步:创建finfo资源

$info=finfo_open(FILEINFO_MIME_TYPE);

//var_dump($info); //resource(2) of type (file_info)

//第二步:将finfo资源和文件做比较

$mime=finfo_file($info,$_FILES['face']['tmp_name']);

//第三步,比较是否合法

$allow=array('image/jpeg','image/png','image/gif'); //允许的类别

echo in_array($mime,$allow)?'合法':'不合法';

}

?>

小结:验证文件格式有三种方法

1、可以验证扩展名(不可以防止文件伪装)

2、通过$_FILES[]['type']验证(不可以防止文件伪装)

3、通过file_info扩展(可以防止文件伪装)

1.7.3 优化文件上传例题

步骤

第一步:验证是否有误

第二步:验证格式

第三步:验证大小

第四步:验证是否是http上传

第五步:上传实现

/**

*验证错误

*如果有错,就返回错误,如果没错,就返回null

*/

function check($file) {

//1:验证是否有误

if($file['error']!=0){

switch($file['error']) {

case 1:

return '文件大小超过了php.ini中允许的最大值,最大值是:'.ini_get('upload_max_filesize');

case 2:

return '文件大小超过了表单允许的最大值';

case 3:

return '只有部分文件上传';

case 4:

return '没有文件上传';

case 6:

return '找不到临时文件';

case 7:

return '文件写入失败';

default:

return '未知错误';

}

}

//2、验证格式

$info=finfo_open(FILEINFO_MIME_TYPE);

$mime=finfo_file($info,$file['tmp_name']);

$allow=array('image/jpeg','image/png','image/gif'); //允许的类别

if(!in_array($mime,$allow)){

return '只能上传'.implode(',',$allow).'格式';

}

//3、验证大小

$size=123456789;

if($file['size']>$size){

return '文件大小不能超过'.number_format($size/1024,1).'K';

}

//4、验证是否是http上传

if(!is_uploaded_file($file['tmp_name']))

return '文件不是HTTP POST上传的
';

return null; //没有错误

}

//表单提交

if(!empty($_POST)) {

//上传文件过程中有错误就显示错误

if($error=check($_FILES['face'])){

echo $error;

}else{

//文件上传,上传的文件保存到当天的文件夹中

$foldername=date('Y-m-d'); //文件夹名称

$folderpath="./uploads/{$foldername}"; //文件夹路径

if(!is_dir($folderpath))

mkdir($folderpath);

$filename=uniqid('',true).strrchr($_FILES['face']['name'],'.'); //文件名

$filepath="$folderpath/$filename"; //文件路径

if(move_uploaded_file($_FILES['face']['tmp_name'],$filepath))

echo "上传成功,路径是:{$foldername}/{$filename}";

else

echo '上传失败
';

}

}

?>

运行结果

小结:

1、将时间戳转换格式

echo date('Y-m-d H:i:s',1231346),'
'; //将时间戳转成年-月-日 小时:分钟:秒

echo date('Y-m-d H:i:s'),'
'; //将当前的时间转成年-月-日 小时:分钟:秒

2、设置时区(php.ini)

PRC:中华人民共和国

3、PHP的执行可以不需要Apache的参与

1.8 作业

1、多文件上传

1.9 作业讲解

1、递归遍历文件夹

//获取文件夹的子级

function getFile($path) {

$folder=opendir($path); //打开文件夹

echo '

    ';

    while($f=readdir($folder)){ //读取文件夹

    if($f=='.' || $f=='..')

    continue;

    echo '

  • '.iconv('gbk','utf-8',$f).'
  • ';

    $subpath="{$path}/{$f}";

    if(is_dir($subpath)) //如果子级还是文件夹,继续打开并读取

    getFile($subpath);

    }

    echo '

';

}

//测试

getFile('./');

运行结果

2、一只猴子看守一堆桃子,第一天吃了一半后又多吃了1个,第二天一样,到第十天的时候就剩下一个桃子,请问原来有几个桃子?

分析

f(n)-(f(n)/2+1)=f(n+1)

=>f(n)/2-1=f(n+1)

=>f(n)=(f(n+1)+1)*2

代码实现

function getTao($n) {

if($n==10)

return 1;

return (getTao($n+1)+1)*2;

}

echo getTao(1); //1534

原文链接:

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。