PHP基础知识4

184 阅读1分钟

作用域

变量作用域

1、全局变量:在函数外面 2、局部变量:在函数里面,默认情况下,函数内部是不会去访问函数外部的变量 3、超全局变量:可以在函数内部和外部访问

image.png

<?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

静态变量(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();

匿名函数use()

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

<?php
$num=10;
$fun=function() use($num) {  //将$num引入到匿名函数中
    echo $num;  
};
$fun();   //10

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

1、使用超全局变量

2、$GLOBALS

3、global

4、use将函数外部变量引入到匿名函数内部 多学一招:use可以引入值,也可以引入地址

<?php
$num=10;
$fun=function()use(&$num){   //use可以传地址
    $num=100;
};
$fun();
echo $num;  //100

##递归

函数内部自己调用自己

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

例题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 

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

包含文件

image.png

1.4.1 包含文件的方式

1、require:包含多次

2、include:包含多次

3、require_once: 包含一次

4、include_once: 包含一次

image.png 小结:

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

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

3、require_once、include_once只能包含一次

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

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

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

包含文件的路径

./      当前目录
../     上一级目录

区分如下包含:

require './head.html';   //在当前目录下查找
require 'head.html';      //受include_path配置影响

image.png include_path的使用场景:

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

<?php
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. notice:提示
  2. warning:警告
  3. error:致命错误

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

错误的提示方法

方法一:显示在浏览器上

方法二:记录在日志中

####与错误处理有关的配置

在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的配置参数

自定义错误处理(了解)

通过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;

运行结果

image.png

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

/**
*自定义错误处理函数
*@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:\wamp\www\4-demo.php
错误行号:50

##文件编程

文件夹操作

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);      //关闭文件夹

小结:

1opendir()返回资源类型
2、每个文件夹中都有.和..
3iconv()用来做字符编码转换