PHP07 函数
学习要点
- 函数的定义
- 自定义函数
- 函数的工作原理和结构化编程
- PHP变量范围
- 声明及应用各种形式的PHP函数
- 递归函数
- 使用自定义函数库
- 匿名函数和闭包
- 常用PHP系统函数
- PHP7函数新特性
函数的定义
- 数学中的函数: y=f(x);x是参数,y是返回值。
- PHP中的函数:被命名的,独立的代码段,执行特定的任务,并可以给调用他的程序返回一个值。
- 被命名的:在一个项目中,函数名唯一;PHP通过函数名调用函数。
- 独立的:函数可以单独执行任务,无需干预。
- 执行特定任务:任务是程序运行时执行的具体工作。
- 返回值:程序调用函数时,将执行函数中的语句,这些语句可以将信息返回给调用者。
- PHP的模块化编程是通过函数来实现的。
- 提高重用性
- 提高可维护性
- 提高开发效率
- 提高软件可靠性
- 控制程序的复杂性
自定义函数
系统有常用功能的函数,直接调用;若没有,则根据模块需要自行编写函数。
PHP 的真正力量来自它的函数:它拥有超过 1000 个内建的函数。
函数的声明
- 语法规范
function 函数名([参数1,参数2,参数3,……参数n]){ 函数体; [return 返回值]; }
- 函数名以字母或下划线开头(不允许数字开头)。
- 函数名对大小写不敏感。
- 函数名应该见名知意。
- 演示示例1:定义输出表格函数table()
function table() { // 将使用双层for循环输出表格的代码声明为函数,函数名为table echo "<table align='center' border='1' width='600'>"; echo "<caption><h1>通过函数输出表格</h1></caption>"; for($out = 0; $out < 10; $out ++) { if ($out % 2 == 0) $bgcolor = "#ffffff"; else $bgcolor = "#dddddd"; echo "<tr bgcolor=" . $bgcolor . ">"; for($in = 0; $in < 10; $in ++) { echo "<td>" . ($out * 10 + $in) . "</td>"; } echo "</tr>"; } echo "</table>"; } // table函数结束花括号
函数的调用
- 函数如何调用
- 通过函数名调用函数。
- 如果需要参数,则通过函数名后的小括号传入对应的值。
- 如果函数有返回值,则函数名可以当作返回值。
- 演示示例2:函数的调用
可以在函数定义之前或之后调用函数。
函数的参数
- 参数列表可选,可以没有参数,一个参数或者多个参数。每个参数是一个表达式,用逗号隔开。也称为形式参数(形参)。
- 演示示例3:定义可以改变表名、行数和列数的函数
/** * 输出表格函数 * @param unknown $tableName * @param unknown $rows * @param unknown $cols */ function table($tableName, $rows, $cols) { echo "<table align='center' border='1' width='600'>"; echo "<caption><h1> $tableName </h1></caption>"; // 在输出表名时使用第一个参数做为表名 for($out = 0; $out < $rows; $out ++) { // 使用第二个参数做为外层循环的次数条件 if ($out % 2 == 0) $bgcolor = "#ffffff"; else $bgcolor = "#dddddd"; echo "<tr bgcolor=" . $bgcolor . ">"; for($in = 0; $in < $cols; $in ++) { // 使用第三个参数做为内层循环的次数条件 echo "<td>" . ($out * $cols + $in) . "</td>"; } echo "</tr>"; } echo "</table>"; } // table函数结束花括号 table ( "第一个3行4列的表", 3, 4 ); // 第一次调用table()函数,传入三个实参。 table ( "第二个2行10列的表", 2, 10 ); // 第二次调用table()函数,传入三个实参。 table ( "第三个5行5列的表", 5, 5 ); // 第三次调用table()函数,传入三个实参。
函数的返回值
- 由于PHP变量作用域的原因,调用函数的脚本程序不能直接使用函数体中的信息,这个需要使用return关键字返回新给调用者。
- return的两个作用:第一是返回信息;第二是退出函数。
- 演示示例4:定义可以改变表名、行数和列数的函数,同时返回表格信息字符串。
/** * 定义可以改变表名、行数和列数的函数,同时返回表格信息字符串 * @param unknown $tableName * @param unknown $rows * @param unknown $cols * @return string */ function table($tableName, $rows, $cols) { $str_table = ""; // 声明一个空字符串,将下面的计算结果累加到这个字符串里面 $str_table .= "<table align='center' border='1' width='600'>"; // 将些行累加到$str_table字符串中 $str_table .= "<caption><h1> $tableName </h1></caption>"; // 将些行累加到$str_table字符串中 for($out = 0; $out < $rows; $out ++) { if ($out % 2 == 0) $bgcolor = "#ffffff"; else $bgcolor = "#dddddd"; $str_table .= "<tr bgcolor=" . $bgcolor . ">"; // 将些行累加到$str_table字符串中 for($in = 0; $in < $cols; $in ++) { $str_table .= "<td>" . ($out * $cols + $in) . "</td>"; // 将些行累加到$str_table字符串中 } $str_table .= "</tr>"; // 将些行累加到$str_table字符串中 } $str_table .= "</table>"; // 将些行累加到$str_table字符串中 return $str_table; // 返回通过本函数计算后的字符串 } $str = table ( "第一个3行4列的表", 3, 4 ); // 调用table函数并将返回的结果赋给变量$str echo table ( "第二个2行10列的表", 2, 10 ); // 调用table函数并直接将返回结果输出 echo $str; // 将获取到的$str字符串输出
上机练习1:定义一个计算器函数
需求说明:
1、 四则运算计算器
2、 操作数和操作符通过html表单输入
3、 三个参数函数,分别是操作数1,操作数2,操作符,返回计算结果
函数的工作原理和结构化编程
- 函数只有被调用后,才会执行函数体。调用结束,控制权转移到调用处。
- PHP的结构化编程函数是最理想的代码块。
1、结构化让程序更容易编写,便于团队协作。
2、结构化更容易调试,故障可以实现单元定位,即定位到函数
PHP变量范围
变量的范围,即变量的生效范围。
超全局变量
超全局变量是在全部作用域中始终可用的内置变量。
局部变量
- 函数内部声明的变量
- 函数的参数
- 局部变量使用完成后,变量即被释放
演示示例5:局部变量
function demo($one) { $two = 100; echo "在函数内部执行:$one+$two =" . ($one + $two) . "<br>"; } demo ( 200 ); echo "在函数外部执行:$one+$two =" . ($one + $two) . "<br>";
全局变量
- 在函数外部定义
- 作用域从定义处开始,到本程序文件的末尾。
- 注意:如果局部变量和全局变量重名,局部变量不会覆盖全局变量。
声明演示示例6:全局变量
$one = 100; $two = 200; function demo() { echo "在函数内部执行:$one+$two =" . ($one + $two) . "<br>"; } demo ( ); echo "在函数外部执行:$one+$two =" . ($one + $two) . "<br>";
- 如果要在函数内部使用全局变量,使用global定义
$one = 100; $two = 200; function demo() { global $one,$two; echo "在函数内部执行:$one+$two =" . ($one + $two) . "<br>"; } demo ( ); echo "在函数外部执行:$one+$two =" . ($one + $two) . "<br>";
- 或者使用超全局变量$GLOBALS数组。Key对应变量名,value对应变量值。
$one = 100; $two = 200; function demo() { $GLOBALS[‘two’] = $GLOBALS[‘one’] + $GLOBALS[‘two’]; echo "在函数内部执行:$one+$two =" . ($one + $two) . "<br>"; } demo(); echo "在函数外部执行:$one+$two =" . ($one + $two) . "<br>";
静态变量
局部变量从存储方式上可以分为动态存储和静态存储。默认动态存储。如果要静态存储,则需要加上关键字static。静态局部变量在函数被调用执行任务之后不会被释放。
演示示例7:静态变量
function test(){ static $a=0; echo $a; $a++; } test(); test(); test();
声明及应用各种形式的PHP函数
函数声明规范
- 函数功能描述:简要描述函数功能
- 参数说明:类型,作用描述
- 返回值:是否有返回值,返回值类型。
演示示例8:函数规范声明
/** * 定义一个求两个整数的平方和函数 * @param int $i 第一个整数参数,作为一个运算数 * @param int $j 第二个整数参数,作为另一个运算数 * @return int 返回一个整数,计算后的结果 */ function test($i,$j){ $sum=0;//声明一个变量保持计算后的结果 $sum=$i*$i+$j*$j;//计算 return $sum;//返回值,返回计算后的结果 } echo test(7,9);
常规参数函数
- 格式说明:
String example(string name,int age,double height) //常规参数的函数格式说明
- 实参和形参个数相等,类型一致。
伪类型参数的函数
- 格式说明:
mixed func (mixed $args) // 参数列表和返回值使用mixed描述的参数 number func (number $args) // 参数列表和返回值使用number描述的参数
- 弱类型语言不存在方法重载。
- 如果参数能接受多种不同类型(并不是指全部类型,例如资源类型,特殊类型等等)的值,可以使用mixed说明。
- 如果一个参数可以是integer或者float,那就说明成number类型。
引用参数函数
- 格式说明:
void func (array &arg) // 在参数列表使用&描述的参数
- PHP默认按照传值的方式传递参数
- 函数的参数也是属于局部变量。函数内部改变的参数值,无法影响外部的值。
- 如果希望函数执行完毕,能够修改外部的值,必须通过引用传递参数。
- 如果在函数中使用&修饰参数,则参数必须是变量,而不能是值。
- 示例代码
/** * 函数参数为引用类型 */ function test(&$var){ $var++; echo $var; } $var=100; test($var); echo "\n".$var;
默认参数函数
- 格式说明:
mixed func (string name[,string value[,int expire]]) //在参数列表使用[]描述的参数
- PHP中支持函数的默认参数值,如果在调用时候没有指定,则使用默认值。
- 默认值必须是常量表达式。不可以是变量、类成员或者函数调用。
- 默认值可以是数组和null值。
- 如果参数列表普通参数和默认值参数并存,默认值参数放在参数列表最后,避免传参异常。
- 适用于实参个数少于形参的情况。
- 示例代码
function hello($name,$age,$job="教师"){ echo "我的名字是{$name},今年岁{$age},从事{$job}工作。"; } hello("李四",21);
可变个数参数的函数
- 格式说明:
mixed func (string arg1[,string …]) // 参数列表中出现…描述参数
- 适合于函数接收任意数量的参数。
- 使用func_get_args()函数获取所有参数,返回值为参数数组。
- 演示示例:
function more_args() { $args = func_get_args (); // 获取参数数组 for($i = 0; $i < count ( $args ); $i ++) { echo "第".($i+1)."个参数是:".$args[$i]."<br>"; } } more_args("one","two","three",1,2,3);
- func_get_arg()函数可以接受一个数字参数,返回指定的参数,例如,修改示例代码:
function more_args() { $args = func_get_args (); // 获取参数数组 for($i = 0; $i < count ( $args ); $i ++) { //echo "第".($i+1)."个参数是:".$args[$i]."<br>"; echo "第".($i+1)."个参数是:".func_get_arg($i)."<br>"; } } more_args("one","two","three",1,2,3);
回调函数
- 格式说明:
mixed func (callback arg) // 参数列表中使用伪类型callback描述参数
定义:func函数的参数也是函数。
作用:函数功能的扩展。
- 变量函数
定义:变量函数也称为可变函数。如果一个变量名后跟上“()“,则PHP将寻找与变量的值相同的函数名,并执行他。
示例代码:
/** * 计算两个数的和 * @param number $a 第一个运算数 * @param number $b 第二个运算数 * @return number 计算结果 */ function one($a,$b){ return $a+$b; } /** * 计算两个数的平方和 * @param number $a 第一个运算数 * @param number $b 第二个运算数 * @return number 计算结果 */ function two($a,$b){ return $a*$a+$b*$b; } /** * 计算两个数的立方和 * @param number $a 第一个运算数 * @param number $b 第二个运算数 * @return number 计算结果 */ function three($a,$b){ return $a*$a*$a+$b*$b*$b; } $result="one"; //$result="two"; //$result="three"; echo "计算结果是:".$result(2,3);//变量是哪个函数名的值,就调用那个函数
- 使用变量函数声明和应用回调函数
工作原理:定义回调函数时,声明参数为普通变量,在函数内部应用这个变量时,加上“()“就可以调用到和这个参数值同名的函数。所以传递参数的时候,这个参数字符串一定要是被调用函数的名称。
示例代码:
/** * 声明回调函数filter,在0-100的整数中通过自定义条件过滤不要的数字 * @param callback $fun 需要传递一个函数名称字符串作为参数 */ function filter($fun){ for($i=0;$i<=100;$i++){ //参数变量加上“()”,则会调用和变量$fun值同名的函数 if($fun($i)){ continue; } echo $i.' '; } } /** * 声明函数one,如果参数是3的倍数就返回true,否则返回false * @param int $num 整数参数 * @return boolean */ function one($num){ return $num%3==0; } /** * 声明函数two,如果参数是回文数(翻转后还是自己)返回true,否则返回false * @param int $num 整数参数 * @return boolean */ function two($num){ return $num==strrev($num); } echo '打印出100以内非3的倍数:'; filter("one"); echo '<br>------------------------<br>'; echo '打印出100以内的非回文数:'; filter("two");
- 使用call_user_func_array()函数自定义回调函数
使用变量函数声明实现回调函数实际应用少,PHP系统提供了call_user_func_array()函数实现回调。call_user_func_array()函数本身也是一个回调函数,其语法格式如下:
mixed call_user_func_array( callback function , array param_arr)
参数说明:
callback function:函数名字符串
array param_arr:被调用函数的参数列表,数组类型。
示例代码(直接调用):
//call_user_func_array()自定义回调函数 function fun($msg1, $msg2) { echo '$msg1 = ' . $msg1; echo '<br>'; echo '$msg2 = ' . $msg2; } call_user_func_array("fun", array("LAMP","SAN科技"));
示例代码(在函数中应用):
/** * 使用自定义函数过滤掉不满足条件的数字 * @param callback $fun 过滤条件函数 */ function filter($fun){ for($i=1;$i<=100;$i++){ if(call_user_func_array($fun, array($i))){ continue; } echo $i." "; } }
- 类静态函数和对象的方法回调
类的静态函数:
class Demo { static function fun($msg1, $msg2) { echo '$msg1 = ' . $msg1; echo '<br>'; echo '$msg2 = ' . $msg2; } }
类的普通方法:
class Demo { function fun($msg1, $msg2) { echo '$msg1 = ' . $msg1; echo '<br>'; echo '$msg2 = ' . $msg2; } }
call_user_func_array()如何调用类的静态函数和类的普通方法?
类的静态方法的调用:
call_user_func_array(array("Demo","fun"), array("LAMP","核心科技"));
类的普通方法的调用:
call_user_func_array(array(new test(),"fun"), array("LAMP","核心科技"));
- call_user_func_array回调函数的说明格式总结
mixed call_user_func_array(callback function,array param_arr);
第一个参数在不同情况下调用的差异:
Callback(“函数名称字符串”) #回调全局函数
Callback(array(“类名称字符串”,“类中静态方法名称字符串”)) #回调类中的静态方法成员
Callback(array(对象引用,“对象中方法名称字符串”)) #回调对象中的方法成员
其中第二个参数各种情况下都是一致的:参数数组。
上机练习2:写一个函数实现字符串翻转。
需求说明:
- 原字符串: i love china!
- 翻转后的字符串: !anihc evol i
- 实现中文字符串的提取和翻转。
提示:
- UTF-8编码的中文字符占用三个字节。
- 使用ord()判断字符串中的字符,如果返回值大于127则为中文字符,否则为英文字符。
- 使用substr()截取字符串。
- 使用array_reverse()翻转输出数组。
- 使用join连接数组元素输出字符串。
递归函数
- 定义:自调用函数,在函数体内部直接或间接的自己调用自己,即函数的嵌套调用是函数本身。
- 在设计递归函数的时候要注意的问题:递归的结束条件。避免递归无限循环。
- 示例代码
/** * 递归函数测试 * @param int $n 整数参数 */ function recursiveDemo($n) { echo $n . '  '; if ($n > 0) { recursiveDemo ( $n - 1 ); }else{ echo '<-->'; } echo $n.'  '; } recursiveDemo(10);
输出结果:
使用自定义函数库
函数库属于一种设计模式。
为了更好的组织代码,使得自定义函数可以在同一个项目的多个文件中使用,通常将多个自定义的函数组织到同一个文件或多个文件中,这些收集自定义函数的PHP文件就是PHP函数库。
如何引用函数库?
引用语句 |
区别 |
require() 或者 require ‘函数库php’; |
函数库内容替换require关键字。多次调用函数库,效率高。 |
Require_once() 或者 require_once ‘函数库php’; |
行为同require();如果该文件在代码中已经被包括,则不会再次加载。 |
include() 或者 include ‘函数库php’; |
每次执行函数库时候,都要加载和评估。适合于每次代码执行通过条件判断读取不同函数库。 |
include _once() 或者 include_once ‘函数库php’; |
行为同include();如果该文件在代码中已经被包括,则不会再次加载。 |
上机练习3:斐波那契数列(Fibonacci sequence)
需求说明:
1、已知一对兔子每一个月可以生一对小兔子,而一对兔子出生后.第三个月开始生小兔子假如一年内没有发生死亡,则一对兔子开始,第N个月后会有多少对?
2、一年后又多少只兔子?
3、使用递归算法实现。
匿名函数和闭包
- PHP中的匿名函数(Anonymous functions),也称为闭包函数(closures),闭包通常是函数的嵌套。
- PHP允许临时创建一个没有指定名称的函数,常用作回调函数参数的值。
- 匿名函数示例代码:
/** * 定义一个匿名函数(闭包函数) * @var string 需要一个字符串参数 */ $func=function ($param){ echo $param; };//注意:匿名函数定义的“}”之后必须加“;”号。 $func("hello php function!");
- 调用回调函数时将匿名函数作为参数代码示例:
/** * 声明函数callback * @param callback $callback 需要传递一个匿名函数作为参数 */ function callback($callback){ $callback(); } callback(function (){ echo "匿名函数作为回调函数参数的值测试!"; });
- use关键字
- 匿名函数的作用域:匿名函数的作用域是在定义他的函数的内部,他能继承到的变量是外部函数的局部变量。这与全局函数和全局变量之间的关系是不同的。
- 使用use关键字来连接闭包函数和外界变量。
- 示例代码:
/** * 声明函数callback * @param callback $callback 需要传递一个匿名函数作为参数 */ function callback($callback){ $callback(); } $var="字符串变量"; callback(function () use($var){//引用传递use(&变量名) //echo $var;//没有使用use无法访问变量 echo $var;//使用use后可以正常反问 });
常用系统函数
系统函数 |
说明 |
string chr(int ascii) |
返回相对应于 ascii 所指定的单个字符; $str=chr(81)返回Q |
float ceil(float value) |
Value值上舍入 |
int rand ([ int $min ], int $max ) |
返回$min到$max之间的随机数 |
array array_combine(array keys,array values) |
返回一个 array,用来自 keys 数组的值作为键名,来自 values 数组的值作为相应的值。 |
Int strnatcmp(string str1,string strw) |
使用”自然”算法来比较两个字符串(区分大小写)。在自然算法中,数字 2 小于数字 10。在计算机排序中,10 小于 2,这是因为 10 中的第一个数字小于 2。 |
String implode(string glue,array pieces) |
把数组元素组合为字符串。Glue,转换后的连接符号,pieces待转换数组。 |
String readdir(resource dir_handle) |
返回目录资源句柄的文件名 |
bool sort (array &$array [, int $sort_flags ] ) |
对数组进行排序。当函数结束时数组单元将被从最低到最高重新安排。 |
bool print_r (mixed $expression [, bool $return ] ) |
print_r() 显示关于一个变量的易于理解的信息。如果给出的是 string、integer 或 float,将打印变量值本身。如果给出的是 array,将会按照一定格式显示键和元素。object 与数组类似。 |
void var_dump ( mixed expression [, mixed expression [, ...]] ) |
判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型。 |
int empty(mixed var) |
用来测试变量是否已经配置。若变量已存在、非空字符串或者非零,则返回 false 值;反之返回 true。 |
void unset ( mixed var [, mixed var [, ...]] ) |
unset() 销毁指定的变量 |
use() |
闭包函数连接外部变量 |
PHP7函数新特性
在脚本中开启declare(strict_types=1)进行参数类型和返回值类型的严格匹配。
例如:
/** * PHP7版本中函数特性:对函数的参数类型和返回值类型做限制 */ declare(strict_types=1);//开启参数类型严格匹配 function test(int $i,int $j):int{//形参 $sum=0;//声明一个变量保持计算后的结果 $sum=$i*$i+$j*$j;//计算 return $sum;//返回值,返回计算后的结果 } echo test(7,9);//实参
1.形参列表增加对参数类型的说明,实参类型和形参必须保持一致;
2.通过 函数名():返回值类型 设定函数返回值类型。
本博客文章未经许可,禁止转载和商业用途!
如有疑问,请联系: 2083967667@qq.com