PHP 速成课程(4):条件、循环和函数

条件执行

PHP 中,只有当条件为真时才可以执行一行代码

1
2
3
if ($name === 'William') {
echo 'Hello William';
}

括号内的代码称为表达式。PHP 将执行此代码并返回其布尔值(真或假)。

如果结果为 true,则将执行 { } 之间的代码。

如果结果为 false,则不会执行此 if 块中的任何内容

以下是另一个带有大于运算符>的示例

1
2
3
4
5
$amount = 120;

if ($amount > 100) {
echo 'Free shipping';
}

此处表达式 ($amount) 将返回 true,因此运费免费。

如果条件为 false,则可以执行代码

1
2
3
4
5
6
7
$amount = 120;

if ($amount > 100) {
echo 'Free shipping';
} else {
echo 'Shipping 9.95$';
}

此处关键字 else 表示如果表达式为 false,则执行代码

最后,可以有多个条件

1
2
3
4
5
6
7
8
9
$amount = 120;

if ($amount > 100) {
echo 'Free shipping';
} elseif ($amount > 50) {
echo 'Shipping 9.95$';
} else {
echo 'Shipping 19.95$';
}

elseif 关键字用于测试另一个条件。请注意,只有当第一个条件为假时才会测试此条件。

如果第一个和第二个条件都为假,则将执行 else 部分中的代码。

比较运算符

以下是可以在表达式中使用的不同运算符。

== 相等 无类型检查
=== 相等 有类型检查
!= 不相等
||
&& 并且
> 大于
< 小于

可以使用运算符 && 同时测试多个表达式

1
2
3
if ($amount > 0 && $amount < 50) {
echo 'The price is between 1 and 49';
}

同样的原则也适用于运算符或 ||

1
2
3
if ($amount === 100 || $amount === 200) {
echo 'The price is 100$ or 200$';
}

没有比较运算符的表达式

1
2
3
4
5
$amount = 0;

if ($amount) {
echo 'The price is not zéro';
}

此处的表达式 ($amount) 不包含比较运算符,尽管如此,此代码仍然有效。为什么?在 PHP 中,每个表达式都转换为布尔值。因此,此处 0 转换为 false。除零(或 null)以外的任何其他值都将转换为 true

转换为布尔值

以下是将转换为 false 的值列表

false
0
0.0
null
'0'(等于零的字符串)
'' (空字符串)

所有其他值都将转换为 true

以下是转换为布尔值的一些示例

1
2
3
4
5
$messsage = 'Hello World'

if ($message) { // true
echo $messsage;
}
1
2
3
4
5
if ($value) {
echo 'Variable is set';
} else {
echo 'Variable is unset';
}

HTML 文件中使用 IF 语句

1
2
3
4
5
6
7
8
9
10
11
12
13
<html lang="en">
<body>
<?php $isAdmin = true; ?>

<h1>Home page</h1>

<?php if ($isAdmin) : ?>
<p>Welcome Administrator</p>
<?php else : ?>
<p>Welcome Guest</p>
<?php endif ?>
</body>
</html>

每一段 PHP 代码都有开始和结束标签。这里的特殊性在于 ifelse 代码块。这里没有 { }。你可以用 : 代替。

Switch

如果我们有多个条件,ifelseif 等可能会导致代码难以阅读。在这种情况下,Switch 语句有助于简化你的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
switch ($color) {
case 'red':
echo 'Danger';
break;
case 'yellow':
echo 'Warning';
break;
case 'green':
echo 'Success';
break;
default:
echo 'The color is unknown';
}

第一行代表我们要评估的表达式:switch($color)

然后只需包含可能的 case

break 函数阻止继续执行

如果没有匹配的 case,则使用 case 默认值。

匹配

PHP 8.1 中的新功能,此指令允许你根据键 => 值对应关系返回表达式

1
2
3
4
5
6
$type = match($color) {
'red' => 'danger',
'yellow', 'orange' => 'warning',
'green' => 'success',
default => 'Unknown'
};

第一行表示我们要匹配的表达式:match($color)

在第二行我们注意到可以一次匹配多个表达式。

然后是键 => 值的列表。如果没有找到键 -> 值,则将执行默认键。

注意,键可以是表达式,值也可以是表达式,甚至可以是函数

1
2
3
4
5
$type = match($color) {
userID == 100 => openAdmin(),
userID < 100 && userID > 0 => openUser(),
default => openOther()
};

Switch 还是 Match ?
Match 在视觉上更简单,但 Switch 允许为每个块执行多行代码。 Match 返回一个 Switch 不返回的值。简而言之,如果可能的话,我会使用 Match,因为我发现该指令在视觉上更精致,但除此之外,我对 Switch 指令没有任何问题

三元运算符 ?:
这是 if...else 的简写语法。

这是一个 if...else 的示例

1
2
3
4
5
if ($isValid) {
echo 'user valid';
} else {
echo 'user not valid';
}

这是相同的例子,但使用了三元运算符

1
echo $isValid ? 'user valid' : 'user not valid';

如果运算符 ? 前面的表达式为真,则将使用 ? 后面的值,否则将使用 : 后面的值。

空合并运算符 ??
如果空合并运算符存在且不为 NULL,则返回其第一个操作数;否则返回其第二个操作数

1
echo $name ?? 'William';  //output 'William' if $name is null

使用空合并运算符进行赋值 ??

1
$name ??= 'William';

如果变量 $name 为空,则分配值“William”

空安全运算符

1
echo $user?->profile?->activate();

如果 ? 前面的变量之一为空,则表达式的值将为空

循环

while

允许执行代码块一定次数。次数取决于条件。只要条件为真,代码块就会运行。

