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页面
<?phpphpinfo();
访问服务器
访问规则: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
# 拒绝所有请求访问
练习四:
<Directory "C:/PHP/Apache/htdocs">
Order deny, allow
Allow from 192.168.101.50
Deny from 192.168
</Directory>
# 拒绝192.168开头,但除去(192.168.101.50)的IP的访问
练习五:
<Directory "C:/PHP/Apache/htdocs">
Order deny, allow
Allow from 192.168.101.50
Deny from all
</Directory>
# 只允许192.168.101.50访问
练习六:
<Directory "C:/PHP/Apache/htdocs">
Order allow,deny
Allow from 192.168
Deny from 192.168.101.50
</Directory>
# 只允许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配置如下
<VirtualHost _default_:80>
DocumentRoot "C:\web1" #指定虚拟目录路径
ServerName www.baidu.com # 虚拟目录绑定的域名
DirectoryIndex aa.php # 默认首页
<Directory "C:\web1">
Options -Indexes -FollowSymLinks +ExecCGI
AllowOverride All
Order allow,deny
Allow from all
Require all granted
</Directory>
</VirtualHost>
<VirtualHost _default_:80>
DocumentRoot "C:\web2"
ServerName www.sina.com
DirectoryIndex bb.php
<Directory "C:\web2">
Options -Indexes -FollowSymLinks +ExecCGI
AllowOverride All
Order allow,deny
Allow from all
Require all granted
</Directory>
</VirtualHost>
在host文件中做dns解析
访问结果
补充:站点、虚拟目录、虚拟主机的区别
站点:站点就是一个文件夹,用来保存与网站有关的所有素材
虚拟目录:站点+权限
虚拟主机:虚拟目录+域名
1.6 PHP语法入门
1.6.1 PHP是编译型语言
编译语言和解释语言的区别在于是否保存最终的可执行程序。
PHP执行过程
1.6.2 PHP定界符
因为PHP是脚本语言,所以需要定界符
1、标准风格(推荐使用)
<?php
?>
例题
<?phpecho'i am a boy!';?>
提醒,如果整个页面都是PHP代码,PHP结束符是可以省略的(推荐)
<?phpecho'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():输出数据的详细信息,带有数据类型和数据长度
<?php
var_dump('abc'); //string(3) "abc"
?>
1.7 变量
变量的本质就是内存中的一段空间
1.7.1 变量的命名规则
- 变量必须以 开 头 , 开头, 开头,符不是变量的一部分,仅表示后面的标识符是变量名。
- 除了$以外,以字母、下划线开头,后面跟着数字、字母、下划线
- 变量名区分大小写, a a 和 aa和 aa和Aa是两个空间
下列变量是否合法
$a 合法
$a1 合法
$1a 不合法
$_1a 合法
注意:PHP语句必须以分号结尾
<?php$a=10;$name='Tom';?>
1.7.2 可变变量
变量名可以变,将变量名存储在另外一个变量中
例题
<?php$a=10;$b='a';echo$$b;//10
例题
<?php$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 变量传递
变量的传递有值传递和地址传递(引用传递)
<?php//值传递$num1=10;//将10付给$num1$num2=$num1;//将$num1的值付给$num2$num2=20;//更改$num2echo$num1;//10
//地址传递$num1=10;//将10付给$num1$num2=&$num1;//将$num1的地址付给$num2$num2=20;//更改$num2echo$num1;//20
小结:
1、参数的传递有两种,值传递和地址传递
2、&表示获取变量的地址
3、值传递中,一个变量变了,另一个变量没有影响,因为是两个空间
4、地址传递中,一个变量变了,另一个也变了,因为两个变量指向同一个空间
1.7.4 销毁变量
用unset()来销毁变量,销毁的是变量名,变量值由PHP垃圾回收机制销毁
<?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
常量名前没有$符
常量名推荐使用大写
例题:
<?phpdefine('NAME','tom');//定义常量define('PI',3.14,true);//定义常量,不区分大小写echoNAME,'<br>',Pi;//true表示不区分大小写,默认是区分大小写的。
2、定义常量可以用特殊字符,但是在调用的时候必须用
constant
关键字调用
define('%-%','tom');echoconstant('%-%');//通过constant获取特殊字符作为常量名的常量
3、判断常量是否定义,通过defined()判断常量是否已经定义
if(!defined('NAME')){define('NAME','berry');}echoNAME;//berry
4、还可以使用const关键字定义常量
constNAME='tom';echoNAME;//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)]
例题
echoPHP_VERSION,'<br>';//PHP版本号echoPHP_OS,'<br>';//PHP操作系统echoPHP_INT_MAX,'<br>';//PHP中整型的最大值
1.2.3 魔术常量
魔术常量它们的值随着它们在代码中的位置改变而改变
echo__LINE__,'<br>';//获取当前行号echo__FILE__,'<br>';//文件的完整路径和文件名echo__DIR__,'<br>';//文件所在的目录
1.3 数据类型
数据类型有两种:强类型和弱类型
PHP是弱类型
1.3.1 基本类型(标量类型)
1、整型
存整数,PHP_INT_MAX获取整形最大值
PHP支持8、10、16机制的整数
<?php$num1=10;//十进制$num2=010;//八进制(数字前面加0)$num3=0x10;//十六进制(数字前面加0x)echo$num1,'<br>';//10echo$num2,'<br>';//8echo$num3;//16
进制转换
机制缩写单词十进制decdecimalist二进制binbinary八进制octoctonary十六进制hexhexdecimalist
例题
PHP提供了进制转换函数
echodecbin(123),'<br>';//十进制转二进制echobindec(1111011),'<br>';//二进制转十进制echodechex(123),'<br>';//十进制转十六进制echohexdec('7b'),'<br>';//十六进制转十进制echodecoct(123);//十进制转八进制
2、浮点型
浮点数在内存中保存的是近似值
浮点数不能参与比较
var_dump(0.9==(1-0.1));//bool(true) echo'<br>';var_dump(0.1==(1-0.9));//bool(false)
如果浮点数要比较,必须确定比较的位数
var_dump(0.9==(1-0.1));//bool(true) echo'<br>';var_dump(0.1==(1-0.9));//bool(false) echo'<br>';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','<br>';//我的名字叫$nameecho"我的名字叫$name",'<br>';//我的名字叫tom
例题:{ }取变量值
$name='tom';echo'$name是我的名字','<br>';//$name是我的名字echo"{$name}是我的名字",'<br>';//{}表示获取变量的值(tom是我的名字)echo"${name}是我的名字",'<br>';//$和{只要挨着一起就可以(tom是我的名字)
输出特殊字符
echo'毛主席说:\'上课不要睡觉\'','<br>';//转义字符 毛主席说:'上课不要睡觉'echo'文件保存在c:\\';//文件保存在c:\
字符串定界符
1、有<<<开头,后面跟的是标识符
2、字符串定界符的结束符必须顶格写,前面不能有任何的空白字符
3、字符串定界符分为两种,heredoc(双引号),nowdoc(单引号)
1.3.2 复合类型
1、数组
在PHP中数组有两种形式,索引数组和关联数组
索引数组:用整数做下标,默认从0开始,后面依次加一
关联数组:用字符串做下标,通过=>符号将下标和值关联起来
例题:数组的声明
<?php//1、索引数组的声明$stu=array('tom','berry','ketty');//索引数组print_r($stu);//输出数组 Array ( [0] => tom [1] => berry [2] => ketty ) echo'<hr>';echo$stu[0],'<br>';//tomecho$stu[1],'<br>';//berryecho$stu[2],'<hr>';//ketty------------------------------------------//2、关联数组$emp=array('name'=>'李白','sex'=>'男','age'=>22);print_r($emp);//Array ( [name] => 李白 [sex] => 男 [age] => 22 ) echo'<hr>';echo$emp['name'],'<br>';//李白echo$emp['sex'],'<br>';//男echo$emp['age'];//22
练习:写出数组的下标
$array=array(1=>'a','b','c','d');print_r($array);//Array ( [1] => a [2] => b [3] => c [4] => d ) echo'<br>';--------------------------$array=array('a',2=>'b','c',5=>'d');print_r($array);//Array ( [0] => a [2] => b [3] => c [5] => d ) echo'<br>';----------------------------$array=array('a','name'=>'b','c','sex'=>'d');print_r($array);//Array ( [0] => a [name] => b [1] => c [sex] => d ) echo'<br>';------------------------------$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,'<br>',$num2;
二维数组的声明
$stu=[['name'=>'tom','sex'=>'男','age'=>22],['name'=>'berry','sex'=>'女','age'=>23]];echo'<pre>';print_r($stu);//运行结果Array([0]=>Array([name]=> tom
[sex]=> 男
[age]=>22)[1]=>Array([name]=> berry
[sex]=> 女
[age]=>23))
多学一招:字符串可以通过数组的方式去调用
echo'abc'[0],'<br>';//a echo'abc'[-1],'<br>';//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、强制类型转换
语法:(数据类型)数据
<?php$num1='12';var_dump($num1,(int)$num1,(float)$num1);//string(2) "12" int(12) float(12)
其他类型和布尔之间的转换
规则:0、空为假,非0非空为真
<?phpvar_dump((bool)'abc');echo'<br>';//bool(true) var_dump((bool)'');echo'<br>';//bool(false) var_dump((bool)'0');echo'<br>';//bool(false) var_dump((bool)'0.0');echo'<br>';//bool(true) var_dump((bool)'00');echo'<br>';//bool(true) var_dump((bool)'false');echo'<br>';//bool(true) var_dump((bool)'null');echo'<br>';//bool(true) var_dump((bool)1);echo'<br>';//bool(true) var_dump((bool)0);echo'<br>';//bool(false) var_dump((bool)-10);echo'<br>';//bool(true) var_dump((bool)0.0);echo'<br>';//bool(false) var_dump((bool)array());echo'<br>';//bool(false) var_dump((bool)array(1));echo'<br>';//bool(true) var_dump((bool)array(false));echo'<br>';//bool(true) var_dump((bool)null);echo'<br>';//bool(false)
1.4 运算符
1.4.1 算术运算符
一元运算符二元运算符+++–-*/% (取模)
注意:在PHP中,算术运算符只能做数学运算。
<?phpecho'10'+'20','<br>';//30echo'10ab'+'20cd','<br>';//30echo'ab10'+'cd20','<br>';//0
++前置:先自增再运算
++后置:先运算再自增
练习
$num=10;$num++;echo$num;//11-------------------------$num=10;echo$num++;//10------------------------$num=10;echo++$num;//11
练习
<?php$num=5;echo(++$num)+(++$num)+(++$num);//21-------------------------<?php$num=5;echo($num++)+($num++)+($num++);//18
1.4.2 关系运算符(比较运算符)
>
>=
<
<=
==
!=
===
!==
比较运算符的运算结果是布尔值
1.4.3 逻辑运算符
& 与:运算符两边的表达式都要计算
| 或:运算符两边的表达式都要计算
&& 短路与:如果前面的条件不满足,后面的条件就不用计算了
|| 短路或
! 非
例题
<?php$a=5;$b=10;if($a>10&&++$a>20)echo'你好吗';echo$a;//5//分析:$a>10为false, 与中只要有一个是false,另一个不用计算结果肯定是false,所以短路与++a就不计算了,结果是5----------------------------<?php$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 错误抑制符(@)
错误抑制符只对表达式有效
<?phpecho @($aa+$bb);//错误抑制
1.4.7 三元运算符(?😃
语法:
表达式?值1:值2
//表达式的值为true,返回值1,否则返回值2
练习
<?php$num=11;echo$num%2?'奇数':'偶数';
1.4.8 null合并运算符(??)
PHP7.0以后才支持
例题
<?phpecho$name??'姓名不详';//姓名不详
多学一招:两个用来判断的函数
isset():判断变量是否被设置,并且设置的不是null
empty():检查一个变量是否为空,能转成false全部是空,['',0,0.0,array(),null]
例题
echoisset($name)?$name:'姓名不详';//姓名不详echo'<hr>';$stu=array();echoempty($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、在服务器获取提交的数据,并判断
代码实现
<body>
<?php
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 '您输入的不是数字';
}
}
}
?>
<form method="post" action="">
请输入年份: <input type="text" name="year"> <br />
<input type="submit" name="button" value="判断闰年">
</form>
</body>
运行结果
小结:
1、$_POST是一个变量,用来保存post提交的数据
2、action=''表示将数据提到本页面
3、is_numeric()判断变量是否是数字或字符串数字
4、is_int()判断变量是否是整型
5、if、else后面如果只是一句代码,大括号可以省略
例题二:判断成绩(练习多分支)
目标:输入语文和数学,判断等级
代码实现
<body>
<?php
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}<br>";
if($avg>=90)
echo 'A';
elseif($avg>=80)
echo 'B';
elseif($avg>=70)
echo 'C';
elseif($avg>=60)
echo 'D';
else
echo 'E';
}
}
?>
<form method="post" action="">
语文: <input type="text" name="ch"> <br />
数学: <input type="text" name="math"> <br />
<input type="submit" name="button" value="判断成绩">
</form>
</body>
运行结果
例题三:更改颜色(switch-case)
目标:将文字的颜色改成选择的颜色
<body>
<?php
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
<script type="text/javascript">
window.οnlοad=function(){
document.getElementById('shi').style.color='$color';
}
</script>
str;
}
?>
<div id="shi">
锄禾日当午, <br />
汗滴禾下土。 <br />
谁知盘中餐, <br />
粒粒皆辛苦。 <br />
</div>
<form method="post" action="">
<select name="color">
<option value="0">请选择颜色</option>
<option value="1">红色</option>
<option value="2">绿色</option>
<option value="3">蓝色</option>
</select>
<input type="submit" name="button" value="更改颜色">
</form>
</body>
运行结果
1.6 作业
计算器
1.2 循环
1.2.1 for
for(初始值;条件;增量){//循环体}
注意:循环中千万不能出现死循环
思考:如下代码输出什么
例题一:
<?phpfor($i=1;$i<=10;$i+=2){echo"{$i}:锄禾日当午<br>";}/*
1:锄禾日当午
3:锄禾日当午
5:锄禾日当午
7:锄禾日当午
9:锄禾日当午
*/
例题二:
<?phpfor($i=1;$i<=10;){}//死循环,$i永远等于1,1永远小于10,条件永远为true
例题三
<?phpfor($i=1;;$i++){}//死循环,只要没有条件都是死循环
例题四
<?phpfor(;;){}//这是一个经典的死循环
1.2.3 思考题
1、如下代码循环了几次?
for($i=1;$i!=5;$i++){}//循环了4次
2、在循环N次循环体中,初始值执行了几次?条件执行了几次?增量执行了几次?
初始值执行了1次
条件执行了N+1次
增量执行了N次
3、在循环执行完毕后,$i的值是存在的。
<?phpfor($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
<?php//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,'<br>';//5050//可以有如下更改$i=1;$sum=0;do{$sum+=$i++;//++后置}while($i<=100);echo$sum,'<br>';//5050//可以做如下更改$i=1;$sum=0;do{$sum+=$i;}while(++$i<=100);//++前置echo$sum,'<br>';//5050
小结:
1、for、while、do-while可以相互替换
2、结合++前置和++后置考虑逻辑
1.2.6 多语句表达式
初始值、增量可以由多条语句组成
例题:数字分解
<?phpfor($i=1,$j=9;$i<=$j;$i++,$j--){echo"10可以分成{$i}和{$j}<br>";}//运行结果/*
10可以分成1和9
10可以分成2和8
10可以分成3和7
10可以分成4和6
10可以分成5和5
*/
小结:初始值、增量可以写多个表达式,但是条件一般只写一个,如果条件写多个,只是最后一个条件起作用
1.2.7 双重循环
1、打印阶梯数字
<?phpfor($i=1;$i<=9;$i++){//循环行for($j=1;$j<=$i;$j++){//循环列echo$j,' ';}echo'<br>';}//运行结果112123123412345123456123456712345678123456789
2、打印九九乘法表
<style type="text/css">
table{
width:980px;
}
table,td{
border:solid 1px #0000FF;
border-collapse:collapse;
}
td{
height:40px;
}
</style>
<table>
<?php
for($i=1;$i<=9;$i++){ //行
echo '<tr>';
for($j=1;$j<=$i;$j++){ //列
echo "<td>{$j}*{$i}=".($j*$i).'</td>';
}
echo '</tr>';
}
?>
</table>
运行结果
小结:规则:当前列*当前行
1.28 foreach
foreach循环是用来遍历数组
语法
//语法一foreach(数组 as 值){}//语法二foreach(数组 as 键=>值){}
例题
<?php$stu=['tom','berry','ketty'];foreach($stuas$v){echo$v,'<br>';}/**
tom
berry
ketty
*/echo'<hr>';-----------------------------------------------------------foreach($stuas$k=>$v){echo"{$k}:{$v}<br>";}/**
0:tom
1:berry
2:ketty
*/
1.3 跳转语句
1.3.1 语法
break:中断循环
continue:中断当前循环,进入下一个循环
例题:
<?phpfor($i=1;$i<=10;$i++){if($i==5)break;//中断循环echo"{$i}:锄禾日当午<br>";}//结果1:锄禾日当午
2:锄禾日当午
3:锄禾日当午
4:锄禾日当午
--------------------------------------------------<?php
for($i=1;$i<=10;$i++){if($i==5)continue;//跳出5,进入6循环echo"{$i}:锄禾日当午<br>";}1:锄禾日当午
2:锄禾日当午
3:锄禾日当午
4:锄禾日当午 //注意,没有打印第5句6:锄禾日当午
7:锄禾日当午
8:锄禾日当午
9:锄禾日当午
10:锄禾日当午
1.3.2 中断多重循环
break和continue默认中断、跳出1重循环,如果调中断、跳出多重循环,在后面加一个数字。
<?phpfor($i=1;$i<=10;$i++){for($j=1;$j<=$i;$j++){echo$j.' ';if($j==5){break2;//中断2重循环}}echo'<br>';}//运行结果112123123412345
练习
<?phpfor($i=1;$i<=10;$i++){switch($i){case5:break2;}echo$i,'<br>';}//结果1234
小结:switch的本质是循环了一次的循环
1.4 替代语法
php中除了do-while以外,其他的语法结构都有替代语法
规则:左大括号变冒号,右大括号变endXXX
//if的替代语法
if():
elseif():
else:
endif;
//switch替代语法
switch():
endswitch;
//for
for():
endfor;
//while
while():
endwhile;
//foreach
foreach():
endforeach;
例题:在混编的时候用替代语法
<body>
<?php
for($i=1;$i<=10;$i++):
if($i%2==0):
?>
<?php echo $i;?>:锄禾日当午<br>
<?php
endif;
endfor;
?>
</body>
//运行结果
2:锄禾日当午
4:锄禾日当午
6:锄禾日当午
8:锄禾日当午
10:锄禾日当午
小结:可以通过替代语法证明else if之间如果有空格是嵌套if语句。
<?php$score=80;if($score>=90):echo'A';elseif($score>=80)://elseif之间没有空格,如果有空格是嵌套if语句echo'B';else:echo'C';endif;----------------------------------------<?php$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,...){//函数体}
通过函数名()调用函数
<?php//定义函数functionshow(){echo'锄禾日当午<br>';}//调用show();//锄禾日当午SHOW();//锄禾日当午 函数名不区分大小写
小结:
1、变量名区分大小写
2、关键字、函数名不区分大小写
1.5.2 可变函数
将函数名存储到变量中
<?phpfunctionshow($args){echo$args,'<br>';}$str='show';//将函数名保存到变量中$str('锄禾日当午');
例题:随机调用函数
<?php//中文显示functionshowChinese(){echo'锄禾日当午<br>';}//英文显示functionshowEnglish(){echo'chu he re dang wu<br>';}//测试$fun=rand(1,10)%2?'showChinese':'showEnglish';//可变变量$fun();
1.5.3 匿名函数
匿名函数就是没有名字的函数
<?php//匿名函数$fun=function(){echo'锄禾日当午<br>';};//匿名函数调用$fun();
1.5.4 参数传递
函数的参数有形式参数和实际参数
形式参数是定义函数时候的参数,只起形式的作用,没有具体的值
实际参数的调用函数时候的参数,有具体的值
<?phpfunctionfun($num1,$num2){echo$num1+$num2;}fun(10,20);//30
默认情况下,参数的传递是值传递
<?php$num=10;functionfun($args){$args=100;}fun($num);echo$num;//10
地址传递
<?php$num=10;//地址传递functionfun(&$args){//&符表示取地址$args=100;}fun($num);echo$num;//100
小结
1、函数的参数默认是值传递
2、如果要传递地址,在参数前面加&
3、如果是地址传递,不能直接写值
functionfun(&$args){$args=100;}fun(10);//Fatal error: Only variables can be passed by reference (只有变量才能传递引用)
1.5.5 参数默认值
1、在定义函数的时候给形参赋值就是参数的默认值
<?php//参数的默认值functionfun($name,$add='地址不详'){echo'姓名:'.$name,'<br>';echo'地址:'.$add,'<hr>';}//测试fun('tom','北京');fun('berry');
2、默认值必须是值,不能用变量代替
<?php$str='地址不详'functionfun($name,$add=$str){//错误,默认值可以使用变量echo'姓名:'.$name,'<br>';echo'地址:'.$add,'<hr>';}
3、默认值可以使用常量
<?phpdefine('ADD','地址不详');functionfun($name,$add=ADD){//默认值可以使用常量echo'姓名:'.$name,'<br>';echo'地址:'.$add,'<hr>';}//测试fun('berry');
4、有默认值的写在后面,没有默认值的写在前面
<?php//没有默认值的写在前面,有默认值写在后面functionfun($name,$age='未知',$add='地址不详'){echo"姓名:{$name}<br>";echo"年龄:{$age}<br>";echo"地址:{$add}<br>";}fun('tom');//运行结果
姓名:tom
年龄:未知
地址:地址不详
1.5.6 参数个数不匹配
<?phpfunctionfun($num1,$num2){echo$num1,'<br>';echo$num2,'<br>';}//fun(10); //实参少于形参(报错)fun(10,20,30);//实参多于形参,只取前面对应的值
获取所有传递的参数
<?phpfunctionfun(){//echo func_num_args(),'<br>'; //获取参数的个数$args=func_get_args();//获取参数数组print_r($args);}fun(10);fun(10,20);fun(10,20,30);
1.5.7 参数约束
1、定义变长参数(了解)
<?php// ...$hobby包含了除了前面两个参数以外的所有参数functionfun($name,$age,...$hobby){echo'姓名:'.$name,'<br>';echo'年龄:'.$age,'<br>';print_r($hobby);echo'<hr>';}fun('tom',22);fun('berry',25,'读书','睡觉');
运行结果
多学一招:
functionfun(...$args){print_r($args);echo'<br>';}$num=[10,20];echo'<pre>';fun(...$num);//将数组中的参数展开//运行结果/*
Array
(
[0] => 10
[1] => 20
)
*/
2、参数类型约束
//类型约束functionfun(string$name,int$age){echo"姓名:{$name},'<br>'";echo"年龄:{$age}<br>";}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 终止脚本执行
<?phpecho'锄禾日当午<br>';return;//终止脚本执行echo'汗滴禾下土<br>';//不执行
提醒:return只能中断当前页面,如果有包含文件,只能中断包含文件
例题:
6-demo.php
<?phpecho'锄禾日当午<br>';require'./test.php';//包含文件echo'汗滴禾下土<br>';
test.php
<?phpecho'aaa<br>';return;//只能中断test.phpecho'bbb<br>';
运行结果
如果要完全终止脚本执行,使用exit()、或die()
echo'aaa<br>';exit();//die()echo'bbb<br>';
1.6.2、返回页面结果
test.php
<?phpreturnarray('name'=>'tom','sex'=>'男');
6-demo.php
<?php$stu=require'./test.php';print_r($stu);//Array ( [name] => tom [sex] => 男 )
小结:在项目中引入配置文件就使用这种方法
1.6.3 函数的返回和终止
return在函数中使用作用有二
1、终止函数执行
2、返回值
functionfun(){echo'aaa';return;//终止函数执行echo'bbb';}fun();//aaa----------------------------------functionfun(){return10;//返回值}echofun();//10
1.7 作业讲解
计算器
<body>
<?php
$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;
}
}
?>
<form method="post" action="">
<input type="text" name="num1" value='<?php echo $num1?>'>
<select name="op">
<option value="+" <?php echo $op=='+'?'selected':''?>>+</option>
<option value="-" <?php echo $op=='-'?'selected':''?>>-</option>
<option value="*" <?php echo $op=='*'?'selected':''?>>*</option>
<option value="/" <?php echo $op=='/'?'selected':''?>>/</option>
</select>
<input type="text" name="num2" value='<?php echo $num2?>'>
<input type="submit" name="button" value="=">
<input type="text" name="result" value='<?php echo $result?>'>
</form>
</body>
运行结果
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、超全局变量:可以在函数内部和函数外部访问
<?php
$num=10;
function fun() {
echo $num; //Notice: Undefined variable: num
}
fun();
//函数内部默认不能访问函数外部的值
---------------------
<?php
$_POST['num']=10; //将值付给超全局变量
function fun() {
echo $_POST['num']; //获取超全局的值 10
}
fun();
----------------------------
<?php
function fun() {
$_GET['num']=10; //将值付给超全局变量
}
fun();
echo $_GET['num']; //打印超全局变量的值 10
在函数内部访问全局变量
<?php$num=10;//全局变量functionfun(){echo$GLOBALS['num'];//输出全局的$num}fun();
练习:如下代码输出什么
<?phpfunctionfun(){$GLOBALS['num']=10;//将值付给全局的$num}fun();echo$num;//10
global关键字
<?php$num=10;functionfun(){global$num;//将全局变量的$num的地址引入到函数内部 相当于$num=&GLOBALS['num']echo$num;//10$num=100;}fun();echo'<br>';echo$num;//100-----------------------------------<?php$num=10;functionfun(){global$num;unset($num);//销毁的是引用,不是具体的值}fun();echo$num;//10
小结:
1、$GLOBALS保存的是全局变量的所有的值
<?php$a=10;$b=20;functionshow(){echo'<pre>';var_dump($GLOBALS);//是一个数组,保存的是全局变量的所有的值}show();
2、global用于创建一个全局变量的引用
注意:常量没有作用域的概念
<?php/*
define('PI',3.14);
function fun() {
echo PI; //3.14
}
fun();
echo '<br>';
*/-------------------------------------functionfun(){define('PI',3.14);}fun();echoPI;//3.14
1.2.2 静态变量(static)
静态变量一般指的是静态局部变量。
静态变量只初始化一次
<?phpfunctionfun(){$num=10;//普通变量每调用一次初始化一次,调用完毕销毁$num++;echo$num,'<br>';}fun();//11fun();//11--------------------------------<?php
functionfun(){static$num=10;//静态变量只初始化一次,调用完毕吧不销毁,第二次调用的时候就不再初始化$num++;echo$num,'<br>';}fun();//11fun();//12
常量和静态变量的区别
1、常量和静态变量都是初始化一次
2、常量不能改变值,静态变量可以改变值
3、常量没有作用域,静态变量有作用域
<?phpfunctionfun1(){define('num',10);}functionfun2(){echo num;//10}fun1();fun2();------------------------------------------------------------<?php
functionfun1(){static$num=10;}functionfun2(){echo$num;//Notice: Undefined variable: num 因为静态变量是有作用域的}fun1();fun2();
1.2.3 匿名函数use()
默认情况下,函数内部不能访问函数外部的变量,但在匿名函数中,可以通过use将外部变量引入匿名函数中
<?php$num=10;$fun=function()use($num){//将$num引入到匿名函数中echo$num;};$fun();//10
思考:如何在函数内部访问函数外部变量
1、使用超全局变量
2、$GLOBALS
3、global
4、use将函数外部变量引入到匿名函数内部
练习:如果代码输出什么
<?php$num=10;functiontest(){$num=20;$fun=function()use($num){//只能引入一层echo$num;};$fun();}test();//20
多学一招:use可以引入值,也可以引入地址
<?php$num=10;$fun=function()use(&$num){//use可以传地址$num=100;};$fun();echo$num;//100
1.3 递归
函数内部自己调用自己
递归有两个元素,一个是递归点(从什么地方递归),第二递归出口
例题1:输出9 8 7 6 …
<?phpfunctionprinter($num){echo$num,' ';if($num==1)//递归出口return;printer($num-1);//递归点}printer(9);//9 8 7 6 5 4 3 2 1
例题2:从1加到100
functioncal($num){if($num==1)return1;return$num+cal($num-1);}echocal(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个斐波那契数functionfbnq($n){if($n==1||$n==2)return1;returnfbnq($n-1)+fbnq($n-2);//第n个斐波那契数等于前两个数之和}echofbnq(5),'<br>';/**
*分析:
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++)echofbnq($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,这样包含就只要写文件名就可以了
<?phpset_include_path('c:\aa\bb\cc\dd');//设置include_pathrequire'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=’地址’:错误日志保存的地址
在项目开发过程中有两个模式,开发模式,运行模式
开发模式:错误显示在浏览器上,不要记录在日志中
运行模式:错误不显示在浏览器上,记录是日志中
例题
<?php$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 信息
<?php$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。
定义错误处理函数
functionerror(){echo'这是自定义错误处理';}set_error_handler('error');//注册错误处理函数,只要有错误就会自动的调用错误处理函数echo$num;
运行结果
处理处理函数还可以带有参数
/**
*自定义错误处理函数
*@param $errno int 错误类别
*@param $errstr string 错误信息
*@param $errfile string 文件地址
*@param $errline int 错误行号
*/functionerror($errno,$errstr,$errfile,$errline){switch($errno){caseE_NOTICE:caseE_USER_NOTICE:echo'记录在日志中,上班后在处理<br>';break;caseE_WARNING:caseE_USER_WARNING:echo'给管理员发邮件<br>';break;caseE_ERROR:caseE_USER_ERROR:echo'给管理员打电话<br>';break;}echo"错误信息:{$errstr}<br>";echo"错误文件:{$errfile}<br>";echo"错误行号:{$errline}<br>";}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:目录,文件夹
例题
<?php//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()】
echois_dir('./aaa')?'是文件夹':'不是文件夹';
5、打开文件夹、读取文件夹、关闭文件夹
$folder=opendir('./');//打开目录//var_dump($folder); //resource(3) of type (stream) while($f=readdir($folder)){//读取文件夹if($f=='.'||$f=='..')continue;echoiconv('gbk','utf-8',$f),'<br>';//将gbk转成utf-8}closedir($folder);//关闭文件夹
小结:
1、opendir()返回资源类型
2、每个文件夹中都有.和..
3、iconv()用来做字符编码转换
1.7 作业讲解
1、 通过for循环将数组中值求和、求平均值
<?php
//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,'<br>'; //和是:138
echo '平均值:'.number_format($sum/count($num),1); //精确到小数点后面1位 平均值:19.7
echo '<hr>';
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<count($stu);$i++){//循环第一列for($j=0;$j<count($stu[$i]);$j++){//循环第二列echo$stu[$i][$j],' ';}echo'<br>';}//运行结果123410203040
4、 循环输出1-100,其中3的倍数输出A,5的倍数输出B,15输出C。
for($i=1;$i<=100;$i++){if($i%15==0)//先写%15,,因为可以%15的值一定可以%3和%5echo'C';elseif($i%3==0)echo'A';elseif($i%5==0)echo'B';elseecho$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,'<br>';}//pow($a,3) 表示$a的三次方//运行结果153370371407
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、将字符串写入文件
<?php$str="床前明月光,\r\n疑是地上霜。\r\n举头望明月,\r\n低头思故乡。";file_put_contents('./test.txt',$str);//将字符串写到文本中
小结:
1、 所有的“写”操作都是清空重写
2、在文本中换行是\r\n
\r:回车 光标移动到当前行的最前面
\n:换行 将光标下移动一行
按键盘的回车键做了两步,第一步将光标移动到当前行的最前面,第二步下移一行。
3、\r\n是特殊字符,必须放在双引号内
2、将整个文件读入一个字符串
//方法一:echofile_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,'<br>';
}
*///3.3 打开文件追加$fp=fopen('./test.txt','a');//打开文件追加fputs($fp,'在河之洲');//在文件末尾追加
小结:
1、打开文件,返回文件指针(文件指针就是文件地址),资源类型
2、打开文件写、追加操作,如果文件不存在,就创建新的文件
3、打开文件读操作,文件不存在就报错
4、fputs()写一行,fgets()读一行,fclose()关闭文件
5、追加是在文件的末尾追加
4、是否是文件【is_file()】
echois_file('./test.txt')?'是文件':'不是文件';
5、判断文件或文件夹是否存在【file_exists()】
echofile_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图片方式解析echofread($fp,filesize($path));//二进制读取
多学一招:file_get_contents()也可以进行二进制读取
header('content-type:image/jpeg');echofile_get_contents('./face.jpg');
小结:
1、文本流有明确的结束符,二进制流没有明确的结束符,通过文件大小判断文件是否读取完毕
2、file_get_contents()既可以进行字符流读取,也可以进行二进制读取。
1.3 表单提交数据的两种方式
1.3.1 两种方式
1、get
2、post
<formmethod="post"action=""></form><formmethod="get"action=""></form>
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跳转
<a href="index.php?name=tom&age=20">跳转</a>
2、JS跳转
<script type="text/javascript">
location.href='index.php?name=tom&age=20';
location.assign('index.php?name=tom&age=20');
location.replace('index.php?name=tom&age=20');
</script>
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页面
<body><!--表单提交数据--><formmethod="get"action="./2-demo2.php">
语文: <inputtype="text"name="ch"><br/>
数学: <inputtype="text"name="math"><br/><inputtype="submit"name="button"value="提交"><br><br></form><!--超链接提交数据--><ahref="2-demo2.php?ch=77&math=88">跳转</a><br><br><!--js提交数据--><inputtype="button"value="点击"onclick="location.href='2-demo2.php?ch=66&math=55'"><br><br><inputtype="button"value="点击"onclick="location.assign('2-demo2.php?ch=11&math=22')"></body>
PHP页面
<?php//post数组中不为空if(!empty($_POST)){echo'这是post提交的数据<br>';echo'语文:'.$_POST['ch'],'<br>';echo'数学:'.$_POST['math'],'<br>';}echo'<hr>';//获取get提交的数据if(!empty($_GET)){echo'这是get提交的数据<br>';echo'语文:'.$_GET['ch'],'<br>';echo'数学:'.$_GET['math'],'<br>';}echo'<hr>';//既能获取get又能获取post提交的数据echo$_REQUEST['ch'],'<br>';echo$_REQUEST['math'];
思考题
在一个请求中,既有get又有post,get和post传递的名字是一样的,这时候通过$_REQUET获取的数据是什么?
答:结果取决于配置文件
request_order ="GP"# 先获取GET,在获取POST值
例题
<?php
if(!empty($_POST)){
echo '姓名:'.$_REQUEST['username'],'<br>';
}
?>
<form method="post" action="?username=berry">
姓名: <input type="text" name="username"><br />
<input type="submit" name="button" value="提交">
</form>
分析:先获取GET的username,再获取post的username,后面的将前面的值覆盖
小结:
1、在开发的时候,如果明确是post提交就使用
$_POST
获取,如果明确get提交就用
$_GET
获取
2、request获取效率低,尽可能不要使用,除非提交的类型不确定的情况下才使用。
1.5 参数传递
1.5.1 复选框值的传递
复选框的命名要注意带’[]'。
<body>
<?php
if(isset($_POST['button'])) {
print_r($_POST['hobby']);
}
?>
<form method="post" action="">
爱好:
<input type="checkbox" name="hobby[]" value='爬山'>爬山
<input type="checkbox" name="hobby[]" value='抽烟'>抽烟
<input type="checkbox" name="hobby[]" value='喝酒'>喝酒
<input type="checkbox" name="hobby[]" value='烫头'>烫头
<input type="submit" name="button" value="提交">
</form>
</body>
小结:
1、表单提交到本页面需要判断一下是否有post提交
2、数组的提交表单元素的名字必须带有[]。
1.5.2 例题
<body>
<?php
if(isset($_POST['button'])) {
echo '姓名:'.$_POST['username'].'<br>';
echo '密码:'.$_POST['pwd'].'<br>';
echo '性别:'.$_POST['sex'].'<br>';
echo '爱好:',isset($_POST['hobby'])?implode(',',$_POST['hobby']):'没有爱好','<br>';
echo '籍贯:'.$_POST['jiguan'],'<br>';
echo '留言:'.$_POST['words'];
}
?>
<form method="post" action="">
姓名: <input type="text" name="username"> <br />
密码: <input type="password" name="pwd"> <br />
性别: <input type="radio" name="sex" value='1' checked>男
<input type="radio" name="sex" value='0'>女 <br />
爱好:
<input type="checkbox" name="hobby[]" value='爬山'>爬山
<input type="checkbox" name="hobby[]" value='抽烟'>抽烟
<input type="checkbox" name="hobby[]" value='喝酒'>喝酒
<input type="checkbox" name="hobby[]" value='烫头'>烫头 <br />
籍贯:
<select name="jiguan">
<option value="021">上海</option>
<option value="010">北京</option>
</select> <br>
留言: <textarea name="words" rows="5" cols="30"></textarea> <br />
<input type="submit" name="button" value="提交">
</form>
</body>
运行结果
1.6 文件上传
开发中需要上传图片、音乐、视频等等,这种上传传递是二进制数据。
1.6.1 客户端上传文件
文件域
<inputtype="file"name="image">
表单的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(临时地址,目标地址)
代码
<body>
<?php
if(!empty($_POST)) {
if($_FILES['face']['error']==0){ //上传正确
//文件上传
move_uploaded_file($_FILES['face']['tmp_name'],'./'.$_FILES['face']['name']);
}else{
echo '上传有误';
echo '错误码:'.$_FILES['face']['error'];
}
}
?>
<form method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</form>
</body>
小结:上传的同名的文件要给覆盖
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 更改文件名
方法一:通过时间戳做文件名
<?php$path='face.stu.jpg';//echo strrchr($path,'.'); //从最后一个点开始截取,一直截取到最后echotime().rand(100,999).strrchr($path,'.');
方法二:通过uniqid()实现
$path='face.stu.jpg';echouniqid().strrchr($path,'.'),'<br>';//生成唯一的IDechouniqid('goods_').strrchr($path,'.'),'<br>';//带有前缀echouniqid('goods_',true).strrchr($path,'.'),'<br>';//唯一ID+随机数
1.7.2 验证文件格式
方法一:判断文件的扩展名(不能识别文件伪装)
操作思路:将文件的后缀和允许的后缀对比
<body>
<?php
if(!empty($_POST)) {
$allow=array('.jpg','.png','.gif'); //允许的扩展名
$ext=strrchr($_FILES['face']['name'],'.'); //上传文件扩展名
if(in_array($ext,$allow))
echo '允许上传';
else
echo '文件不合法';
}
?>
<form method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</form>
</body>
注意:比较扩展名不能防止文件伪装。
方法二:通过
$_FIELS[]['type']
类型(不能识别文件伪装)
<body>
<?php
if(!empty($_POST)) {
$allow=array('image/jpeg','image/png','image/gif'); //允许的类别
$mime=$_FILES['face']['type']; //上传文件类型
if(in_array($mime,$allow))
echo '允许上传';
else
echo '文件不合法';
}
?>
<form method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</form>
</body>
注意:比较
$_FIELS[]['type']
不能防止文件伪装。
方法三:php_fileinfo扩展(可以防止文件伪装)
在php.ini中开启fileinfo扩展
extension=php_fileinfo.dll
注意:开启fileinfo扩展以后,就可以使用finfo_*的函数了
<body>
<?php
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)?'合法':'不合法';
}
?>
<form method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</form>
</body>
小结:验证文件格式有三种方法
1、可以验证扩展名(不可以防止文件伪装)
2、通过
$_FILES[]['type']
验证(不可以防止文件伪装)
3、通过file_info扩展(可以防止文件伪装)
1.7.3 优化文件上传例题
步骤
第一步:验证是否有误
第二步:验证格式
第三步:验证大小
第四步:验证是否是http上传
第五步:上传实现
<body>
<?php
/**
*验证错误
*如果有错,就返回错误,如果没错,就返回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上传的<br>';
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 '上传失败<br>';
}
}
?>
<form method="post" action="" enctype='multipart/form-data'>
<input type="file" name="face">
<input type="submit" name="button" value="上传">
</form>
</body>
运行结果
小结:
1、将时间戳转换格式
echodate('Y-m-d H:i:s',1231346),'<br>';//将时间戳转成年-月-日 小时:分钟:秒echodate('Y-m-d H:i:s'),'<br>';//将当前的时间转成年-月-日 小时:分钟:秒
2、设置时区(php.ini)
PRC:中华人民共和国
3、PHP的执行可以不需要Apache的参与
1.8 作业
1、多文件上传
1.9 作业讲解
1、递归遍历文件夹
<?php//获取文件夹的子级functiongetFile($path){$folder=opendir($path);//打开文件夹echo'<ul>';while($f=readdir($folder)){//读取文件夹if($f=='.'||$f=='..')continue;echo'<li>'.iconv('gbk','utf-8',$f).'</li>';$subpath="{$path}/{$f}";if(is_dir($subpath))//如果子级还是文件夹,继续打开并读取getFile($subpath);}echo'</ul>';}//测试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
代码实现
<?phpfunctiongetTao($n){if($n==10)return1;return(getTao($n+1)+1)*2;}echogetTao(1);//1534
版权归原作者 学不会不改名的小林 所有, 如有侵权,请联系我们删除。