PHP函数的知识点
为什么要使用函数,据个人理解,一是代码的复用,二是常用功能的封装。
目录
1、函数的结构
(1)函数的构成部分
关键字:function
函数名:与变量命名规则相同,以字母或下划线开头,其后跟上字母、下划线、数字。
参数列表:($param1,$param2,……)
函数体:{ …… }
返回值:return $value
关于函数的返回值
- return语句是可选的
- 函数不一定有返回值,如只显示相关信息的函数。
- 或使用引用参数的方式来传递数据。
- 值通过使用可选的返回语句返回,如果省略return,则默认返回值为null。
- 返回值的类型包括数组和对象的任何类型。
- 返回语句会立即中止函数的运行,并且将控制权交回调用函数的代码行。
2、函数的定义与调用
例:函数的定义
function getValue($a,$b)
{
return $a+$b;
}
例:函数的调用
function getValue($a,$b)
{
return $a+$b;
}
$value = getValue(2,3);
echo $value; // 5
3、函数的参数
(1)函数的形参和实参
//函数定义
function getValue($a,$b) //形参
{
return $a + $b;
}
$a = 2 ;
$b = 3 ;
//函数调用
$value = getValue( $a , $b );//实参
echo $value; // 5
函数定义时的参数是形式参数,名为$a或$a1意义相同,无差别,
函数调用时使用的参数是实际要处理的数据,也称之为实参。
(2)函数参数的默认值
PHP函数的参数在传递参数时,
如果传入实参数量大于形参数量,多余的的将自动忽略。
如果传入实参数量小于形参数量,PHP将报错。这种情况可以通过设置函数未传入参数默认值的方式来实现。
如:
//函数定义
function getValue($a,$b=1) //形参,设置第2个参数的默认值是2
{
return $a + $b;
}
$a = 2 ;
//函数调用
$value = getValue( $a );//未传入第2个参数,$b将自动引入默认值 1
echo $value; // 5
注意:
- 默认值只能是常量或常量表达式,
- 设置默认值的1个或多个参数只能在最右侧,左侧的为未设置默认值的参数
(3)强类型参数
declare(static_types = 1); //声明严格模式
//函数定义
function getValue(int $a , int $b) //形参,强类型参数
{
return $a + $b;
}
注意:
- 支持类型:
- php 5.0.0 class interface name
- php 5.1.0 array
- php 5.4.0 callable
- php 7.0.0 bool,float,int,string
- declare(static_types = 1); 声明严格类型,是php7引入的严格类型检查模式的指定语法
(4)函数的可变参数
//函数的可变参数
//PHP 5.5之前的版本用这种方法更多
function get_sum(){
//func_num_args()功能:函数参数数量
$args_num =func_num_args();
$sum = 0;
if ($args_num = 0) { //如果函数参数数量为零,则返加$sum的值0
return $sum;
} else { //如果函数参数数量不为零
for ($i=0 ;$i<$args_num;$i++) { //则for循环取参数值并相加,
//func_args_arg($i)功能:取第$i个参数值
$sum += func_get_arg($i); //求$sum,即所有参数之和
}
}
}
//函数的可变参数
//PHP 5.6之后的版本用这种方法更多
function get_sum(...$nums){
$sum = 0;
if (!$num){
return $sum;
} else {
foreach ($nums as $num){
$sum += $num;
}
}
}
(5)函数参数的值传递与引用传递
<?php
//函数参数的值传递
//此处$num是形式参数,负责将函数调用的参数值传递入函数体即完成
function factorial($num)
{
$result = 1;
for ($i = 1; $i <= $num; $i++) { //此处 $num值为函数调用时实际变量$num1的变量值 3
$result *= $i;
}
$num =5 ; //此行代码将$num变量值赋值5
return $result;
}
$num1 =3;
echo factorial($num1); //显示 6
echo $num1; //显示 3 ,$num1值未改变
注意:函数参数的值传递是单身后,只能是实参向形参传递,而不能逆向传递;
4、函数体中变量的作用域
- 函数体中变量的作用域只限于函数体内
- 页面定义的局部变量不能作用于函数体内
5、函数的高级应用
(1)复杂函数之可变函数
PHP 中支持可变函数的概念(也叫变量函数),可以这样理解,如果一个变量名后有小括号
( )
,那么 PHP 就会寻找与变量值同名的函数并执行它。也就是说如果给一个变量赋不同的值,程序就会调用不同的函数。
需要注意的是,可变函数不能直接用于例如 echo、print、unset()、isset()、empty()、include、require 以及类似的语言结构,需要使用自己包装的函数来将这些结构用作可变函数。
可变函数的语法如下所示:
$name();
其中,$name 为一个变量,后面的小括号( )
与调用函数时函数名后的小括号功能相同。
<?php
//可变函数的示例
function website(){
echo 'C语言中文网<br>';
}
function url($str = ''){
echo $str.'<br>';
}
function title($string){
echo $string;
}
$funcname = 'website';
$funcname();
$funcname = 'url';
$funcname('http://c-local.biancheng.net/php/');
$funcname = 'title';
$string = 'PHP 教程';
$funcname($string);
?>
运行结果如下:
C语言中文网
http://c-local.biancheng.net/php/
PHP 教程
<?php
//可变函数应用实例
function get_apple($num) //销售apple函数
{
return 'sell ' . $num . ' Apple!' . '<br>';
}
function get_orange($num) //销售orange函数
{
return 'sell ' . $num . ' Orange!' . '<br>';
}
function get_fruit($fruit, $num)
{ //水果销售函数 $fruit:销售品种,$num:数量
$opt = "get_" . $fruit; //生成相应的函数名
return $opt($num); //执行并返回
}
echo get_fruit('apple', 5); // 输出sell 5 Apple!
//用非可变函数的方式实现上述功能
function get_fruit2($fruit, $num)
{
$foo = '';
if ($fruit = 'apple') {
get_apple($num);
} elseif ($fruit = 'orange') {
get_orange($num);
} else {
return false;
}
}
echo get_fruit('apple', 5); // 输出sell 5 Apple!
(2)复杂函数之嵌套函数
PHP的嵌套函数有一些特别之处。最特别的是,当外部函数被调用时,内部函数就会自动进行全局域中,成为新的定义函数。
//单层嵌套函数
function out()
{
if (!function_exists('in')) { //此if语句可先不加入来测试
function in()
{
echo '如果外部的函数out()没有被调用的话,我是不存在的';
}
}
}
//in(); //是没有被定义的,
out(); //无显示
in(); //如果外部的函数out()没有被调用的话,我是不存在的
//说明如果外部函数被调用的话,内部函数将升级为全局域函数
//out(); //再次调用out()函数,会报错
//如何再次使用out()函数,要加入function_exsits()检查in()函数是否已经在全局域中存在了
out(); //加入function_exsits(){}语句后,可正常执行out()函数
<?php
function out($str_msg)
{
if (!function_exists('in')) {
function in($msg)
{
// echo '如果外部函数out()没有被调用的话,我是不存在的'.'<br>';
echo $msg;
echo '<br>';
}
}
echo 'function out():' . $str_msg . '<br>';
in($str_msg);
echo '<hr>';
}
out('Hello!');
// 输出
//function out():Hello! 这是外层out()函数输出的
//如果外部函数out()没有被调用的话,我是不存在的 这是in()函数输出的
in('CCTV'); //先执行out()函数后,in()函数作用域升为全局,也正常执行
实际用于哪些方面,也是一头雾水!
(3)复杂函数之递归函数
递归,一直没真正弄懂的一个问题!先记下,再学习!
形式上看:函数在函数体内调用它自身;
作用是什么?把问题分解成类似的小问题,调用自身
什么时候用?符合能够把问题分解成类似的问题,如求乘积的问题
<?php
//递归( recursive)函数
//用递归函数方式求乘积
//阶乘:n!=n*(n-1)*(n-2)*(n-3)...
//转化为: n!=n*(n-1)*(n-1-1)*(n-1-1-1)
//3!=3*2*1
{
$sum = 1;
echo 'recruive()当前参数$i值为' . $i . '<br>';
if (1 == $i) { //递归终止条件
echo '$i=' . $i . '; $sum=' . $sum . '<br>';
return 1;
} else {
$sum = $i * recursive($i - 1);
}
echo '$i=' . $i . '; $sum=' . $sum . '<br>';
return $sum;
}
recursive(3);
//显示如下:
//recruive()当前参数$i值为3
//recruive()当前参数$i值为2
//recruive()当前参数$i值为1
//$i=1; $sum=1
//$i=2; $sum=2
//$i=3; $sum=6)
function recursive($i)
{
$sum = 1;
echo 'recruive()当前参数$i值为' . $i . '<br>';
if (1 == $i) { //递归终止条件
echo '$i=' . $i . '; $sum=' . $sum . '<br>';
return 1;
} else {
$sum = $i * recursive($i - 1);
}
echo '$i=' . $i . '; $sum=' . $sum . '<br>';
return $sum;
}
recursive(3);
//显示如下:
//recruive()当前参数$i值为3
//recruive()当前参数$i值为2
//recruive()当前参数$i值为1
//$i=1; $sum=1
//$i=2; $sum=2
//$i=3; $sum=6
(4)复杂函数之匿名(闭包)函数
- 匿名函数(Anonymous functions),也叫闭包函数(closures)
- 允许临时创建一个没有指定名称的函数,最经常用作回调函数(callback)的值
- 闭包函数可以作为变量的值来使用。
<?php
//简单好理解的匿名(闭包)函数的例子
//就是将一个没有函数名的函数定义赋值给一个变量
$example = function () {// 这里的函数没有函数名。?之所以称为为匿名函数?
echo 'Hello';
}; //这里一定要加上分号,作为一个语句的结束
$example(); //引用时就是变量名加(),很像可变函数
//输出:Hello
<?php
//错误示例,在闭包函数中使用全局变量
$msg = 'Hello';
$example = function () {
echo $msg;
};
$example(); //错误提示
<?php
//正确示例,如何在闭包中使用全局变量
$msg = 'Hello';
$example = function ($name) use (&$msg) { //&符号,引用方式,可去掉&符号,体验效果
echo $msg, ',', $name;
};
$msg = 'Hi';
$example('Lily'); //显示:Hello
//实用示例
function test_closure($name, closure $clo)
{
echo "Hello,{$name}<br>";
$clo();
}
/**
*在调用test_closure()函数前,先显示欢迎信息,
* 再进行处理真心关心的闭包的内容
*/
test_closure('Lily', function () {
echo '跳转到VIP页面';
});
//显示
//Hello,Lily
//跳转到VIP页面
(5)函数代码重用
- 主要是将函数放入一个公共函数文件,在函数使用前通过include\include_once\require\require_once来引入文件。
- 使用技巧:
- get_include_path()
- set_include_path()
//如果我们没有设置这个值,可能我们需要写一些完全的路径:
include("123/test1.php");
include("123/test2.php");
include("123/test3.php");
require("123/test4.php");
require("123/test5.php");
?>
//来引入很多外部文件,但是如果我们设置了set_include_path("123/"),我们就可以用下面这段代码代替。
set_include_path("123/");
include("test1.php");
include("test2.php");
include("test3.php");
require("test4.php");
require("test5.php");
//那么这个函数它不仅可以定义一个文件夹,我们可以定义很多文件夹。如下所示,我要写一个初始化函数:
function initialize()
{
set_include_path(get_include_path().PATH_SEPARATOR . "core/");
set_include_path(get_include_path().PATH_SEPARATOR . "app/");
set_include_path(get_include_path().PATH_SEPARATOR . "admin/");
set_include_path(get_include_path().PATH_SEPARATOR . "lib/");
set_include_path(get_include_path().PATH_SEPARATOR . "include/");
set_include_path(get_include_path().PATH_SEPARATOR."data/");
set_include_path(get_include_path().PATH_SEPARATOR."cache/");
}
//这样它的路径就成了:
//.;C:\php5\pear;core/;app/;admin/;lib/;include/;data/;cache/
//我们发现前面还有个.;C:\php5\pear;这到底是怎么回事呢,其实我们如果什么也不写直接先输出一下include_path的默认值,就会发现它就是.;C:\php5\pear;它可以允许随便去一个引入文件。
//PATH_SEPARATOR是php中的一个预定义常量(路径分隔符)。
//我们可以直接echo这个常量,在linux系统中,该常量输出":",在windows系统中,该常量输出";"号。
//因此,我们可以通过PATH_SEPARATOR输出值来判断当前服务器系统类型。
//如果不用考虑linux上使用,可以直接输出符号“;”,就好了。
<?php
//可替换set_include_path()的函数ini_set()
ini_set('include_path',get_include_path().PATH_SEPARATOR .'testa/');
ini_set('include_path',get_include_path().PATH_SEPARATOR .'testb/');
set_include_path(get_include_path().PATH_SEPARATOR . "core/");
set_include_path(get_include_path().PATH_SEPARATOR . "app/");
set_include_path(get_include_path().PATH_SEPARATOR . "admin/");
set_include_path(get_include_path().PATH_SEPARATOR . "lib/");
set_include_path(get_include_path().PATH_SEPARATOR . "include/");
set_include_path(get_include_path().PATH_SEPARATOR."data/");
set_include_path(get_include_path().PATH_SEPARATOR."cache/");
echo get_include_path();//显示当前导入文件路径
//显示
//.;C:\php\pear;testa/;testb/;core/;app/;admin/;lib/;include/;data/;cache/
//. 是指当前目标
//C:\php\pear;应该是系统设置的原始导入路径