php中的函数
来源:互联网 发布:软件测试行业现状 编辑:程序博客网 时间:2024/06/17 03:17
定义一个函数
function test($a, $b){ $temp = $a + $b; return $temp;}
在php中,任何有效的 PHP 代码都有可能出现在函数内部,甚至包括其它函数和类定义。 同时,由于PHP 中的所有函数和类都具有全局作用域,可以定义在一个函数之内而在之外调用,反之亦然。 也就是说,在函数内定义的函数或类,在函数之外可以直接使用,使用时与定义它的函数并无关联。
另外,有别于变量,函数是不能重复定义的。
有条件地定义一个函数
有条件定义一个函数包括两种情形,即函数定义在一个条件语句中,或定义在另一个函数(假设为函数a)中,这时语句是否执行以及函数a是否调用,就成了函数是否定义的条件。在这两种情况下,函数必须是确定已经定义之后,才可以调用。
除了这两种情况,函数是可以先调用再定义的。
$a = 4;if($a % 2 == 0){ function test1(){ echo "test1\n"; }}switch($a){ case 4; function test2(){ echo "test2\n"; } break;}function fun(){ function test3(){ echo "test3\n"; }}fun();test1();test2();test3();本示例能够正常运行,对于test1(),因为if语句确实运行过了,对于test2(),switch中的分支确实运行过了,对于test3(),fun()函数也是确实运行过了,只有这样,这些函数才得以正常运行。
引用参数
通过在函数参数前添加"&"符号,可以定义引用参数,这时形参将成为实参的一个别名:
$a = 4;function test1(&$x){ $x++;}test1($a);echo $a; // 5
默认参数
可以给函数参数添加默认参数,这种情况下,如果调用时不提供实参,将会以默认参数作为实参。默认参数可以是各种标量、数组、NULL等,不过必须是常量表达式,不能是诸如变量,类成员,或者函数调用等。
$str = "Hi";function test($a, $b=null, $c=array("Ann","Nicke","Jeck"), &$x="Hello"){ foreach($c as $name) { if($a-- <= 0) break; echo "$x $name\n"; }}test(2);注意:
1.提供了默认参数的参数必须全部集中在参数列表的最后
2.引用参数也可以有默认参数(尽管上例没能很好地体现这一点)
类型声明
默认情况下函数的参数是没有指定类型的,这样的参数可以传递任何类型的参数。不过也可以为参数指定一个类型,如果参数的类型不正确,将会抛出TypeError异常。另外,虽然指定了参数的类型,仍可以通过给参数设定一个null默认值,使得参数可以接收null。
function test(int $x) { return $x * $x;}echo test(2); // 4
类名/接口名/array/callable/bool/float/int/string/self
注意:
1.不能使用integer/boolean/double等
2.self只用于类或接口方法,表示参数的类型与所有在类或接口类型相同
3.对于指定为类的参数,实参可以是子类对象
4.如果不开启严格模式,那么在默认情况下,PHP将会强迫错误类型的值转为函数期望的标量类型。 例如,一个函数的一个参数期望是string,但传入的是integer,最终函数得到的将会是一个string类型的值。
function test(float $x) { return $x * $x;}echo test("2x"); // 4
declare(strict_types=1);function test(float $x) { return $x * $x;}echo test("2x"); // 异常
可变数量的参数列表
函数可以接受不定数量的参数,这些参数可以在函数内部以数组的形式获得。
function test(int ...$num) { $count = 0; foreach($num as $x) $count += $x; return $count;}echo test(1,2,3); // 6
可变数量的参数最多只能有一个,而且只能出现在参数列表的最后一个。同时,可变数量的参数也可以是引用参数,可以有或者没有类型声明。
function test($x, $y=2, &...$num) { foreach($num as &$n) { $n += $x; $n *= $y; }}$a = 4;$b = 5;test(2,3,$a,$b);echo "$a\n"; // 18echo "$b\n"; // 21
可变数量的参数还有第二种实现方式,即使用以下三个函数:
int func_num_args ( void ) - 实参个数
mixed func_get_arg ( int $arg_num ) - 获取指定编号的实参值
array func_get_args ( void ) - 获取全部实参,返回一个数组
这3个函数可用于任意函数内部,与是否使用...参数无关
function test1($x, $y, ...$num) { var_dump(func_num_args()); var_dump(func_get_args());}function test2(){ $count = 0; for($i=0; $i<func_num_args(); $i++) $count += func_get_arg($i); return $count;}test1(1,2,3,4);echo test2(1,2,3,4);--------------------
int(4)
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
}
10
...运算符不仅可以用于函数形参,也可以用于函数实参,效果是将数组类型的实参拆解为多个值
function test($x, $y) { return $x + $y;}$a = [1,2,3];echo test(...$a); // 3echo test(...[3,4]); // 7echo test(2,3,4); // 5 实参数量可以比形参多,但不能少,否则出错
返回值
可以使用return语句从函数中返回一个值。可以返回包括数组和对象的任意类型。如果省略了 return,则返回值为 NULL。 函数不能返回多个值,但可以通过返回一个数组来得到类似的效果。
返回一个引用
要让函数返回一个引用,必须在函数声明和函数调用处,都使用&运算符,而return语句处则不需要。
function &test(&$x, &$y) { if($x > $y) return $x; else return $y;}$a = 3;$b = 4;$c = &test($a, $b);$c++;echo "$a\n"; // 3echo "$b\n"; // 5
function &test($x) { static $max = 0; $max = $x > $max ? $x : $max; return $max;}$a = 3;$b = 4;$c = &test($a);test($b);echo $c; // 4在本例中,局部变量定义成静态变量,从语法上这不是必须的,但是如果定义成非静态变量,则每次函数返回的引用都将是新的局部变量(也就是每次函数调用都会临时创建的局部变量)。
指定函数的返回类型
与函数的参数可以声明类型一样,函数的返回值也可以声明类型,例如:
function numAdd($x, $y) : int { return $x + $y;}$x = numAdd(3,4);$y = numAdd("23", true);echo $x; // 7echo $y; // 24与参数的类型一样,如果需要严格的类型匹配,可以为文件添加 declare(strict_types=1); 声明。
可变函数
与可变变量类似,PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。不过,可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及类似的语言结构。如果确实需要,可自行对这些语言结构进行函数封装。
一般情况下,在调用函数或方法时,函数名前面是不会有$符号的,例如:
var_dump();
如果出现了$符号,则表明$之后的标识符不是一个函数名,只有在与$结合起来解析后,才会得到真正的函数名(或方法名)。
function myPrint($x) { echo "$x\n";}function varPrint($x) { return print $x;}$a = "myPrint";$a("Hello world!");这里便出现了$xxx()的形式,类似的,方法也可以使用可变函数:xxx->$xxx(); xxx::$xxx();
可变的变量不仅仅只能是一个字符串,还可以是数组,一般包含以下几种形式:
1.字符串:函数名或方法名
2.字符串:"类名::静态方法名"
3.数组:array("类名","静态方法名")
4.数组:array(对象,"对象方法名")
另外,注意在使用类的静态成员时,解析的优先问题:
class TestClass { public static $a = "func"; }function func() { return "func";}echo TestClass::$a; // funcecho TestClass::$a(); // 出错第二个输出语句被解析为:
(TestClass::($a))()
而不是:
(TestClass::$a)()
由于$a未定义,所以出错。
class TestClass { public static $a = "func"; public static function ft() { return "ft"; }}function func() { return "func";}$a = "ft";echo TestClass::$a; // funcecho TestClass::$a(); // ft本例中,两个输出语句都能正常输出。
匿名函数/闭包
匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。 目前通过 Closure 类来实现。
定义匿名函数时,不需要指定函数名,类似如下形式:
function ($a ...) {}
可以直接将这样的表达式传递给函数调用,也可以赋值给一个变量
$p = function($x) { echo "$x\n";};$p("Hello world!");
闭包的特色功能在于继承父作用域的变量,只需要使用use语言结构。注意,PHP 7.1 起,不能传入此类变量: 超级全局变量、 $this 或者和参数重名。
$message = 'hello';// 继承 $message$example = function () use ($message) { var_dump($message);};$example(); // string(5) "hello"// 变量的值在函数定义时继承,而不是在函数调用时$message = 'world';$example(); // string(5) "hello"在本例中,如果不使用use继承变量,那么函数内$message实际上只是一个未定义的局部变量。从父作用域中继承变量与使用全局变量是不同的。全局变量存在于一个全局的范围,无论当前在执行的是哪个函数。而 闭包的父作用域是定义该闭包的函数(不一定是调用它的函数)。
下面是一个相对实用一些的闭包实例:
function operate($operator){ return function($a,$b) use($operator) { switch($operator) { case "-": return $a-$b; case "+": return $a+$b; } };}$subtraction = operate("-");echo $subtraction(4,3); // 1$addition = operate("+");echo $addition(1,2); // 3
$message = 'hello';// 引用继承$example = function () use (&$message) { var_dump($message);};$example(); // string(5) "hello"// 外界变量的改变可以映射到闭包内部$message = 'world';$example(); // string(5) "world"
下面的例子演示了引用继承多个变量:
function func($x, $y) { return function() use(&$x, &$y) { echo $x + $y; $x++; $y++; };}$a = func(4,5);$a(); // 9$a(); // 11$a(); // 13
在类内部定义的匿名函数会自动绑定$this,如果要避免此特性,可将匿名函数定义成静态的
class MyClass{ public function __construct($num) { $this->num = $num; } public function func() { return function() { var_dump($this->num); }; }}$a = new MyClass(3);$x = $a->func();$x(); // int(3)$a->num = 4;$x(); // int(4)
class MyClass{ public function __construct($num) { $this->num = $num; } public function func() { return static function() { }; }}
- PHP函数中的函数
- PHP中的时间函数
- PHP中的字符串函数
- php中的时间函数
- PHP中的empty()函数
- PHP中的字符串函数
- php中的截取函数
- PHP中的sprintf()函数
- php中的htmlspecialchars函数
- PHP中的字符串函数
- php 中的mail函数
- php中的sleep()函数
- PHP中的构造函数
- PHP中的mysql_real_escape_string函数
- PHP中的function_exists函数
- PHP中的数组函数
- php 中的日期函数
- PHP 中的时间函数
- Linux之命令scp
- Monotone Increasing Digits问题及解法
- 什么是无侵入
- Servlet
- 49. Group Anagrams
- php中的函数
- Linux 进程间通信2
- Nicescroll滚动条插件的用法
- 解决Mac环境下vim中文乱码&转码问题
- git如何上传所有的新文件
- 设计模式之策略模式
- mongodb入门--增删改查
- 【Linux】Linux中常用操作命令
- SpringBoot学习总结(二)