《PHP 7从零基础到项目实战》学习笔记3——函数

函数分为系统内部函数和用户自定义函数。如果一段功能代码需要多次在不同地方使用,便可以将其封装成一个函数,即自定义函数。这样在使用时直接调用该函数即可,无需重写代码。除了自定义函数外,PHP内还提供了许多内置函数,可以直接使用。

1.函数的使用

函数可用以下语法来定义:

functin foo($arg_1, $arg_2) {
    statement(函数体)
}

其中,foo表示函数名称, a r g 1 和 arg_1和 arg1arg_2表示函数的参数。函数的命名规则:**以字母或下划线开头,后面跟字母、数字或下划线。**PHP中函数的作用域是全局的,在一个文件中定义了函数后,可以在该文件的任何地方调用。

示例:

<?php
/**
 * 返回两数之和
 * @param $a 参数1
 * @param $b 参数2
 * @return mixed
 */
function add($a, $b) {
    return $a + $b;
}
$c = add(1, 2);
echo $c; // 3
?>

注意:PHP不支持函数重载,也不能取消定义或重定义已声明的函数。

2.函数的参数

PHP支持按值传递参数(默认),通过引用传递参数及默认参数,也支持可变长度参数列表。PHP支持函数参数类型声明。

2.1参数传递方式

在调用函数时,需要向函数传递参数,被传入的参数称为实参,而函数定义的参数称为形参
PHP中函数参数传递的三种方式:按值传递、通过引用传递和默认参数。

2.1.1按值传递

按值传递的参数相当于在函数内部有这个参数的备份,即使在函数内部改变参数的值,也并不会改变函数外部的值。

  • 按值传递
<?php
/**
 * 值传递
 * @param $a
 * @return int
 */
function test($a) {
    $a += 1;
    return $a;
}
$a = 1;
echo test($a); // 2
echo test(2); // 3
echo $a; // 1
?>

2.1.2通过引用传递参数

如果希望允许函数修改它的参数值,就必须通过引用传递参数。这样我们在函数内部是对这个参数本身进行操作。

<?php
/**
 * 引用传递
 * @param $a
 * @return int
 */
function test(&$a) {
    $a += 1;
    return $a;
}

$x = 1;
// 引用传递的参数必须是一个变量
echo test($x); // 2
echo $x; // 2
?>

2.1.3默认参数

PHP支持函数默认参数,允许使用数组array和特殊类型NULL作为默认参数。默认值必须是常量表达式,不能是变量、类成员或函数调用等。

<?php
function test($arr = array('red', 'green', 'blue'), $str = 'color') {
    echo "My favourite $str is $arr[1]\n";
}
$colors = ['yellow', 'black', 'gray'];
$color = "orange";
test(); // My favourite color is green
test($colors, $color); // My favourite orange is black
?>

为避免出现意外情况,一般将默认参数放在非默认参数的右侧。

<?php
function test($arg2, $type = "arg1") {
    return "$arg2 and $type.\n";
}
echo test("test"); // test and arg1.
?>

2.2参数类型声明

表2-1 参数声明类型
| 类型 | 说明 | PHP版本 | | -------------------------------- | ---------------------------- | ------- | | class/interface name(类,接口) | 参数必须是指定类或接口的实例 | PHP 5.0 | | Array | 参数为数组类型 | PHP 5.1 | | Callable | 参数为有效的回调参数 | PHP 5.4 | | Bool | 参数为布尔型 | PHP 7.0 | | Float | 参数为浮点型 | PHp 7.0 | | Int | 参数为整型 | PHP 7.0 | | String | 参数为字符串类型 | PHP 7.0 |
<?php
class A{}
class B extends A{} // 类B继承自类A
class C extends B{}
function f(A $a) {
    echo get_class($a)."\n";
}
f(new A); // A
f(new B); // B
f(new C); // C
?>
<?php
function test(int $a, String $b, String $c) {
    echo ($a + $b);
    echo " the string is $c";
}
test( 3.14159, 2, 'hello'); // 5 the string is hello
?>
<?php
/**
 * 在PHP 7中,可以使用declare(strict_types = 1)设置严格模式
 */
declare(strict_types = 1);
function test2(int $a, string $b, string $c) {
    echo ($a + $b);
    echo " the string is $c";
}
test2(3.84, 2, "test2");
// Fatal error: Uncaught TypeError: Argument 1 passed to test2() must be of the type int, float given
?>

2.3可变参数数量

