【php基础入门】细说PHP中的函数声明与使用详解(重要)

您所在的位置:网站首页 php函数的定义和调用 【php基础入门】细说PHP中的函数声明与使用详解(重要)

【php基础入门】细说PHP中的函数声明与使用详解(重要)

2024-07-12 11:26| 来源: 网络整理| 查看: 265

一、PHP函数

在日常开发中,如果有一个功能或者一段代码要经常使用,则可以把它写成一个自定义函数,在需要的时候进行调用。

在程序中调用函数是为了简化编程的负担,减少代码量和提高开发效率,达到增加代码重用性、避免重复开发的目的。

我们先来看一个创建5行3列表格的案例

$table = ""; for($i=0;$i 匿名函数

匿名函数的声明一般是将整个函数赋值给一个变量,通过变量可以调用该函数。变量本身就是函数本身,调用 变量名(参数)即可。匿名函数没有声明提升,和变量一样必须先声明在访问。

$fn = function(){ // 函数体 return 返回值; }; // 匿名函数要以分号结尾

我们来定义一个匿名函数

$str = function(){ return "hello world!"; } echo $str(); // 自调用的匿名函数 (function(){ echo 'run……'; })(); 2. PHP函数参数传递

如果函数没有参数列表,函数执行的任务就是固定的,用户在调用函数时不能改变函数内部的一些执行行为。

如果函数有参数列表,函数就可以从外部获取函数执行所需要的数据值。也就是用户在调用函数时,在函数体还没有执行之前,将一些数据通过函数的参数列表传递到函数内部,这样函数在执行函数体时,就可以根据用户传递过来的数据决定函数体内部如何执行。

根据参数使用的位置,参数分为形式参数和实际参数两种。

形式参数(形参)

形式参数就是定义函数时函数名后面括号内的参数列表(简称“形参”),就像它的名字一样,形参本身没有具体的值。因为函数体中需要使用外部传入的参数,为了使参数可以正确地传递进来,就需要通过形式参数与函数体里面的数据进行传递,形式参数如下图所示。

实际参数(实参)

实际参数就是我们在调用函数时函数名后面括号中的若干个参数(简称“实参”),实参和形参需要按顺序一一对应,它会替换形式参数在函数体中对应的变量值,函数的参数可以是一个具体的值,也可以是一个变量,实际参数如下图所示。

在调用函数时,需要向函数传递参数,被传入函数的参数称为实参,而函数定义的参数称为形参。而向函数传递参数的方式有四种,分别是值传递、引用传递、可选参数(默认值参数)和可变长度参数。

值传递 引用参数 必选参数 // 必选参数 function hello(string $name):string{ return "hello $name"; } echo hello("zhang"); // hello zhang // 会将标量类型自动转换为字符串 echo hello(123); // hello 123 echo hello(true); // hello 1 echo hello(); // 必选参数 不传参会报致命错误 可选参数(默认值参数) // 可选参数 (默认值参数) // 默认参数就是给函数的某个或多个形式参数指定一个默认的值,如果调用函数时不传入对应的值,那么函数就会使用这个默认值,这样可以避免调用时出现没有参数的错误 function hello(string $name = "zhang"):string{ return "hello $name"; } echo hello(); // hello zhang echo hello("shuai"); // hello shuai // 注意:当有多个参数时,可选参数必须放在最后面。 function user($name,$gender,$age=18,$city="合肥"):string{ return sprintf("姓名:%s 性别:%s 年龄:%d 城市:%s",$name,$gender,$age,$city); } // 姓名和性别为必选参数不可以省略 echo user('zhang','男'); // 姓名:zhang 性别:男 年龄:18 城市:合肥 echo user('zhang','男',20); // 姓名:zhang 性别:男 年龄:20 城市:合肥 不定参数 // 不定参数 function add(float $a,float $b,float $c):float { return $a+$b+$c; } echo add(1,2,3); // 6 // 如果有跟多的值计算参数非常多,以上函数就显得非常麻烦 function add(){ // 通过函数中内置的三个函数获取到参数的全部信息 // 1. 参数有几个? $n = func_num_args(); // 2. 参数组成的数组 $arr = func_get_args(); // 将数组转换为字符串 $args = implode(',',$arr); // 3. 获取某一个参数 $arg = func_get_arg(1); printf('参数数量:%d参数分别为%s第二个参数为%d',$n,$args,$arg); } add(1,2,3,4,5,6); // 求N个数的和 function sum(){ // array_sum 求数组的和 echo "参数之和:".array_sum(func_get_args()); } sum(8,9,8,56,4,84,26); 剩余参数 // js中的...rest语法剩余参数 // 函数的形式参数可使用 … 来表示函数可接受一个可变数量的参数,可变参数将会被当作一个数组传递给函数 function rest(...$args){ print_r($args); // Array ( [0] => 6 [1] => 5 [2] => 4 [3] => 3 [4] => 2 [5] => 1 ) echo ""; echo count($args); // 6 echo ""; echo array_sum($args); // 21 } rest(6,5,4,3,2,1); // 计算数组的和 // ...$args 归并数组 [666,888,999,689] function sum(...$args){ return array_sum($args); } $num = array(666,888,999,689); // ...$num 解构数组 666,888,999,689 echo sum(...$num); // 3242 echo ...[6,7,8]; //------------------------------- // 剩余参数实战场景 (数据库连接) function connect(...$arg){ return new PDO($arg[0],$arg[1],$arg[2]); } $pdo = connect('mysql:dbname=sys','root','root'); echo $pdo?'连接成功':"连接失败"; 3. PHP声明参数类型

在 PHP 7 中增加了参数可声明的类型种类,我们可以限制函数的传入参数类型和返回值类型

类型 说明 class/interface name(类,接口) 参数必须是指定类或接口的实例 Array 参数为数组类型 Callable 参数为有效的回调类型 Bool 参数为布尔型 Float 参数为浮点型 Int 参数为整型 String 参数为字符串

在 PHP 7 中,可以使用declare(strict_types=1)设置严格模式,这样只有在传递的参数与函数期望得到的参数类型一致时才能正确执行,否则会抛出错误。只有一种情况例外,就是当函数期望得到的是一个浮点型数据而提供的是整型时,函数也能正常被调用。

4. PHP 函数返回值

使用 return 语句时需要注意以下几点:

return 语句用于向“调用函数者”返回一个值,返回值后,立即结束函数运行,所以 return 语句一般都放在函数的末尾; 如果一个函数中存在多个 return 语句,则只会执行第 1 个; return 语句也可以不返回参数,就相当于结束函数运行; 如果在全局作用域内使用 return 语句,则会立即终止当前运行的脚本; 如果使用 include 或 require 引入的脚本文件中含有 return 语句,则会返回到引入脚本的地方继续向下执行,return 之后的其它代码不再执行。 function fn(){ return 'hello world'; // 返回字符串 return 3.1415926; // 返回浮点型 return 2>3; // 0 返回布尔型 return md5('zhang'); // 32位的散列值 return array('hello','world','!'); // 返回数组 return new StdClass(); // 返回对象 } echo ""; print_r(fn()); // hello world

在 PHP7 中增加了一个新功能——声明返回值类型。与声明参数类型相似,在非严格模式下,PHP 将会尝试将返回值类型转换为声明的类型,如果转换失败会报一个 Fatal error 错误。

// 多个值可以 以数组的形式返回 function demo1():array{ return ['status'=>1,'msg'=>'验证成功!']; } $res = demo1(); echo $res['status']==1?$res['msg']:'验证失败……'; // 验证成功 // ------------------------------------- echo ''; // 返回一个对象 function demo2():object{ // 返回一个匿名类 return new class(){ public $name = 'admin'; public $email = '[email protected]'; }; } $user = demo2(); echo ""; // 对象成员的访问 -> echo $user->name; echo $user->email; var_dump($user); /* object(class@anonymous)#1 (2) { ["name"]=> string(5) "admin" ["email"]=> string(13) "[email protected]" } */ // ------------------------------------- // 返回一个转为JSON格式的字符串 function demo3():string{ // json_encode() 第二个参数格式 // JSON_UNESCAPED_UNICODE 不将中文转义为Unicode编码 return json_encode(['status'=>1,'msg'=>'验证成功!'],JSON_UNESCAPED_UNICODE); } $json_str = demo3(); echo $json_str; /* { "status": 1, "msg": "验证成功!", "img":"https:\/\/up.keaitupian.com\/\/uploads\/allimg\/170111\/1_170111233712_1.jpg" } */ // 需要将JSON格式的字符串解析为PHP能够处理的数据类型 json_decode() $res = json_decode($json_str); echo ""; var_dump($res); /* 转换成了对象 object(stdClass)#1 (3) { ["status"]=> int(1) ["msg"]=> string(15) "验证成功!" ["img"]=> string(69) "https://up.keaitupian.com//uploads/allimg/170111/1_170111233712_1.jpg" } */ // 那么我们可以指定json_decode()第二个参数为true将转换为数组 $res = json_decode($json_str,true); echo ""; var_dump($res); /* array(3) { ["status"]=> int(1) ["msg"]=> string(15) "验证成功!" ["img"]=> string(69) "https://up.keaitupian.com//uploads/allimg/170111/1_170111233712_1.jpg" */ // ------------------------------------- // 以序列化字符串返回 function demo4():string{ return serialize(['status'=>1,'msg'=>'验证成功!','code'=>256]); } $str = demo4(); echo $str; // a:3:{s:6:"status";i:1;s:3:"msg";s:15:"验证成功!";s:4:"code";i:256;} // 作为日志打印到文件中 file_put_contents('file.txt',$str); // 还原为PHP可以处理的数据类型 $res= unserialize($str); echo ""; var_dump($res); /* array(3) { ["status"]=> int(1) ["msg"]=> string(15) "验证成功!" ["code"]=> int(256) } */ 5. PHP可变函数

PHP 中支持可变函数的概念(也叫变量函数),可以这样理解,如果一个变量名后有小括号( ),那么 PHP 就会寻找与变量值同名的函数并执行它。也就是说如果给一个变量赋不同的值,程序就会调用不同的函数。

需要注意的是,可变函数不能直接用于例如 echo、print、unset()、isset()、empty()、include、require 以及类似的语言结构,需要使用自己包装的函数来将这些结构用作可变函数。

6. PHP闭包函数

闭包是指在创建时封装周围状态的函数。即使闭包所在的环境不存在了,闭包中封装的状态依然存在。 匿名函数就是没有名称的函数。匿名函数可以赋值给变量,还能像其他任何PHP对象那样传递。不过匿名函数仍是函数,因此可以调用,还可以传入参数。匿名函数特别适合作为函数或方法的回调。 注意:理论上讲,闭包和匿名函数是不同的概念。不过,PHP将其视作相同的概念。所以,我们提到闭包时,指的也是匿名函数,反之亦然。 PHP闭包和匿名函数使用的句法与普通函数相同,但闭包和匿名函数其实是 伪装成函数的对象(Closure类的实例)。

$closure = function($name){ return sprintf('Hello %s', $name); }; echo $closure("zhang"); //Hello zhang var_dump($closure instanceof Closure); //bool(false)

我们通常把PHP闭包当做函数和方法的回调使用。很多PHP函数都会用到回调函数,例如 array_map() 和 preg_replace_callback() .如下示例,我们将用 array_map() 处理数组,将数组每一项进行平方操作:

$numbers = [1, -2, 3, -4, 5]; $squares = array_map(function ($number) { return $number ** 2; }, $numbers); print_r($squares); /* Array ( [0] => 1 [1] => 4 [2] => 9 [3] => 16 [4] => 25 ) */

PHP闭包不会像真正的javascript闭包那样自动封装应用的状态,我们必须手动调用闭包对象的 bindTo() 方法或者使用 use 关键字,把状态附加到PHP闭包上。

// 不使用global和$GLOBALS来获取全局作用域下的变量 $name = 'zhang'; $age = 18; $closure = function() use($name,$age){ return sprintf('姓名:%s 年龄:%d',$name,$age); }; echo $closure().""; // 姓名:zhang 年龄:18 // 使用引用传参配合use来改变函数体外传递进来的参数值 echo $name.""; // zhang $closure2 = function($myName) use(&$name){ $name = $myName; }; $closure2('shuai'); echo $name.""; // shuai

闭包应用场景

// 闭包经常用作于函数的返回值 function Car($name,$owner){ return function($statu,$color="pink") use ($name,$owner){ return sprintf("

Car %s is %s and myname is %s

",$name,$statu,$owner); }; } // Car 的返回值是一个闭包函数 $car = Car('bwm','wudy'); echo $car('running'); //Car bwm is running and myname is wudy // 简写()()连续调用 echo Car('特斯拉','宝马')('突突突突','green'); 7. PHP回调函数

所谓的回调函数,就是指调用函数时并不是向函数中传递一个标准的变量作为参数,而是将另一个函数作为参数传递到调用的函数中,这个作为参数的函数就是回调函数。通俗的来说,回调函数也是一个我们定义的函数,但是不是我们直接来调用的,而是通过另一个函数来调用的,这个函数通过接收回调函数的名字和参数来实现对它的调用。

实例演示数据库链接查询

$sql = "select * from sys_config limit 2"; $mysql = function($dsn,$username,$password)use($sql){ $pdo = new PDO($dsn,$username,$password); $stmt = $pdo->prepare($sql); $stmt->execute(); return $stmt->fetchALL(PDO::FETCH_ASSOC); }; // 回调一个匿名函数 $res = call_user_func_array($mysql,['mysql:dbname=sys','root','root']); echo ""; print_r($res); /* Array ( [0] => Array ( [variable] => diagnostics.allow_i_s_tables [value] => OFF [set_time] => 2019-07-25 13:30:15 [set_by] => ) [1] => Array ( [variable] => diagnostics.include_raw [value] => OFF [set_time] => 2019-07-25 13:30:15 [set_by] => ) ) */

很多PHP函数都会用到回调函数,例如 array_map() 和 array_filter()

$arr = [2,3,4,5]; // 将数组的每一项乘以2,返回一个新数组 $res = array_map(function($v){ return $v*2; },$arr); echo ""; print_r($arr); print_r($res); /* Array ( [0] => 2 [1] => 3 [2] => 4 [3] => 5 ) Array ( [0] => 4 [1] => 6 [2] => 8 [3] => 10 ) */ // 过滤出数组中大于7的数 $res = array_filter($res,function($v){ return $v>7; }); print_r($res); /* Array ( [2] => 8 [3] => 10 ) */ 8. PHP递归函数

递归函数即自调用函数,也就是函数在函数体内部直接或间接地自己调用自己。需要注意的是使用递归函数时通常会在函数体中附加一个判断条件,以判断是否需要继续执行递归调用,当条件满足时会终止函数的递归调用。

想要实现递归,需满足以下两个条件:

子问题需与原始问题为同样的事,且更为简单。 不能无限制地调用本身,必须有一个出口,化简为非递归状况处理。

实例演示:利用递归删除目录下的所有文件

// 递归函数:自己调用自己,要有调用条件 function delete_dir_file($dir){ // 声明一个初始状态,默认情况下缓存未被删除 $init = false; if(is_dir($dir)){ // 成功打开目录流 if($handle = opendir($dir)){ // 读取目录流 while(($file = readdir($handle))){ // echo $file.""; /* . .. demo.php function.php */ if($file!='.'&&$file!=".."){ // echo "$dir.'\\'.$file"; // 判断子目录是否合法 if(is_dir($dir.'\\'.$file)){ delete_dir_file($dir.'\\'.$file); }else{ // 检测到非目录 是文件 // 删除文件 (只能删除文件,不能删除目录) unlink($dir.'\\'.$file); } } } } // 关闭目录句柄 closedir($handle); // 删除空目录 if(rmdir($dir)) { $init = true; } } return $init; } // 删除当前目录下的所有文件 $res = delete_dir_file(__DIR__); echo $res?'缓存目录删除成功!':''; 9. PHP命名空间

命名空间一个最明确的目的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误。这种情况下只要避免命名重复就可以解决,最常见的一种做法是约定一个前缀。

命名空间将代码划分出不同的空间(区域),每个空间的常量、函数、类(为了偷懒,我下边都将它们称为元素)的名字互不影响, 这个有点类似我们常常提到的'封装'的概念。

二、结束 今日份函数 abs() 绝对值函数 strlen() 获取字符串长度函数 strtoupper() 小写字母转大写函数 mt_rand() 随机生成数函数 count() 获取数组长度函数 array_sum() 数组元素求和函数 implode() 将数组以指定字符串分割 extract() 将数组拆分为独立的变量 // 绝对值函数 echo abs(-3.1415926); // 3.1415926 // 字符串长度 echo strlen('nihao'); // 5 echo strlen('你好'); // 6个字符 // 小写转大写 echo strtoupper('hello world'); // HELLO WORLD // 生成随机数 echo mt_rand(0,100); // 数组长度 echo count([1,2,3,4]); // 4 // 数组元素的和 echo array_sum([3,8,6]); // 17 // 将数组以指定符号分割成字符串 echo implode('---',[1,2,3]); // 1---2---3 // 将数组的每一项拆分成独立的变量 $arr = ['name'=>'zhang','gender'=>"男",'age'=>18]; extract($arr); echo $name,$gender,$age; // zhang 男 18 // JSON 转换 json_encode(); // 数组转换为JSON字符串 json_decode(); // JSON字符串转换为对象或数组 // serialize 将数组序列化为字符串 serialize(); // 序列号字符串 unserialize(); // 还原为数组格式 // call_user_func()和call_user_func_array() // https://www.php.net/manual/zh/function.call-user-func.php // https://www.php.net/manual/zh/function.call-user-func-array.php

今日语录:生活就像坐公交车一样,就算公交上空无一人 ,司机也会把车开到终点。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3