函数是完成某些功能的代码片段,可以在程序中重复使用,可提高了代码的可维护性页面,可简单分为:系统函数、自定义函数;
1 自定义函数的使用:
函数的执行原理:当封装完函数之后将其导入内存中,当调用函数时,找到对应的函数,执行对应的函数体,当碰到Return语句或者执行到函数尾部时,将控制权移交到函数的位置上,接着程序继续执行;
1.2 函数定义:
1.1 一个函数可由以下的语法来定义:
<?php function foo($arg_1, $arg_2, /* ..., */ $arg_n) { echo "任何有效的 PHP 代码都有可能出现在函数内部,甚至包括其它函数和类定义。"; return $retval; } ?>
注意:函数名能够以字母或下划线开头,使用动词开始、驼峰命名法,函数名对大小写不敏感。
1.1 有条件的函数
<?php $makefoo = true; /* 不能在此处调用foo()函数, 因为它还不存在,但可以调用bar()函数。*/ bar(); if ($makefoo) { function foo() { echo "I don't exist until program execution reaches me.\n"; } } /* 现在可以安全调用函数 foo()了, 因为 $makefoo 值为真 */ if ($makefoo) foo(); function bar() { echo "I exist immediately upon program start.\n"; } ?>
注意:当一个函数是有条件被定义时,必须在调用函数之前定义。
1.3 函数中的函数
<?php function foo() { function bar() { echo "I don't exist until foo() is called.\n"; } } /* 现在还不能调用bar()函数,因为它还不存在 */ foo(); /* 现在可以调用bar()函数了,因为foo()函数 的执行使得bar()函数变为已定义的函数 */ bar(); ?>
函数不能重载或者重名,可以使用function_exists()检测函数是否存在;
1.4 函数的返回值
值通过使用可选的返回语句返回。只能返回 0 个或 1 个值,可以返回任何类型的值,所以需要返回多个值可以返回数组的形式,返回语句会立即中止函数的运行,并且将控制权交回调用该函数的代码行。如果省略了 return,则返回值为 NULL。
//返回不同类型的值,默认是返回NULL; if ( !function_exists('test') ) { function test() { return 123; return 12.3; return 'abc'; return null; return false; return array(123,12.3,'abc'); return new mysqli(); return md5('abc'); return fopen('1.php','r'); .... } }
1.5 函数的参数
函数可以有 0 个 或 多个 参数,通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表,参数可以从左向右求值,函数的参数可以是任意数据类型,可分为可选参数和必选参数,如果有可选参数和必选参数,必选参数一定在可选参数之前;
/* * @param number 行; * @param number 列; * @param string 默认内容; * @return string 表格 */ function createtable ( $rows,$cols,$content="xxx" ) { $table .= "<table border='1' width='80%' cellpadding='0' cellspacing='0'>"; for ( $i=1;$i<=$rows;$i++ ) { $table .= "<tr>"; for ( $j=1;$j<=$cols;$j++ ) { $table .= "<td>{$content}</td>"; } $table .= "</tr>"; } $table .= "</table>"; return $table; } echo table ( 3,5);
注意:默认参数和参数调用的顺序;
1.6 作用域
函数体内的变量称为局部变量,局部变量又分为动态变量和静态变量,动态变量函数执行完毕之后立即释放(不保存),静态变量是通过static关键字声明的变量,当第一次调用函数的时候相当与初始化静态变量,当函数执行完毕之后静态变量没有释放而是保存在静态内存中,当再次调用函数的时候首先从静态内存中取出变量的值继续执行。
函数体外的声明的变量或者在函数体内通过global关键字声明的变量称为全局变量。
//静态变量的栗子 $a = 2; $b = 3; function test (){var_dump($a); //null ,函数体内不能使用全局变量的值; global $b; //声明了$b是全局变量var_dump($b); //3 ,已经通过global声明使用的全局变量; $b = 5; static $i=1; echo $i; ++$i; }var_dump($i); //null,不能在函数体外调用局部变量的值; test(); //1 test(); //2 $i不再是1 echo $b; //5 ,在函数体内已经修改了$b的值;var_dump( $GLOBAL ); //打印全部的全局变量;
栗子比较混乱,为了节省文章长度;
1.7 函数的传值与传引用
传值:默认情况下,函数参数通过值传递(因而即使在函数内部改变参数的值,它并不会改变函数外部的值)。
//传值栗子
$str = "KiNg";
$cha_str = strtolower( $str );
echo $str ; //KiNg;
echo $cha_str; //king;
$str 还是原来的$str,没有被改变;
引用传值:如果希望允许函数修改它的参数值,必须通过引用传递参数。通过在参数前添加&符号,代表通过引用传递参数,在函数内部对其所做操作影响其本身;
//引用传值 $arr =array('a','b','c'); array_pop($arr);var_dump( $arr ); //$arr最后一个键值对已经被删除; //注意:只有传递变量才能使用传引用;
之前没有使用传引用是因为在传值之后直接使用传值的变量,相当于使用了改变之后的变量;
2 PHP特殊形式的函数
特殊函数形式主要有 5 种:可变函数、递归函数、匿名函数、回调函数、可变参数形式函数;
2.1 可变函数
PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。
<?php
function test(){
echo "this is a test";
}
test(); //正常方式;
$func_name = "test";
$func_name(); //可变函数get_defined_functions(); //得到所有函数;
?>
可变变量:一个可变变量获取了一个普通变量的值作为这个可变变量的变量名,都是等量代换的原则;
可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。
2.2 回调函数
通俗解释:回调函数是在调用一个函数时将另外一个函数名称作为参数传递到函数体中,并在函数体内调用;
栗子:被传递函数无参数时
<?php
//自定义一个函数作为参数
function study () {
echo "studying...";
}
//回调函数
function dowhat ( $func_name ) {
echo "正在";
$func_name();
}
//调用回调函数
dowhat("study"); //正在studying...
echo call_user_func("dowhat","study"); //正在studying...
栗子:被传递函数有参数时
<?php //自定义一个函数作为参数 function study ( $parameter ) { echo $parameter." is studying..."; } //回调函数 function dowhat ( $func_name,$argument ) { $func_name( $argument ); } //调用回调函数 dowhat("study","Tong"); //Tong is studying...call_user_func("dowhat","study","Tong"); //Tong is studying...call_user_func_array("dowhat",array("study","Tong")); //Tong is studying...
栗子:被传递函数含有多个参数;
<?php //自定义函数作为参数 function add ( $x,$y ) { echo $x+$y; } //自定义函数作为参数 function reduce ( $x,$y ) { echo $x-$y; } //回调函数 function calculate ( $way,$x,$y ) { $way($x,$y); } 调用回调函数的方法 calculate( "add",5,4 ); //9 echo "<br />"; calculate( "reduce",5,4 ); //1 echo "<br />";call_user_func("calculate","add",5,4); //9 echo "<br />";call_user_func_array("calculate",array("reduce",5,4)); //1
在PHP系统函数中,回调函数有很多应用,常用的有 array_map()、array_walk()、array_fileter() 等;
2.3 匿名函数/闭包函数
匿名函数,也叫闭包函数,允许临时创建一个没有指定名称的函数,最经常用作回调函数参数的值,匿名函数也可以作为变量的值来使用;
栗子1:
<?php
//创建匿名函数的方法;
$func = function (){
return "this is a test";
}; //记得有个分号;var_dump( $func() ); //this is a test;
栗子2:
<?php //匿名函数的使用; $func_name = create_function("","echo 'this is a test';"); //注意格式规范 $func_name(); //this is a test;
栗子3 :
<?php //匿名函数的使用; $arr = [1,2,3,4,5];var_dump($arr); //1,2,3,4,var_dump(array_map( function($x){return $x*2;} ,$arr)); //2,4,6,8,10call_user_func( function($name){echo "hello".$name;},"Tong" ); //hello Tong;
2.4 递归函数
如果函数A需要调用函数B,而发现函数B的代码实现与函数A完全相同,以此类推,此时就需要封装为递归函数,最基本的特点是函数自身调用自身,但必须在调用自身前有条件判断,否则无限无限调用下去。主要应用于PHP实现目录的遍历,目录的复制,删除非目录操作、无限极分类等;
<?php //递归函数; function test( $i ){ echo $i; if ( $i>=0 ) { $func_name =__FUNCTION__; $func_name($i-1); //相当于使用test($i-1); } echo $i; } test(2); //210-1-1012,要掌握解析为何是该结果哟!
__FUNCTION__的使用,返回的是函数的名称!尽量不要使用递归函数,很容易造成无限递归造成死循环;
3 使用自定义函数
当系统函数不能满足我们日常需求时,这时候就需要封装自定义的函数满足需求,一般我们都将函数封装到类似 xxx.func.php 的文件中,php提供了两种包含文件的方法:require/require_once、include/include_once;(带once和不带once的区别主要是:带once的会判断你在加载这个文件之前是否已经加载过了文件,避免重复加载。)
参考:include与require的区别;
不同点:
对 include() 来说,在 include() 执行时文件每次都要进行读取和评估;如果文件不存在,会给出一个 warning,但脚本会继续执行;require()不能有条件的包含文件。使用require()语句包含的文件不能有返回值。
对 require() 来说,文件只处理一次(实际上,文件内容替换了 require() 语句。如果文件不存在,会报出一个 fatal error 脚本停止执行;
应用
require 的使用方法如 require(“./inc.php”);通常放在PHP程式的最前面,PHP程式在执行前,就会先读入 require 所指定引入的档案,使它变成PHP 程式网页的一部份。
include 使用方法如 include(“./inc.php”);一般是放在流程控制的处理区段中。PHP程式网页在读到 include 的档案时,才将它读进来。这种方式,可以把程式执行时的流程简单化。
-