PHP 5.6之后,参数可包含“…“来表示函数可接受一个可变数量的参数,可变参数将会被当作一个数组传递给函数。

<?php
function test(...$num) {
    $acc = 0;
    foreach ($num as $key => $value) {
        $acc += $value;
    }
    return $acc;
}
echo test(1, 2, 3, 4); // 10
?>

3.函数返回值

函数的返回值可以是任意类型的数据,函数也可以不返回值。函数使用return返回数据,遇到return语句会立即终止执行。

<?php
function square($num) {
    return $num * $num;
}
echo square(4); // 16
?>

函数不能返回多个值,但可以通过返回一个数组来得到类似的效果。

<?php
function square($num) {
    return $num * $num;
}
echo square(4); // 16

function small_numbers() {
    return array(0, 1, 2, 3);
}
list($a, $b, $c) = small_numbers();
echo $a.$b.$c; // 012
?>

在PHP 7中函数增加了返回值的类型声明,非严格模式下,PHP将会尝试将返回值类型转换成期望得到的值类型,但在严格模式下,函数的返回值类型必须与声明的返回值类型一致。

<?php
function sum($a, $b):float {
    return $a + $b;
}
var_dump(sum(1, 2)); // float(3)
?>
<?php

declare(strict_types=1);
function sum($a, $b): int
{
    return $a + $b;
}

var_dump(sum(1, 3.14));
// Fatal error: Uncaught TypeError: Return value of sum() must be of the type int, float returned
?>

4.可变函数

PHP支持可变函数。如果一个变量名后有圆括号,PHP将寻找与变量的值同名的函数,并尝试执行它。

<?php
function foo() {
    echo "In foo() \n";
}
function bar($arg = '') {
    echo "In bar(); argument was '$arg'.\n";
}
// 使用echo的包装函数
function echoit($string) {
    echo $string;
}
$func = 'foo';
$func(); // In foo() 
$func = 'bar';
$func('test'); // In bar(); argument was 'test'.
$func = 'echoit';
$func('test'); // test
?>

5.内置函数

6.匿名函数

匿名函数也叫闭包函数,允许临时创建一个没有指定名称的函数,通常用作回调函数参数的值。

<?php
echo preg_replace_callback('~-([a-z])~', function($match) {
    return strtoupper($match[1]);
}, 'hello-world');
// helloWorld
?>

闭包函数也可以作为变量的值来使用,php会自动将这种表达式转换成内置类closure的对象实例。

<?php
$greet = function($name) {
    echo "hello $name \n";
};
$greet('World');
$greet('PHP');
// hello World 
// hello PHP 
?>

闭包可以从父作用域继承变量,这时需要使用关键词user。

<?php
$message = 'hello';

// 没有'use'
$example = function () {
    var_dump($message);
};

echo $example(); // NULL

// 继承$message
$example = function() use ($message) {
    var_dump($message);
};

echo $example(); // string(5) "hello"

/**
 * 当函数被定义时就继承了作用域中变量的值,而不是在调用时才继承
 */
// 此时改变$message的值对继承没有影响
$message = 'world';
echo $example(); // string(5) "hello"

// 重置$message的值为'hello'
$message = 'hello';
// 继承引用
$example = function () use (&$message) {
    var_dump($message);
};
echo $example(); // string(5) "hello"

/**
 * 父作用域中,$message的值被改变,当函数被调用时$message的值发生改变
 */
// 注意与非继承引用的区别
$message = 'world';
echo $example(); // string(5) "world"

// 闭包也可接收参数
$example = function ($arg) use ($message) {
    var_dump($arg.' '.$message);
};
$example("hello"); // string(11) "hello world"
?>

7.递归与迭代

7.1递归

递归就是程序调用自身、函数不断引用自身,直到引用的对象已知。

构成递归需满足以下两个条件:

  • 子问题需与原始问题为同样的事,且更为简单。
  • 不能无限制地调用本身,必须有一个出口,化简为非递归状况处理。

例如,斐波那契数列:1,1,2,3,5,8…

<?php
function readd($n) {
    if($n > 2) {
        $arr[$n] = readd($n - 2) + readd($n -1); // 递归调用自身
        return $arr[$n];
    } else {
        return 1;
    }
}
echo readd(30); // 832040
?>

7.2迭代

迭代就是利用变量的原值推算出变量的一个新值。

<?php
function diedai($n) {
    for($i = 0, $j = 0; $i < $n; $i++) {
        $j = $j + $i;
    }
    return $j;
}
echo diedai(4); // 6
?>

往期文章:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦里逆天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值