PHP函数、数组和错误处理:简单实用的开发技巧和错误处理方法

目录

PHP函数

函数的基本概念:

函数定义语法:

函数命名关系:

参数详解

形参

实参

​编辑

默认值

引用传递

函数体

函数返回值

作用域

静态变量

可变函数

匿名函数

基本概念

闭包

伪类型

库函数

有关输出的函数

有关时间的函数

有关数字的函数

有关函数的函数

PHP错误处理

错误分类

错误代号

错误触发

错误显示设置

错误日志设置

自定义错误处理

字符串定义

字符串转义

单引号和双引号的区别:

双引号变量识别的规则:

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

字符串长度问题

字符串相关函数

数组

数组的概念

数组定义语法

PHP数组特点

多维数组

二维数组

多维数组

异形数组(不规则数组)

数组遍历

遍历的基本含义

Foreach遍历语法

Foreach遍历原理

For循环遍历数组

数组的相关函数:


PHP函数

函数的基本概念:

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

函数定义语法:

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

语法格式:

function 函数名(参数)
//函数体
//返回值 :return 结果

定义函数的目的:

一个功能使用一个函数实现

例如:

<?php
function display(){
    echo "hello world";
    //没有返回值
}
display();
?>

 

函数是在代码执行阶段,碰到函数名的时候才会调用,不是在编译阶段

注意:函数的调用可以在函数定义之前;即:及即使函数的调用在函数实现的前面调用时,也可以正常输出。

原因:编译和执行是分开的(先编译,后执行)

函数命名关系:

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

常用的两种命名方法:

1、驼峰法:除了左边第一个单词外,后面的所有的单词首字母大写;showPartentinfo();

2、下划线法L单词之间使用下划线连接:show_parent_info();

参数详解

参数被分为两类:形参和实参

形参

形式参数,不具有实际意义的参数,是在函数定义时的参数

实参

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

两者的关系:

形参是实参的载体;实参在调用时通常是需要传入到函数内部参与计算,那么需要在函数内部去找到实际数据所在位置才能找打数据本身;需要在实际调用的时候,将数据以实参的形式传递给形参,给形参复制,从而使得函数内部可以使用到外部的数据。

例如:

<?php
//函数参数
//定义函数
function add($arg1,$arg2)//两个形参
{
   echo  $arg1+$arg2,'<br/>';
}
add(1,2);
$a=100;
$b=89;
add($a,$b);
?>

默认值

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

<php?
function jian($num1=0,$num2=0)
{
    echo $num1=$num2,'<br/>';
}
//调用时默认值如果存在,可以不同传入
jian();
jian(2,1);
?>

注意:

1、默认值是放在最后面的,不能左边的形参有默认值,但是右边却没有

2、函数外部定义的变量名字可以和函数定义形参的名字重复;

引用传递

实参在调用时会将赋值给形参,那么实际上使用的方式就是一种简单的值传递;将实参的结果取出来赋值给形参;形参与位爱步实际传入的参数没有任何关系,只是他们的结果一样。

有时候,希望在函数内部拿到的外部数据,能够在函数内部改变,那么就需要明确告知函数,函数才会在调用的时候去主动回去数据的呢存地址。这就是引用传递;

在调用的时候,必须引用传值的参数位置传入实际参数,而且参数本身必须是变量(变量才有指向数据的内存地址的功能)

例如:

function display($a,&$b)
{
    //修改形参的值
    $a=$a*$a;
    $b=$b*$b;
    echo $a,'<br/>',$b,'<br/>';
}
$a=10;
$b=20;
display($a,$b);
echo '<hr/>',$a,'<br/>',$b;
?>

注意:当函数中的形参是变量引用的实参传递时如果不是变量会报错;

函数体

函数内部(即大括号内部的所有代码)

函数体:基本上所有的代码都可以作为函数的函数体

函数返回值

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

<?php
function display(){
    echo __FUNCTION__;//输出函数名
}
var_dump(display());
// ?>

 

<?php
function add($a1,$a2){
    return $a1+$a2;
}
$a3=add(10,11);
echo $a3
?>
运行结果:
21

注意:

1、return会直接结束函数,所以return后面的所有语句就不在执行

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

作用域

作用域:变量能够被访问的区域

由于变量可以在外部进行定义也可以在函数内部进行定义;作用域严格来说分为两种;但是PHP自身也有一种特殊的作用域,所以有三种

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

所属全局空间;在PHP中只允许在全局空间使用;理论上函数内部不可以访问(js可以)

脚本周期:直到脚本运行结束

2、局部变量:函数内部定义的变量

所属当前函数空间:在PHP中只允许在当前函数自己内部使用

函数周期:函数执行结束;

3、超全局变量:系统定义的变量(预定义变量);

