当你的才华
还撑不起你的野心时
那你就应该静下心来学习
目录
用户自定义函数
定义
一个函数可由以下的语法来定义:
-
<?php
-
function foo($arg1, ..., $argn)
-
{
-
//do something
-
return $retval;
-
}
命名规范
函数名和 PHP 中的其它标识符命名规则相同。有效的函数名以字母或下划线打头,后面跟字母,数字或下划线。
函数调用前必须先定义
-
<?php
-
-
function actionA()
-
{
-
echo
"A";
-
}
-
-
actionA();
//可以调用
-
actionB();
//可以调用
-
-
function actionB()
-
{
-
echo
"B";
-
}
执行结果:
函数中调用函数
-
<?php
-
-
function actionA()
-
{
-
function actionB()
-
{
-
echo
"B";
-
}
-
}
-
-
actionB();
//无法调用
-
actionA();
//定义函数 actionB()
-
actionB();
//可以调用
执行结果:
PHP 不支持函数重载,也不可能取消定义或者重定义已声明的函数。
-
<?php
-
-
function sayHi()
-
{
-
echo
'Hi';
-
}
-
function sayHi()
-
{
-
echo
'Hello';
-
}
-
sayHi();
//报错,不能重定义函数 sayHi()
执行结果:
函数名是大小写无关的,不过在调用函数的时候,通常使用其在定义时相同的形式。
递归函数
递归函数的本质是函数调用函数本身,但是要避免递归函数/方法,调用超过 100-200 层,因为可能会使堆栈崩溃从而使当前脚本终止。 无限递归可视为编程错误。
-
<?php
-
function recursion($a)
-
{
-
if ($a <
20) {
-
echo
"$a\n";
-
recursion($a +
1);
-
}
-
}
执行结果:
函数的参数
通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表。
PHP 支持按值传递参数(默认),通过引用传递参数以及默认参数。也支持可变数量的参数;
通过引用传递参数
缺省情况下,函数参数通过值传递(因而即使在函数内部改变参数的值,它并不会改变函数外部的值)。如果希望允许函数修改它的参数值,必须通过引用传递参数。 如果想要函数的一个参数总是通过引用传递,可以在函数定义中该参数的前面预先加上符号 &:
-
<?php
-
function actionB(&$string)
-
{
-
$string .=
'and something extra.';
-
}
-
$str =
'This is a string, ';
-
actionB($str);
-
echo $str;
// outputs 'This is a string, and something extra.'
-
?>
执行结果:
默认参数的值
函数可以定义 C++ 风格的标量参数默认值,如下:
-
<?php
-
function makecoffee($type = "cappuccino")
-
{
-
return
"Making a cup of $type.\n";
-
}
-
echo makecoffee();
-
echo makecoffee(
null);
-
echo makecoffee(
"espresso");
-
?>
执行结果:
返回值
值通过使用可选的返回语句返回。可以返回包括数组和对象的任意类型。返回语句会立即中止函数的运行,并且将控制权交回调用该函数的代码行。
return
-
<?php
-
function square($num)
-
{
-
return $num * $num;
-
}
-
echo square(
4);
// outputs '16'.
执行结果:
函数不能返回多个值,但可以通过返回一个数组来得到类似的效果。
返回一个数组以得到多个返回值
-
<?php
-
function small_numbers()
-
{
-
return
array (
0,
1,
2);
-
}
-
list ($zero, $one, $two) = small_numbers();
从函数返回一个引用,必须在函数声明和指派返回值给一个变量时都使用引用操作符 & :
从函数返回一个引用
-
<?php
-
function &returns_reference()
-
{
-
return $someref;
-
}
-
-
$newref =& returns_reference();
-
?>
返回值类型声明
PHP 7 增加了对返回类型声明的支持。 类似于参数类型声明,返回类型声明指明了函数返回值的类型。可用的类型与参数声明中可用的类型相同。
-
<?php
-
-
function arraysSum(array ...$arrays): array
-
{
-
return array_map(
function(array $array): int {
-
return array_sum($array);
-
}, $arrays);
-
}
-
-
print_r(arraysSum([
1,
2,
3], [
4,
5,
6], [
7,
8,
9]));
以上例程会输出:
-
Array
-
(
-
[
0] =>
6
-
[
1] =>
15
-
[
2] =>
24
-
)
可变函数
PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。
变量函数不能用于语言结构,例如 echo, print, unset(), isset(), empty(), include, require 以及类似的语句。需要使用自己的包装函数来将这些结构用作变量函数。
-
<?php
-
-
class Test
-
{
-
public
static $actionB =
"property B";
-
-
public
function actionA()
-
{
-
echo
"method A";
-
}
-
public
static
function actionB()
-
{
-
echo
"method B";
-
}
-
}
-
-
function sayHi() {
-
echo
"Hi".PHP_EOL;
-
}
-
-
function sayHello($word = '') {
-
echo
"Hello $word";
-
}
-
-
-
$func =
'sayHi';
-
$func();
-
-
$func =
'sayHello';
-
$func(
'World');
-
-
$func =
'actionA';
-
(
new Test())->$func();
-
-
echo Test::$actionB;
-
$actionB =
'actionB';
-
Test::$actionB();
-
执行结果:
从结果可以看出
- 可以用可变函数的语法来调用一个对象方法和静态方法。
- 静态方法调用优先级高于属性调用
内部函数
也称为内置函数,PHP 有很多标准的函数和结构。还有一些函数需要和特定地 PHP 扩展模块一起编译,否则在使用它们的时候就会得到一个致命的未定义函数错误。
例如,要使用 image 函数中的 imagecreatetruecolor()
,需要在编译 PHP 的时候加上 GD 的支持。或者,要使用 mysql_connect()
函数,就需要在编译 PHP 的时候加上 MySQL 支持。
调用 phpinfo()
或者 get_loaded_extensions()
可以得知 PHP 加载了那些扩展库。同时还应该注意,很多扩展库默认就是有效的。PHP 手册按照不同的扩展库组织了它们的文档。
Note: 如果传递给函数的参数类型与实际的类型不一致,例如将一个 array 传递给一个 string 类型的变量,那么函数的返回值是不确定的。在这种情况下,通常函数会返回 NULL。但这仅仅是一个惯例,并不一定如此。
参见 function_exists(),函数参考,get_extension_funcs() 和 dl()。
匿名函数
匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。
匿名函数目前是通过 Closure 类来实现的。
-
<?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 7.1 起,不能传入此类变量: superglobals、 $this 或者和参数重名。
-
<?php
-
$msg =
'hello';
-
-
$a =
function () {
-
var_dump($msg);
-
};
-
$a();
-
-
$b =
function () use ($msg) {
-
var_dump($msg);
-
};
-
$b();
-
-
$msg =
'hi';
-
$b();
-
-
$c =
function () use (&$msg) {
-
var_dump($msg);
-
};
-
$c();
-
-
$d =
function ($arg) use ($msg) {
-
var_dump($arg .
' ' . $msg);
-
};
-
$d(
"hello");
执行结果:
从结果可以看出
- 使用 use 可以从父作用域继承变量
- 匿名函数是在定义的时候继承父作用域变量,而不是在调用的时候继承
- 变量使用引用赋值,则原变量发生改变,则引用该变量的变量也会发生变化
参考链接:https://www.shiyanlou.com/courses/23
我不需要自由,只想背着她的梦
一步步向前走,她给的永远不重