• 0xx_PHP04


    1.1 今日目标

    1. 掌握静态变量的工作原理;
    2. 了解全局变量、局部变量和超全局变量的区别;
    3. 了解两种错误处理机制;
    4. 掌握错误相关信息的三种配置方式;
    5. 掌握自定义函数实现错误处理;
    6. 理解四种包含文件方式的区别;
    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;  //全局变量
    function fun() {
    	echo $GLOBALS['num'];	//输出全局的$num
    }
    fun();
    

    练习:如下代码输出什么

    <?php
    function fun() {
    	$GLOBALS['num']=10;  //将值付给全局的$num
    }
    fun();
    echo $num;   //10
    

    global关键字

    <?php
    $num=10;
    function fun() {
    	global $num;   //将全局变量的$num的地址引入到函数内部  相当于$num=&GLOBALS['num']
    	echo $num;	//10
    	$num=100;
    }
    fun();
    echo '<br>';
    echo $num;    //100
    -----------------------------------
    <?php
    $num=10;
    function fun() {
    	global $num;
    	unset($num);  //销毁的是引用,不是具体的值
    }
    fun();
    echo $num;    //10  
    

    小结:

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

    <?php
    $a=10;
    $b=20;
    function show() {
    	echo '<pre>';
    	var_dump($GLOBALS);   //是一个数组,保存的是全局变量的所有的值
    }
    show();
    

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

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

    <?php
    /*
    define('PI',3.14);
    function fun() {
    	echo PI;   //3.14
    }
    fun();
    echo '<br>';
    */
    -------------------------------------
    function fun() {
    	define('PI',3.14);
    }
    fun();
    echo PI;   //3.14
    

    1.2.2 静态变量(static)

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

    静态变量只初始化一次

    <?php
    function fun() {
    	$num=10;	//普通变量每调用一次初始化一次,调用完毕销毁
    	$num++;
    	echo $num,'<br>';
    }
    fun();	//11
    fun();	//11
    --------------------------------
    <?php
    function fun() {
    	static $num=10;	//静态变量只初始化一次,调用完毕吧不销毁,第二次调用的时候就不再初始化
    	$num++;
    	echo $num,'<br>';
    }
    fun();	//11
    fun();	//12
    

    常量和静态变量的区别

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

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

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

    <?php
    function fun1() {
    	define('num',10);
    }
    function fun2() {
    	echo num;   //10
    }
    fun1();
    fun2();
    ------------------------------------------------------------
    <?php
    function fun1() {
    	static $num=10;
    }
    function fun2() {
    	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;
    function test() {
    	$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 .....

    <?php
    function printer($num) {
    	echo $num,'&nbsp;';
    	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),'<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++)
    	echo fbnq($i),'&nbsp;';   //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:aabccdd中有多个文件需要包含,可以将包含的路径设置成include_path,这样包含就只要写文件名就可以了

    <?php
    set_include_path('c:aabccdd');  //设置include_path
    require 'head1.html';	  //受include_path配置影响
    require 'head2.html';
    

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

    set_include_path('c:aabccdd;d:\');
    

    多学一招:

    正斜(/) web中目录分隔用正斜  http://www.sina.com/index.php
    反斜()物理地址的分隔用反斜,(windows中物理地址正斜和反斜都可以)  c:web1aa
    

    1.5 错误处理

    1.5.1 错误的级别

    1. notice:提示
    2. warning:警告
    3. 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。

    定义错误处理函数

    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 '记录在日志中,上班后在处理<br>';
    			break;
    		case E_WARNING:
    		case E_USER_WARNING:	
    			echo '给管理员发邮件<br>';
    			break;
    		case E_ERROR:
    		case E_USER_ERROR:
    			echo '给管理员打电话<br>';
    			break;
    	}
    	echo "错误信息:{$errstr}<br>";
    	echo "错误文件:{$errfile}<br>";
    	echo "错误行号:{$errline}<br>";
    }
    set_error_handler('error');
    echo $num;
    
    //运行结果
    记录在日志中,上班后在处理
    错误信息:Undefined variable: num
    错误文件:F:wampwww4-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()】

    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),'<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],'&nbsp;';
    	}
    	echo '<br>';
    }
    //运行结果
    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 '&nbsp;';
    }
    

    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的三次方
    //运行结果
    153
    370
    371
    407
    

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

    $num1=1;   //第一个数
    $num2=1;    //第二个数
    echo $num1,'&nbsp;',$num2,'&nbsp;';
    while(true){
    	$num3=$num1+$num2;   //第三个数是前面两个数的和
    	if($num3>100)		 //超过100就终止循环
    		break;
    	echo $num3,'&nbsp;';
    	$num1=$num2;		//将$num2移给$num1
    	$num2=$num3;		//将$num3移给$num2
    }
    //1 1 2 3 5 8 13 21 34 55 89 
    

    1.8 作业

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

    2、递归遍历整个文件夹

  • 相关阅读:
    mysql的常用查询创建命令
    maven的简介
    google guava
    分库分表的情况下生成全局唯一的ID
    书单
    MD5Util
    UUID生成工具
    nodejs学习笔记三——nodejs使用富文本插件ueditor
    nodejs学习笔记二——链接mongodb
    mongodb 安装
  • 原文地址:https://www.cnblogs.com/xeclass/p/12655927.html
Copyright © 2020-2023  润新知