所属全局空间:没有访问限制(即函数内外都可以访问)

<?php
//PHP中作用域
$global ='global';
// 全局变量的定义
function display()
{
    $inner = __FUNCTION__;
    // 定义局部变量
    echo $global;
    // 尝试函数空间访问全局变量
    // 这里访问不到,因为全局变量不能在函数内部使用
}
 display();
 echo $global;
 //全局空间访问全局变量
?>

可以使用数组或者参数传值的方式实现局部变量访问全局变量

在PHP中,还有一种方式可以实现全局可以访问局部,局部也可以访问全局;使用GLOBAL关键字

1、如果使用global定义的变量名在外部存在(全局变量),那么系统在函数内部定义的变量直接指向外部变量所指向的内存空间(同一个变量)

2、如果使用global定义的变量名在外部不存在(全局变量),那么系统会自动的在全局空间(函数外部)定义一个与局部变量同名的全局变量

本质:在函数的内部和外部,对一个同名的变量使用同一块内存地址保存数据,从而实现共同拥有

<?php
//PHP中作用域
$global ='global';
// 全局变量的定义
function display()
{
    $inner = __FUNCTION__;
    // 定义局部变量
    global $global;
    //适应global关键字将外部的global引入到函数内部
    echo $global;
    // 尝试访问全局变量
    //这里正常输出
}
display();
?>

静态变量

静态变量:static ,是在函数内部定义的变量,用来实现跨函数共享数据的变量:函数运行结束所有局部变量都会清空,如果重新运行一下函数,所有的局部变量又会重新初始化,静态变量的作用就是让该变量保持上一次的结果,而不是清空。

例如:

<?php
function display()
{
    $local =1;
    static $count=1;
    $count+=1;
    $local+=1;
    echo '<hr/>';
    echo $count,'<br/>',$local,'<br/>';
}
display();
display();
display();
?>

静态变量的原理:系统在进行编译的时候就会对static这一行进行初始化;为静态变量赋值;

应用场景:

1、统计:统计当前函数被调用次数

2、为了统筹函数多次调用得到的不同结果

可变函数

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

例如:

<?php
function display()
{
    echo __FUNCTION__;
}
$func='display';
echo $func,'<hr/>';
//使用可变函数(变量)访问函数
display();
// 使用函数名访问函数
?>

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

回调函数:将用户定义的函数传入给另外一个函数(函数名)去使用的过程。

匿名函数

基本概念

没有名字的函数

格式:

变量名=function(){

//函数体

}

例如:

<?php
$a=function()
{
 echo "hello world";
};
 $a();
?>

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

闭包

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

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

例如:

<?php
function display()
{
    $name= __FUNCTION__;
    $innerfunction=function() use($name)
    //use就是将外部的变传入内部进行使用 
    {
        //函数的内部的函数
        echo $name;
    }
}
display();
?>

检测函数的局部变量在函数内部使用完成后没有释放的几种方法:

1、使用内部匿名函数

2、匿名函数使用变量use

3、匿名函数被返回给外部

伪类型

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

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

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

库函数

有关输出的函数

print():类似于echo 输出提供的内容,本质是一种结构(不是函数)

print_r():类似于var_dump,但是比var_dump简单,不会输出数据类型,只会输出值。

例如:

<?php
echo  print('hello world<br/>');
print('hello world<br/>');
$a='hello world<br/>';
print_r($a);
?>

有关时间的函数

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

time():返回自从 (格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数。

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

例如:

<?php
echo date('Y m d H:i:s',12345678),'<br/>';
echo time(),'<br/>';
echo microtime(),'<br/>';
?>

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

有关数字的函数

max():指定参数中的最大值

min():指定参数中的最小值

rand():得到一个指定区间的随机数

mt_rand():与rand一样,效率更高

round():四舍五入

cell():向上取整

floor():向下取整

pow():求指定数字的指定指数次结果

abs():绝对值

sqrt():求平方根

有关函数的函数

function_exists():判断指定的函数名字是否存在内存中存在(帮助用户不去使用一个不存在的函数)

func_get_arg():在自定义函数中去获取指定数值对应的参数

func_get_args():在自定义函数中获取所有的参数

func_num_args():在当前自定义函数的参数数量

例如:

<?php
echo '<pre>';
function test($a,$b)
{
var_dump(func_get_arg(1));
//获取指定参数
var_dump(func_get_args());
//获取所有参数
var_dump(func_num_args());
//获取参数个数
}
function_exists('test') && test(1,'2,3,4');
// 判断是该函数否存在
?>

PHP错误处理

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

错误分类

1)语法错误:用户书写的代码不符合PHP的语法规范,语法错误会导致代码在编译过程中不通过,所以代码不会执行(Parse error)

2)运行时错误:代码编译通过,但是代码在执行的过程中会出现一些条件不满足导致的错误(runtime error)

3)逻辑错误:程序员在写代码的时候不够规范,出现了一些逻辑性的错误,导致代码正常执行,但是得不到想要的结果

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

错误代号

所有看到的错误代号在PHP中都被定义成了系统常量(可以直接使用)

(1)系统错误:

E_PARSE:编译错误,代码不会执行

E_ERROR:fatal error,致命错误,会导致代码不能正确继续执行(出错的位置断掉)

E_WARNING:warning,警告错误,不会影响代码执行,但是可能得到意想不到的结果

E_NOTICE:notice,通知错误,不会影响代码执行

(2)用户错误:E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE

用户在使用自定义错误触发的时候,会使用到的错误代号(系统不会用到)

(3)其他:E_ALL,代表着所有的错误(通常在进行错误控制的时候使用比较多),建议在开发过程中(开发环境)使用

所有以E开头的错误常量(代号)其实都是由一个字节存储,然后每一种错误占据一个对应的位,如果想进行一些错误的控制,可以使用位运算进行操作

排除通知级别notice:E_ALL & ~E_NOTICE

只要警告和通知:E_WARNING | E_NOTICE

错误触发

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

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

Trigger_error(错误提示):

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

错误显示设置

错误显示设置:哪些错误该显示,以及该如何显示

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

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

Display_errors:是否显示错误

Error_reporting:显示什么级别的错误

2、 可以在运行的PHP脚本中去设置:在脚本中定义的配置项级别比配置文件高(通常在开发当中都会在代码中去进行控制和配置)

Error_reporting():设置对应的错误显示级别

Ini_set(‘配置文件中的配置项’,配置值)

例如:

Ini_set(‘error_reporting’,E_ALL);

Ini_set(‘display_errors’,1);

错误日志设置

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

1、 不友好

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

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

1、 开启日志功能

2、指定路径

自定义错误处理

最简单的错误处理:trigger_errors()函数,这个函数是在出错时的错误提示,但是该函数不会阻止系统报错

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

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

2、 自定义错误处理函数,系统有要求

字符串定义

  1. 单引号字符串

  2. 双引号字符串

    引号的方式比较适合比较短或者没有结构要求的字符串

    如果内容过长可以使用下面两种方式

    结构化定义:

  3. nowdoc字符串:没有单引号的单引号字符串

  4. heredoc字符串没有双引号的双引号字符串

    例如:

    <?php
    $str1='hello';
    $str2="hello";
    $str3=<<<EOD
        hello
            world
    EOD;
    $str4=<<<'EOD'
        hello
            world
    EOD;
    var_dump($str1,'<hr/>',$str2,'<hr/>',$str3,'<hr/>',$str4);
    ?>*

字符串转义

转义:在计算机通用协议中,有一些特定的方式定义的字母,系统会特定处理;通常这种方式都是使用反斜杠+字母的特性:

PHP在识别准一字符的时候也是同样的模式;

常用的PHP中常用的转义符号

\':单引号

\":双引号

\r:回车(理论上是跳转到当前行的首位置)

\n:新的一行

\t:tab键,四个空格

\$:在PHP中使用$作为变量符号,这里表示‘$’本身字符

单引号和双引号的区别:

1、其中单引号可以识别'\',双引号不能识别‘\’;

2、双引号可以识别$符号,索引双引号可以解析变量,但是单引号不可以解析变量,只会原样打印

双引号变量识别的规则:

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

2、使用变量专业标识符,给变量加上一组大括号{}

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

1、上边界符后面不能跟任何内容

2、下边界符必须顶格

3、下边界符后面只能跟分号,不能跟任何内容

4、机构化定义字符串的内部的所有内容都是字符串本身

字符串长度问题

strlen函数:得到字符串长度的函数(单位是字节)

例如:

<?php
header('Content-type:text/html;charset=ytf-8');
$str1='hello';
$str2="hello world";
echo strlen($str1),'<br/>',strlen($str2);
?>

 

多字节字符串的长度问题:包含中文的长度

多字节字符串扩展模块:mbstring扩展

首先需要加载PHP的mbstring扩展;

下面就可以使用mbstring中扩展的很多函数了