1
2
3
4
5
$number = 1;
while ($number < 10) {
echo 'value : ' . $number ;
$number += 1;
}

这里代码块将被执行 9 次。

do while

本质上与 while 循环的原理相同,但在这种情况下,代码块将始终至少执行一次。仅在代码块末尾测试条件。

1
2
3
4
5
$number = 1;
do {
echo 'value : ' . $number ;
$number += 1;
} while ($number < 10);

for

用于按条件定义的次数执行代码块

1
2
3
for ($i = 0; $i < 20; $i++) {
echo "i value = " . i;
}

该参数分为三个部分,第一部分是计数器的定义 ($i = 0)。然后是执行代码块所要遵循的条件 ($i < 20),最后是每次迭代时要执行的代码 ($i++)

foreach

foreach 函数为数组的每个元素执行一个代码块。

1
2
3
4
5
$names = ['William', 'Shawn', 'John'];

foreach($names as $name) {
echo 'Hello ' . $name;
}

第一个参数是要浏览的数组的名称,第二个参数表示对当前元素的引用。

Break 和 Continue

breakcontinue 语句用于修改循环

1
2
3
4
5
6
for ($i = 0; $i < 20; $i++) {
if ($i % 2 === 0) {
continue;
}
echo $i . '<br>';
}

此循环将仅当值为奇数时打印 $i 的值。

如果值为偶数 ($i % 2 === 0)。因此我们要求循环继续执行下一个值。

可以使用 break 指令随时退出循环

1
2
3
4
5
6
7
8
9
$i = 0;

while ($i < 10000) {
$i++;
if ($i == 10) {
break;
}
echo $i . '<br>';
}

$i 的值为 10 时,循环将停止

函数

PHP 中已经预定义了几个函数。我们也可以创建自己的函数。

函数让我们避免多次重复代码。它们还让我们将应用程序划分为更易于维护的小块。

创建函数的语法非常简单

1
2
3
function hello() {
echo 'Hello World';
}

这里我们使用关键字 function,后面跟着函数的名称。

一旦创建了函数,就可以启动它的执行

1
hello();

我们的函数可以包含一个或多个参数

1
2
3
function hello($firstName, $lastName) {
echo 'Hello' . $firstName . ' ' . $lastName;
}

函数的启动必须按照声明的顺序包含参数

1
hello('William', 'Taylor');

可以为参数分配一个默认值,这样在调用函数时该参数就变成可选的了。

1
2
3
4
5
6
function hello($firstName, $lastName = 'none') {
echo 'Hello' . $firstName . ' ' . $lastName;
}

hello('William');
// William none

请注意,具有默认值的参数必须最后定义。

PHP 8 版开始,可以通过命名参数来启动函数。调用更清晰,并且不必遵守参数的顺序。

1
hello(lastName: 'Taylor', firstName: 'William');

返回

调用函数时返回一个值。

1
2
3
4
5
function fullName($firstName, $lastName) {
return $firstName . ' ' . $lastName;
}

echo fullName('John', 'Doe');

此处函数返回包含名字和姓氏的连接字符串

echo 函数将在网页上显示 fullName() 函数返回的值

匿名函数(闭包)

允许创建函数而不指定其名称。以下是示例:

1
2
3
4
5
$sum = function ($a, $b) (
return $a + $b;
);

echo $sum(10, 15);

匿名函数以分号结尾;并且它们无法访问父上下文变量。

可以使用语句 use 从父上下文传递变量

1
2
3
4
5
6
7
8
$x = 10;

$sum = function ($a, $b) use $x (
return $x + $a + $b;
);

echo $sum(10, 15);
// 35

回调函数

回调函数是作为参数传递的匿名函数。以下是示例

1
2
3
4
5
6
7
8
$products = ['iPhone 12', 'iPhone 13', 'iPad', 'iWatch'];

$filtered_products = array_filter($products, function ($product) {
return str_contains($product, 'Phone');
});

print_r($filtered_products);
// Array ( [0] => iPhone 12 [1] => iPhone 13 )

这里 array_filter() 函数有一个匿名函数作为第二个参数。

箭头函数

允许使用快捷语法:

1
2
3
4
5
$products = ['iPhone 12', 'iPhone 13', 'iPad', 'iWatch'];

$filtered_products = array_filter($products, fn ($product) => str_contains($product, 'Phone'));

print_r($filtered_products);

请注意,目前 Arrow 函数仅允许执行一个表达式。Arrow 函数在当前上下文中执行,因此它们可以使用变量而无需使用 use 语句。

函数类型提示

请注意,函数可以输入(stringint 等)。可以为每个参数定义一个类型,并为函数的返回值定义一个类型

1
2
3
function display(string $first, string $last) : string {
return "$first $last";
}

这里的 $first$last 参数必须是字符串类型,返回值也是如此。

关于类型函数,还有其他一些事情需要了解,我们稍后会回顾。

严格类型

以下是具有类型的函数的示例

1
2
3
4
5
6
7
function add(int $a, int $b): int
{
return $a + $b;
}

echo add('10', 20);
// 30

在此示例中,参数 $a 为整数类型。但是 PHP 不会返回错误。原因是 PHP 会尝试将字符串 '10' 转换为整数。如果可以转换,则不会报告任何错误。

有时你希望 PHP 不允许这种转换,并且仅在参数确实属于指定类型时才执行。为此,你必须在文件开头添加一条指令。

1
2
3
4
5
6
7
8
9
declare(strict_types=1);

function add(int $a, int $b): int
{
return $a + $b;
}

echo add('10', 20);
// TypeError

这里返回错误,因为参数的类型不是整数


相关文章: