用户自定义函数
带有return 就表示有返回值,没有则表示没有返回值
<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
echo "Example function.\n";
return $retval;
}
?>
函数无需在调用之前被定义,除非是下面两个例子中函数是有条件被定义时。
当一个函数是有条件被定义时,必须在调用函数之前定义。
有条件的函数
<?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";
}
?>
函数中的函数
<?php
function foo()
{
function bar()
{
echo "I don't exist until foo() is called.\n";
}
}
/* 现在还不能调用bar()函数,因为它还不存在 */
foo();
/* 现在可以调用bar()函数了,因为foo()函数
的执行使得bar()函数变为已定义的函数 */
bar();
?>
PHP 中的所有函数和类都具有全局作用域,可以定义在一个函数之内而在之外调用,反之亦然。
PHP 不支持函数重载,也不可能取消定义或者重定义已声明的函数。
PHP 的函数支持可变数量的参数和默认参数。
在 PHP 中可以调用递归函数。
<?php
function recursion($a)
{
if ($a < 20) {
echo "$a\n";
recursion($a + 1);
}
}
?>
但是要避免递归函数/方法调用超过 100-200 层,因为可能会使堆栈崩溃从而使当前脚本终止。 无限递归可视为编程错误。
函数的参数
PHP 支持按值传递参数(默认),引用传递参数以及默认参数。也支持可变长度参数列表。
值传递:
<?php
function takes_array($input)
{
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
}
?>
引用传递参数
如果想要函数的一个参数总是通过引用传递,可以在函数定义中该参数的前面加上符号 &:
<?php
function add_some_extra(&$string)
{
$string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str; // outputs 'This is a string, and something extra.'
?>
默认参数 默认值必须是常量表达式,不能是诸如变量,类成员,或者函数调用等。
注意当使用默认参数时,任何默认参数必须放在任何非默认参数的右侧;否则,函数将不会按照预期的情况工作。
<?php
function makecoffee($type = "cappuccino")
{
return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");
?>
输出:
Making a cup of cappuccino.
Making a cup of .
Making a cup of espresso.
PHP 还允许使用数组 array 和特殊类型 NULL 作为默认参数
自 PHP 5 起,传引用的参数也可以有默认值。
函数默认参数的不正确用法
默认参数没有放到最右侧!!!!!
<?php
function makeyogurt($type = "acidophilus", $flavour)
{
return "Making a bowl of $type $flavour.\n";
}
echo makeyogurt("raspberry"); // won't work as expected
?>
函数默认参数正确的用法
<?php
function makeyogurt($flavour, $type = "acidophilus")
{
return "Making a bowl of $type $flavour.\n";
}
echo makeyogurt("raspberry"); // works as expected
?>
有效的参数类型:
Type | Description | Minimum PHP version |
---|---|---|
Class/interface name | The parameter must be an instanceof the given class or interface name. | PHP 5.0.0 |
array | The parameter must be an array. | PHP 5.1.0 |
callable | The parameter must be a valid callable. | PHP 5.4.0 |
bool | The parameter must be a boolean value. | PHP 7.0.0 |
float | The parameter must be a floating point number. | PHP 7.0.0 |
int | The parameter must be an integer. | PHP 7.0.0 |
string | The parameter must be a string. | PHP 7.0.0 |
可变数量的参数列表
在 PHP 5.6 及以上的版本中,由 … 语法实现;
在 PHP 5.5 及更早版本中,使用函数 func_num_args(),func_get_arg(),和 func_get_args() 。
<?php
function sum(...$numbers) {
$acc = 0;
foreach ($numbers as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
?>
返回值
1,通过关键字return实现
2,如果省略了 return,则返回值为 NULL
<?php
function square($num)
{
return $num * $num;
}
echo square(4); // outputs '16'.
?>
可变函数
如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。
可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及类似的语言结构。需要使用自己的封装的函数来将这些结构用作可变函数。
<?php
function foo() {
echo "In foo()<br />\n";
}
function bar($arg = '') {
echo "In bar(); argument was '$arg'.<br />\n";
}
// 使用 echo 的包装函数
function echoit($string)
{
echo $string;
}
$func = 'foo';
$func(); // This calls foo()
$func = 'bar';
$func('test'); // This calls bar()
$func = 'echoit';
$func('test'); // This calls echoit()
?>
用可变函数的语法来调用一个对象的方法。
<?php
class Foo
{
function Variable()
{
$name = 'Bar';
$this->$name(); // This calls the Bar() method
}
function Bar()
{
echo "This is Bar";
}
}
$foo = new Foo();
$funcname = "Variable";
$foo->$funcname(); // This calls $foo->Variable()
?>
当调用静态方法时,函数调用要比静态属性优先:
<?php
class Foo
{
static $variable = 'static property';
static function Variable()
{
echo 'Method Variable called';
}
}
echo Foo::$variable; // This prints 'static property'. It does need a $variable in this scope.
$variable = "Variable";
Foo::$variable(); // This calls $foo->Variable() reading $variable in this scope.
?>
匿名函数
匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
return strtoupper($match[1]);
}, 'hello-world');
// 输出 helloWorld
?>
闭包函数也可以作为变量的值来使用。PHP 会自动把此种表达式转换成内置类 Closure 的对象实例。把一个 closure 对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最后也要加上分号;
<?php
$greet = function($name)
{
printf("Hello %s\r\n", $name);
};
$greet('World');
$greet('PHP');
?>
闭包可以从父作用域中继承变量。 任何此类变量都应该用 use 语言结构传递进去。
<?php
$message = 'hello';
// 没有 "use"
$example = function () {
var_dump($message);
};
echo $example();
// 继承 $message
$example = function () use ($message) {
var_dump($message);
};
echo $example();
// Inherited variable's value is from when the function
// is defined, not when called
$message = 'world';
echo $example();
// Reset message
$message = 'hello';
// Inherit by-reference
$example = function () use (&$message) {
var_dump($message);
};
echo $example();
// The changed value in the parent scope
// is reflected inside the function call
$message = 'world';
echo $example();
// Closures can also accept regular arguments
$example = function ($arg) use ($message) {
var_dump($arg . ' ' . $message);
};
$example("hello");
?>
输出:
Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) “hello”
string(5) “hello”
string(5) “hello”
string(5) “world”
string(11) “hello world”