字符串相关函数

  1. 转化函数

    str_split(字符串,字符串长度):按照指定长度查分字符串得到数组

    implode(连接诶方式,数组):将数组中的元素按照某个规则连接成一个字符串

    explode(分割字符,目标字符串):将字符串按照某个格式进行分割,变成数组

  2. 截取函数

    trim(字符串,[指定字符]):本身默认是用来去除两百年的空格,但是也可以指定要去除的内容,是按照指定的额呢绒循环去除两边有的内容:直到碰到一个不是目标字符串为止;

    ltrim():去除左边的

    rtrim():去除右边的

    substr(字符串,起始位置,[长度]):指定位置开始截取字符串,可以截取指定长度的字符串

    strstr(字符串,匹配字符):从指定位置开始,一直截取到最后(可以用来取文件后缀名)

  3. 大小转换函数

    strtolower:全部小写

    strtoupper:全部大写

    ucfist:首字母大写

  4. 查找函数

    strpos():查找字符串中指定字符首次出现的位置

    strrpos():判断字符串中指定字符最后一次出现的位置

  5. 替换函数

    str_replace(匹配对象,替换字符,字符串本身):将目标字符串中部分字符串进行替换

  6. 格式化函数

    printf():格式化输出数据

    sprintf():格式化输出数据

  7. 其他函数

    str_repeat():重复某个字符串N次

    str_shuffle():随机打乱字符串

数组

数组的概念

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

数组定义语法

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

1、 使用array关键字:最常用的

$变量 = array(元素1,元素2,元素3..);

2、 可以使用中括号来包裹数据:

$变量 = [元素1,元素2…];

3、 隐形定义数组:给变量增加一个中括号,系统自动变成数组

$变量[] = 值1; //如果不提供下标也可以,系统自动生成(数字:从0开始)

$变量[下标] = 值; //中括号里面的内容称之为下标key,该下标可以是字母(单词)或者数字,与变量命名的规则相似

PHP数组特点

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

如果数组下标都为整数:索引数组

如果数组下标都为字符串:关联数组

2) 不同下标可以混合存在:混合数组

3) 数组元素的顺序以放入顺序为准,跟下标无关

4) 数字下标的自增长特性:从0开始自动增长,如果中间手动出现较大的,那么后面的自增长元素从最大的值+1开始

5) 特殊值下标的自动转换

布尔值:true和false

空:NULL

6) PHP中数组元素没有类型限制

7) PHP中数组元素没有长度限制

补充:PHP中的数组是很大的数据,所以存储位置是堆区,为当前数组分配一块连续的内存。

多维数组

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

二维数组

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

多维数组

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

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

异形数组(不规则数组)

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

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

数组遍历

遍历的基本含义

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

$arr = array(0=>array(‘name’ => ‘Tom’),1=>array(‘name’ => ‘Jim’));  //二维数组
//访问一维元素:$arr[一维下标]
$arr[0];    //结果:array(‘name’ => ‘Tom’);
//访问二维元素:$arr[一维下标][二维下标
$arr[1][‘name’];    //Jim

Foreach遍历语法

基本语法如下:

Foreach($数组变量 as [$下标 =>] $值){
•   //通过$下标访问元素的下标;通过$值访问元素的值
}

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

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

Foreach遍历原理

Foreach遍历的原理:本质是数组的内部有一颗指针,默认是指向数组元素的第一个元素,foreach就是利用指针去获取数据,同时移动指针。

Foreach($arr as $k => $v){
•   //循环体

1、 foreach会重置指针:让指针指向第一个元素;

2、 进入foreach循环:通过指针取得当前第一个元素,然后将下标取出放到对应的下标变量$k中(如果存在),将值取出来放到对应的值变量$v中;(指针下移)

3、 进入到循环内部(循环体),开始执行;

4、 重复2和3,直到在2的时候遇到指针取不到内容(指针指向数组最后)

For循环遍历数组

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

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

1、 获取数组长度:count(数组)得到数组元素的长度

2、 要求数组元素的下标是规律的数字

数组的相关函数:

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

sort():顺序排序(下标重排)

rsort():逆序排序

asort():顺序排序(下标保留)

arsort():逆序排序

ksort():顺序排序:按照键名(下标)

krsort():逆序排序

shuffle():随机打乱数组元素,数组下标会重排

(2)指针函数

reset():重置指针,将数组指针回到首位

end():重置指针,将数组指针指导最后一个元素

next():指针下移,取得下一个元素的值

prev():指针上移,取得上一个元素的值

current():获取当前指针对应的元素值

key():获取当前指针对应的下标值

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

(3)其他函数

count():统计数组中元素的数量

array_push():往数组中加入一个元素(数组后面)

array_pop():从数组中取出一个元素(数组后面)

array_shift():从数组中取出一个元素(数组前面)

array_unshift():从数组中加入一个元素(数组前面)

array_reverse():数组元素反过来

in_array():判断一个元素在数组中是否存在

array_keys():获取一个数组的所有下标,返回一个索引数组

array_values():获取一个数组的所有值,返回一个索引数组

猜你喜欢

转载自blog.csdn.net/qq_68163788/article/details/131445295