函数
理论基础说明
1. 语法
函数是实现代码复用的重要方式,在所有编程语言中均如此
function 函数名称(类型: 参数列表): 返回值类型
{
// 函数体
return 返回值;
}
序号 | 名称 | 描述 |
---|---|---|
1 | function |
声明函数 |
2 | 函数名称 |
符合 PHP 标识符命名规范,不区分大小写 |
2 | 参数列表 |
零个或多个接收外部传入到函数的变量 |
2 | {... |
创建出一个封闭的函数作用域 |
2 | 函数体 |
由零个可多个合法的 PHP 语句组成 |
2 | return 值 |
将执行结果返回函数调用者[可选] |
2 | ...} |
函数执行结束,如果没有return ,则返回null |
2. 类型
序号 | 类型 | 语法 | 描述 |
---|---|---|---|
1 | 自定义函数 | function getName(){...} |
用户根据业务需求创建 |
2 | 系统函数 | substr(), count()... |
也叫预定义函数,不必声明直接调用 |
3 | 可变函数 | $funcName(); |
函数名使用变量表示 |
4 | 匿名函数 | $f = function (){...} |
也叫”闭包”或”函数表达式”,常用做回调处理 |
3. 返回值
- 函数必须要有返回值
- 函数必须是遵守单值返回原则
序号 | 场景 | 描述 |
---|---|---|
1 | return |
可以返回任何类型的值,包括函数类型 |
2 | 无return |
遇到} 也会返回, 默认返回null |
- 如果需要返回多个值,可以通过以下手段
序号 | 返回值类型 | 描述 |
---|---|---|
1 | string |
字符串拼接 |
2 | array |
数组 |
3 | json |
JSON 字符串 |
4 | serialize |
序列化字符串 |
json 和序列化,使用时需要进行解码操作
4. 参数
- 调用者可以通过参数将数据传递到函数中
- 参数是以逗号分隔的表达式列表
- 参数按照从左到右的顺序求值
参数类型
序号 | 类型 | 描述 |
---|---|---|
1 | 值参数 | 默认传参方式 |
2 | 引用参数 | 改变原始调用参数值 |
3 | 默认参数 | 调用时允许省略的参数 |
4 | 剩余参数 | 调用参数数量不确定 |
5. 回调函数
语法 | 类型 | 执行方式 | 应用场景 |
---|---|---|---|
匿名函数 | 闭包Closure |
异步 | 函数参数 |
异步执行,是指当前函数的执行并不会中断当前程序的执行流程
6. 命名空间
- 使用目录来整理文档, 允许将同名文档,存储在不同的目录下面即可
- 不同目录下的同名文件,访问时必须带上的它的目录名称,以未区别
- 命名空间采用类似的思想,同名函数,只要声明在不同空间中即可
- 同样, 访问这些函数时, 也需要带上它的命名空间才可以
代码小示例
可变函数、系统函数和匿名函数
<html>
<head>
<meta charset="utf-8">
<title>金额换算</title>
</head>
<body>
<?php
// 定义变量
$discount = $_POST['discount'];
$money = $_POST['money'];
$num = $_POST['num'];
$f = function ($discount) {
// 子函数
return function (float $money, float $num) use ($discount) : float
{
$amount = $money * $num;
return $amount = $amount >= 2000 ? $amount * $discount : $amount;
};
};
?>
<form method="post">
单价: <input type="text" name="money">
数量: <input type="text" name="num">
折扣:<input type="text" name="discount">
<input type="submit" value="提交">
</form>
<?php
echo "<h2>您应付金额是:</h2>";
echo $f($discount)($money,$num);
?>
</body>
</html>
通过JSON返回
<?php
function w_connct1() : string
{
// json_encode(): 将php数据编码为json格式的字符串返回
return json_encode(['status'=>1, 'message'=>'成功']);
}
$data = w_connct1();
echo $data;
echo '<hr>';
// 将json格式的字符串还原/解析为php对象/数组
$var = json_decode($data, true);
print_r($var);
echo '<hr>';
通过序列化返回
<?php
//序列化返回
function w_connct1() : string
{
return serialize(['status'=>1, 'message'=>'成功']);
}
echo w_connct1();
// 反序列化才可以使用
$arr =unserialize(w_connct1());
printf('<pre>%s</pre>', print_r($arr,true));
值参数、引用传递
<?php
function demo1(float $arg) : float
{
return $arg *= 2;
}
$value = 800;
echo demo1($value) , '<br>';
// 在函数中改变了调用参数的值,但原始调用参数并没有发生变化
echo $value;
echo '<hr>';
// 2. 引用传递
function demo2(float &$arg) : float
{
return $arg *= 2;
}
$value = 800;
echo demo2($value) , '<br>';
// 如果在参数前面使用了取地址符,则会改变原始调用参数的值
echo $value;
echo '<hr>';
// 3. 默认参数
// 默认参数必须写在必选参数的后面
function demo3(float $a, float $b, string $opt = '+' )
{
$res = 0;
switch ($opt) {
case '+':
$res = "$a + $b = " . ($a + $b);
break;
case '-':
$res = "$a - $b = " . ($a - $b);
break;
case '*':
$res = "$a * $b = " . ($a * $b);
break;
case '/':
$res = "$a / $b = " . ($a / $b);
break;
default:
$res = '非法操作符';
}
return $res;
}
echo demo3(10, 20), '<br>';
// echo demo3(10, 20, '*'), '<br>';
// echo demo3(10, 20, '#'), '<br>';
echo '<hr>';
// 4. 剩余参数
function demo4(float $a, float $b, float $c ) : float
{
return $a + $b + $c;
}
// 计算三个数之和
echo demo4(1,2,3), '<br>';
echo '<hr>';
function demo5( )
{
// 参数数量
// return func_num_args();
// 根据索引返回指定的调用参数
// return func_get_arg(2);
// return func_get_args();
$total = 0;
// for ($i = 0;$i <func_num_args(); $i++ ) {
// $total +=func_get_arg($i);
// }
// return $total;
foreach (func_get_args() as $value) {
$total +=$value;
}
return $total;
}
// echo demo5(3,4,7,8,24);
print_r(demo5(3,4,7,8,24));
echo '<hr>';
// echo demo5(1,2,3,4,5,6,9,22,67), '<br>';
// 使用剩余参数简化
// ...: 参数归纳:
function demo6(...$args ) : float
{
// return $args;
return array_sum($args);
// return array_product($args);
}
// print_r(demo6(3,4,7,8,24));
// echo demo6(1,2,3,4,5,6,9,22,67), '<br>';
// 调用参数
$arr = [1,2,3,4,5,6,9,22,67];
// ...:
// 1. 用在函数的形式参数列表中,表示"收集",将多个离散的参数打包到一个数组中处理
// 2. 用在函数的调用参数列表中,表示"展开",还原将一个数组展开成一个个离散的值
print_r(demo6(...$arr));
echo '<hr>';
// $config = ['localhost', 'phpedu', 'uft8', '3306'];
// $dsn = 'mysql:host=localhost;dbname=phpedu;charset=utf8;port=3306';
// $db = [$dsn, $username, $password];
// $pdo = new PDO(...$db);
// 扩展知识
$user[] = [100, '小红', 90];
$user[] = [110, '小兰', 60];
$user[] = [120, '小芬', 98];
// 数组解包
// js中解构赋值, php中也有解构
foreach ($user as list($id, $name)) {
printf('id=%s, name=%s<br>', $id, $name);
}
个人问题
foreach
的概念还是有点理解不透彻。还需要多加练习!
回调函数
<?php
# 回调函数:用在函数的回调参数中
//回调:在将来某一时刻,或者某个事件发生时再执行
//生成一个1-100共100个整数的数组
// $data=[1,2,3,4,5,6,7,8,9,...,100];
// $data = range(0, 99, 5);
// // range(起始数字,结束数字,步长)
// print_r($data);
// 只返回当前数据中偶数
$data = range(0, 99);
print_r($data);
//只返回偶数
var_dump(4 % 2);
echo ((4 % 2) == 0) ? '偶数' : '奇数';
$res = array_map(function (int $item) {
if ($item % 2 === 0) return $item;
}, $data);
// array_map(回调函数,数组)
echo $res;
printf('<pre?>%s</pre>', print_r($res, true));
// 过滤空值/假值
// array_filter仅返回结果为trus的数据
$res = array_filter($res, function ($item) {
return $item;
});
$res = array_values($res);
printf('<pre>%s</pre>', print_r($res, true));
命名空间
<?php
# 命名空间(相当于在不同的目录下)
// 防止命名冲突
// 全局成员:函数,常量,类,接口
namespace ns1 {
function demo1(): string
{
return __FUNCTION__;
}
}
namespace ns2 {
function demo1(): string
{
return __FUNCTION__;
}
}
// 全局空间不需要名称
namespace {
echo \ns1\demo1();
echo '<hr>';
echo \ns2\demo1();
}
总结
通过学习函数的概念以及函数基础知识点,算是已经对php的一个基本构成有了一个初步的了解了。但是,说实话,关于一些函数的作用以及方式,还是记不住。这个只能通过日后多加练习来进行记忆了!foreach
的概念还是有点理解不透彻。每次写都得参考教案来进行书写,根本记不住!!脑子瓦特了!!!