166.md 11.0 KB
Newer Older
W
wizardforcel 已提交
1 2 3 4 5 6
# PHP 中的函数

> 原文: [https://zetcode.com/lang/php/functions/](https://zetcode.com/lang/php/functions/)

在 PHP 编程教程的这一部分中,我们讨论函数。

W
wizardforcel 已提交
7
函数是较大程序中的一段代码。 该函数执行特定任务。 使用函数的优点是:
W
wizardforcel 已提交
8 9 10 11 12 13 14

*   减少代码重复
*   将复杂的问题分解成更简单的部分
*   提高代码的清晰度
*   重用代码
*   信息隐藏

W
wizardforcel 已提交
15
有两种基本类型的函数。 内置函数和用户定义的函数。 内置函数是 PHP 语言的一部分。 示例是:`phpinfo()``round()``abs()`。 用户定义的函数由应用员创建,以满足其需求。 它们是使用`function`关键字创建的。
W
wizardforcel 已提交
16 17 18

## PHP 定义函数

W
wizardforcel 已提交
19
使用`function`关键字创建一个函数。
W
wizardforcel 已提交
20 21 22

`simple.php`

W
wizardforcel 已提交
23
```php
W
wizardforcel 已提交
24 25 26 27 28 29 30 31 32 33 34 35
<?php

function displayVersion() {

    echo "this is PHP " . phpversion();
    echo "\n";
}

displayVersion();

```

W
wizardforcel 已提交
36
`function`关键字后跟带有圆括号的函数名称。 函数的主体位于大括号之间。 我们说我们将称为函数。 如果我们调用一个函数,则会执行函数体内的语句。
W
wizardforcel 已提交
37

W
wizardforcel 已提交
38
```php
W
wizardforcel 已提交
39 40 41 42 43 44
displayVersion();

```

该行代码调用该函数。

W
wizardforcel 已提交
45
```php
W
wizardforcel 已提交
46 47 48 49 50 51 52
$ php simple.php 
this is PHP 5.5.9-1ubuntu4.14

```

在这里,我们看到了脚本的结果。

W
wizardforcel 已提交
53
## PHP `return`关键字
W
wizardforcel 已提交
54 55 56 57 58

`return`关键字用于从函数返回值。 函数可能会也可能不会返回值。

`returning.php`

W
wizardforcel 已提交
59
```php
W
wizardforcel 已提交
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
<?php

function maximum($x, $y) {

    if ($x > $y) { 

        return $x;
    } else {

        return $y;
    }
}

$a = 23;
$b = 32;

$val = maximum($a, $b);
echo "The max of $a and $b is $val \n";

```

W
wizardforcel 已提交
81
我们有一个`maximum()`函数。 它返回两个数字的最大值。 我们无法将其命名为`max`,因为已经有内置的`max()`函数。 创建此示例是出于学习目的; 我们始终希望在现实世界的程序中使用内置函数。
W
wizardforcel 已提交
82

W
wizardforcel 已提交
83
```php
W
wizardforcel 已提交
84 85 86 87 88 89 90 91 92 93 94 95
if ($x > $y) { 

    return $x;
} else {

    return $y;
}

```

如果`$x`变量大于`$y`,则返回`$x`。 否则,我们返回`$y`

W
wizardforcel 已提交
96
```php
W
wizardforcel 已提交
97 98 99 100 101 102
$val = maximum($a, $b);

```

`maximum()`函数返回的值分配给`$val`变量。

W
wizardforcel 已提交
103
```php
W
wizardforcel 已提交
104 105 106 107 108 109 110 111 112 113 114 115
echo "The max of $a and $b is $val \n";

```

我们将两个数字的最大值打印到控制台。

## PHP 函数参数

大多数函数接受参数。 参数是发送到函数的值。 函数处理值,并可能返回一些结果。

`fahrenheit.php`

W
wizardforcel 已提交
116
```php
W
wizardforcel 已提交
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
<?php

function FTC($c) {

    return $c * 9/5 + 32;
}

echo FTC(100);
echo "\n";
echo FTC(0);
echo "\n";
echo FTC(30);
echo "\n";

```

在我们的示例中,我们将华氏温度转换为摄氏温度。 `FTC()`函数接受一个参数`$c`,即摄氏温度。

W
wizardforcel 已提交
135
```php
W
wizardforcel 已提交
136 137 138 139 140 141 142 143 144 145 146 147 148
$ php fahrenheit.php 
212
32
86

```

## PHP 隐式值

PHP 函数中的参数可能具有隐式值。 如果未提供任何值,则使用隐式值。

`implicit_value.php`

W
wizardforcel 已提交
149
```php
W
wizardforcel 已提交
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
<?php

function power($a, $b=2) {

    if ($b == 2) {

        return $a * $a;
    }

    $value = 1;

    for ($i = 0; $i < $b; $i++) {

        $value *= $a;
    }

    return $value;
}

$v1 = power(5);
$v2 = power(5, 4);

echo "5^2 is $v1 \n";
echo "5^4 is $v2 \n";

```

在这里,我们创建了幂函数。 该函数有一个带有隐式值的参数。 我们可以使用一个或两个参数来调用该函数。

W
wizardforcel 已提交
179
```php
W
wizardforcel 已提交
180 181 182 183 184 185
$ php implicit_value.php 
5^2 is 25 
5^4 is 625 

```

W
wizardforcel 已提交
186
## PHP 可变参数数量
W
wizardforcel 已提交
187 188 189 190 191 192 193

一个函数可以接受可变数量的参数。 换句话说,有时我们不知道将有多少参数传递给该函数。 `func_get_args()`函数返回一个包含函数的参数列表的数组。

从 PHP 5.6 开始,`...`运算符可用于创建可变函数。

`variable_arguments1.php`

W
wizardforcel 已提交
194
```php
W
wizardforcel 已提交
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
<?php

function sum(...$nums) {

    $sum = 0;

    foreach ($nums as $n) {
        $sum += $n;
    }

    return $sum;
}

echo sum(1, 2, 3) . "\n";
echo sum(1, 2, 3, 4) . "\n";
echo sum(1, 2, 3, 4, 5) . "\n";

```

我们创建一个`sum()`方法,该方法可以使用可变数量的参数。 该方法计算传递给该方法的值的总和。

W
wizardforcel 已提交
216
```php
W
wizardforcel 已提交
217 218 219 220 221 222 223 224 225 226 227
$sum = 0;
foreach ($args as $n) {
    $sum += $n;
}

return $sum;

```

我们计算并返回值的总和。

W
wizardforcel 已提交
228
```php
W
wizardforcel 已提交
229 230 231 232 233 234 235 236
echo sum(1, 2, 3) . "\n";
echo sum(1, 2, 3, 4) . "\n";
echo sum(1, 2, 3, 4, 5) . "\n";

```

我们将三个,四个和五个值传递给`sum()`函数。

W
wizardforcel 已提交
237
```php
W
wizardforcel 已提交
238 239 240 241 242 243 244 245 246 247 248
$ php variable_arguments1.php 
6
10
15

```

这是输出。

`variable_arguments2.php`

W
wizardforcel 已提交
249
```php
W
wizardforcel 已提交
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
<?php

function sum() {

    $args = func_get_args();

    $sum = 0;
    foreach ($args as $n) {
        $sum += $n;
    }

    return $sum;
}

echo sum(1, 2, 3) . "\n";
echo sum(1, 2, 3, 4) . "\n";
echo sum(1, 2, 3, 4, 5) . "\n";

```

W
wizardforcel 已提交
270
现在,使用`func_get_args()`函数创建相同的示例。
W
wizardforcel 已提交
271 272 273 274 275 276 277

## PHP 静态变量

静态变量是已静态分配的变量,其生存期遍及整个程序运行。 默认的局部变量不会在函数的连续调用中保留其值。

`non_static.php`

W
wizardforcel 已提交
278
```php
W
wizardforcel 已提交
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
<?php

function nonstatic() {

    $value = 0;
    $value += 1;

    return $value;
}

nonstatic();
nonstatic();
nonstatic();
nonstatic();

echo nonstatic(), "\n";

```

在上面的示例中,我们有一个普通的非静态变量。 每次调用函数时,我们都会增加变量。 我们调用该函数 5 次。 但是,对于函数的每次调用都会启动非静态变量。 在 5 个函数调用之后,`$value`等于 2。

W
wizardforcel 已提交
300
首次调用函数时,静态变量仅启动一次。 之后,他们保留自己的值。
W
wizardforcel 已提交
301 302 303

`static.php`

W
wizardforcel 已提交
304
```php
W
wizardforcel 已提交
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
<?php

function staticfun() {

    static $value = 0;
    $value += 1;

    return $value;
}

staticfun();
staticfun();
staticfun();
staticfun();

echo staticfun(), "\n";

```

连续 5 次通话后,`$value`等于 5。

W
wizardforcel 已提交
326
```php
W
wizardforcel 已提交
327 328 329 330 331 332 333 334 335 336 337 338 339
$ php nonstatic.php 
2
$ php static.php 
6

```

## PHP 匿名函数

匿名函数没有名称。

`anonymous.php`

W
wizardforcel 已提交
340
```php
W
wizardforcel 已提交
341 342 343 344 345 346 347 348 349 350 351 352 353
<?php

$var = function() {

    echo "This is anonymous function\n";
};

$var();

```

我们将函数主体分配给变量。 只能通过此变量来调用函数。

W
wizardforcel 已提交
354
```php
W
wizardforcel 已提交
355 356 357 358 359 360 361 362 363
$var = function() {

    echo "This is anonymous function\n";
};

```

注意右花括号后的分号。 这是必需的,因为构造是分配。

W
wizardforcel 已提交
364
```php
W
wizardforcel 已提交
365 366 367 368 369 370 371 372 373 374 375 376 377
$ php anonymous.php 
This is anonymous function

```

这是示例的输出。

## 通过值和引用传递参数

PHP 支持两种将参数传递给函数的方式。 默认方式是按值传递参数。 当我们按值传递参数时,该函数仅适用于值的副本。 当我们处理大量数据时,这可能会导致性能开销。

当我们通过引用传递值时,该函数会收到对实际值的引用。 修改后,原始值会受到影响。 这种传递值的方式更加节省时间和空间。 另一方面,它更容易出错。

W
wizardforcel 已提交
378
我们应该使用哪种方式传递参数? 这取决于实际情况。 假设我们有一组数据,即员工工资。 如果我们要计算数据的某些统计信息,则无需修改它们。 我们通过值。 如果我们处理大量数据,并且计算速度至关重要,则可以引用。 如果我们要修改数据,例如进行一些减薪或加薪,我们可以引用一下。
W
wizardforcel 已提交
379 380 381 382 383

以下两个示例涵盖了这两个概念。

`swap1.php`

W
wizardforcel 已提交
384
```php
W
wizardforcel 已提交
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
<?php

function swap($a, $b) {

    $temp = $a;
    $a = $b;
    $b = $temp;
    echo "inside swap function:\n";
    echo "\$a is $a \n";
    echo "\$b is $b \n";
}

$a = 4;
$b = 7;

echo "outside swap function:\n";
echo "\$a is $a \n";
echo "\$b is $b \n";

swap($a, $b);

echo "outside swap function:\n";
echo "\$a is $a \n";
echo "\$b is $b \n";

```

交换函数在`$a``$b`变量之间交换数字。 原始变量不受影响。

W
wizardforcel 已提交
414
```php
W
wizardforcel 已提交
415 416 417 418 419 420 421
$a = 4;
$b = 7;

```

最初,这两个变量被启动。

W
wizardforcel 已提交
422
```php
W
wizardforcel 已提交
423 424 425 426 427 428
swap($a, $b);

```

我们称为`swap()`函数。 该函数将`$a``$b`变量作为参数。

W
wizardforcel 已提交
429
```php
W
wizardforcel 已提交
430 431 432 433 434 435
$temp = $a;
$a = $b;
$b = $temp;

```

W
wizardforcel 已提交
436
`swap()`函数内部,我们更改值。 请注意,`$a``$b`变量是在本地定义的。 它们仅在`swap()`函数内部有效。
W
wizardforcel 已提交
437

W
wizardforcel 已提交
438
```php
W
wizardforcel 已提交
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
$ php swap1.php 
outside swap function:
$a is 4 
$b is 7 
inside swap function:
$a is 7 
$b is 4 
outside swap function:
$a is 4 
$b is 7 

```

输出显示原始变量不受影响。

W
wizardforcel 已提交
454
下一个代码示例通过引用将值传递给函数。 原始变量在`swap()`函数内更改。
W
wizardforcel 已提交
455 456 457

`swap2.php`

W
wizardforcel 已提交
458
```php
W
wizardforcel 已提交
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
<?php

function swap(&$a, &$b) {

    $temp = $a;
    $a = $b;
    $b = $temp;
    echo "Inside the swap function:\n";
    echo "\$a is $a \n";
    echo "\$b is $b \n";
}

$a = 4;
$b = 7;

echo "Outside the swap function:\n";
echo "\$a is $a \n";
echo "\$b is $b \n";

swap($a, $b);

echo "Outside the swap function:\n";
echo "\$a is $a \n";
echo "\$b is $b \n";

```

我们使用`&`字符通过引用传递值。

W
wizardforcel 已提交
488
```php
W
wizardforcel 已提交
489 490 491 492 493 494 495 496
function swap(&$a, &$b) {
...  
}

```

这个例子几乎与前面的例子相同。 除&字符外。

W
wizardforcel 已提交
497
```php
W
wizardforcel 已提交
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
$ php swap2.php 
Outside the swap function:
$a is 4 
$b is 7 
Inside the swap function:
$a is 7 
$b is 4 
Outside the swap function:
$a is 7 
$b is 4 

```

在这里我们看到`swap()`函数确实改变了变量的值。

## PHP 函数递归

W
wizardforcel 已提交
515
在数学和计算机科学中,递归是一种定义函数的方法,其中所定义的函数在其自己的定义内应用。 换句话说,递归函数调用自身以完成其工作。 递归是迭代的替代方法。 递归是函数式语言中的主要方法。
W
wizardforcel 已提交
516 517 518 519 520

一个典型的例子是阶乘的计算。

`recursion.php`

W
wizardforcel 已提交
521
```php
W
wizardforcel 已提交
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
<?php

function factorial($n) {

    if ($n==0) {

        return 1;
    } else {

        return $n * factorial($n - 1);
    }
}

echo factorial(4), "\n";
echo factorial(10), "\n";

```

在此代码示例中,我们计算两个数字的阶乘。

W
wizardforcel 已提交
542
```php
W
wizardforcel 已提交
543 544 545 546 547 548
return $n * factorial($n - 1);

```

在阶乘函数的主体内部,我们使用经过修改的参数调用阶乘函数。 该函数调用自身。

W
wizardforcel 已提交
549
```php
W
wizardforcel 已提交
550 551 552 553 554 555 556 557 558 559
$ php recursion.php 
24
3628800

```

这些就是结果。

## PHP 全局和局部变量

W
wizardforcel 已提交
560
接下来,我们将讨论 PHP 中变量的范围。 范围是可以引用变量的范围。 当我们使用函数时,有两个基本范围:全局范围和局部范围。 局部作用域也称为函数作用域。
W
wizardforcel 已提交
561 562 563

`scope1.php`

W
wizardforcel 已提交
564
```php
W
wizardforcel 已提交
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
<?php

$value = 1;

function simple() {

    var_dump($value);
}

simple();

```

在函数体内定义的变量不能在函数内引用。

W
wizardforcel 已提交
580
```php
W
wizardforcel 已提交
581 582 583 584 585 586
$ php scope1.php 
PHP Notice:  Undefined variable: value in /home/janbodnar/prog/php/functions/scope1.php on line 7
NULL

```

W
wizardforcel 已提交
587
`simple()`函数中的`$value`变量为`NULL`
W
wizardforcel 已提交
588 589 590

`scope2.php`

W
wizardforcel 已提交
591
```php
W
wizardforcel 已提交
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
<?php

$value = 4;

function simple() {
    $value = 3;
    echo $value, "\n";
}

simple();

echo $value, "\n";

```

在此示例中,我们有两个具有相同名称的变量。 它们不会冲突,因为它们存在于不同的范围内。

W
wizardforcel 已提交
609
```php
W
wizardforcel 已提交
610 611 612 613 614 615 616 617 618 619 620 621
$ php scope2.php 
3
4

```

该值在函数内部为 3,在函数外部为 4。

在下一个示例中,我们将在函数内部修改一个值。

`scope3.php`

W
wizardforcel 已提交
622
```php
W
wizardforcel 已提交
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
<?php

$value = 1;

function simple() {

    global $value;
    $value = 2;
}

echo $value, "\n";
simple();
echo $value, "\n";

```

我们使用`global`关键字来引用在函数主体外部定义的变量。

W
wizardforcel 已提交
641
```php
W
wizardforcel 已提交
642 643 644 645 646 647
$ php scope3.php 
1
2

```

W
wizardforcel 已提交
648
`$value`已在`simple()`函数内成功修改。
W
wizardforcel 已提交
649 650

在 PHP 教程的这一部分中,我们介绍了 PHP 函数。