第3章逻辑:做出决定并重复自己

第2章介绍了如何在PHP程序中表示数据的基础知识。但是,一个充满数据的程序只完成了一半。另一个难题是使用该数据来控制程序的运行方式,采取以下措施:

如果管理用户已登录,请打印特殊菜单。
如果是在三点钟之后打印另一个页眉。
如果自上次登录后发布了新消息,请通知用户。
所有这些行动都有一些东西 共同点:他们决定涉及数据的某个逻辑条件是真还是假。在第一个操作中,逻辑条件是“管理用户是否已登录?”如果条件为真(是,管理用户已登录),则会打印一个特殊菜单。在下一个例子中会发生同样的事情。如果条件“它是在3点之后吗?”是真的,则打印不同的页眉。同样,如果“自上次登录用户以来已发布新消息?”为真,则通知用户。

做决定时,PHP引擎将表达式归结为true或false。“理解真假”解释了引擎如何决定哪些表达式和值 true以及哪些是false。

这些true和false值由语言结构使用,例如if()决定是否在程序中运行某些语句。“制定决策”if()详细介绍了这些细节。任何时候程序的结果取决于一些不断变化的条件,使用 和类似的结构。if()

虽然true并且false是决策的基石,但通常您想要提出更复杂的问题,例如“此用户是否至少21岁?”或“此用户是否每月订阅该网站或者他的帐户中有足够的钱购买每日通行证?“ ”构建复杂的决策“解释了PHP的比较和逻辑运算符。 这些可以帮助您表达您在程序中需要做出的任何类型的决策,例如查看数字或字符串是否大于或小于彼此。您还可以将决策链接到一个更大的决策,这取决于它的作品。

当您想要重复执行某些语句时,决策也会在程序中使用,并且您需要一种方法来指示何时应该停止重复。通常,这是由一个简单的计数器决定的,例如“重复10次。”这就像问“我有没有重复10次?”如果是这样,那么程序就会继续。如果不是,则再次重复该动作。确定何时停止也可能更复杂 – 例如,“向学生显示另一个数学问题,直到六个问题得到正确回答。” “重复自己”介绍PHP while()和for()构造,您可以使用它来实现这些类型的循环。

理解真假

PHP程序中的每个表达式都有一个真值: true或false。有时候,真值是重要的,因为你在计算中使用它,但有时你会忽略它。了解表达式如何评估 true或是false理解PHP的重要部分。

大多数标量值都是true。所有整数和浮点数(0和0.0除外)都是true。所有字符串是 true除了两个:含有什么都没有,并只包含字符字符串的字符串 0。特殊的常量false和null也评价到 false。这六个值是false。其他一切都是 true。1

等于其中一个false值的变量或返回其中一个值的函数也会计算为false。每个其他表达式的计算结果为true。

弄清楚表达式的真值有两个步骤。首先,弄清楚表达式的实际值。然后,检查值是否为true或false。有些表达式具有常识值。数学表达式的价值就是用纸和笔做数学计算得到的。例如,7 * 6 等于42。既然42是true,表达式7 * 6是true。表达式5 – 6 + 1等于 0。既然0是 false,表达式5 – 6 + 1 是false。

字符串连接也是如此。连接两个字符串的表达式的值是新的组合字符串。表达式’jacob’ . ‘@example.com’等于字符串 jacob@example.com,即true。

赋值操作的值是指定的值。表达式的$price = 5 计算结果为 5,因为这是分配给它的内容$price。因为作业生成结果,您可以将赋值操作链接在一起,为多个变量分配相同的值:

此表达式表示“设置$price 等于设置的结果$quantity等于 5。”当计算此表达式时,整数5将分配给变量$quantity。赋值表达式的结果是5,赋值。然后,将结果(5)分配给变量 $price。双方$price并 $quantity设置为5。

做出决定

使用该if()构造,您可以在程序中包含语句 只有在某些条件下才会运行true。这使您的程序可以根据具体情况采取不同的操作。例如,您可以在让用户查看敏感数据之前检查用户是否在Web表单中输入了有效信息。

该if()结构运行一个代码块,如果它的测试表达式是true。这在 实施例3-1中说明。

例3-1。用if()做出决定

所述if()构建体发现其括号内的表达式(的真值测试表达式)。如果表达式求值为 true,则if()运行后的大括号内的语句。如果表达式不是 true,则程序继续使用大括号后的语句。在这种情况下,测试表达式只是变量$logged_in。如果 $logged_in是true(或者具有这样的值,计算结果为 true,如5,-12.6或 Grass Carp),然后Welcome aboard, trusted user.被打印。

您可以在花括号内的代码块中包含任意数量的语句。但是,您需要使用分号终止每个分号。这与适用于if()语句外部代码的规则相同 。但是,在封闭代码块的结束花括号之后,您不需要分号。你也不要在开口大括号后面加一个分号。示例3-2显示了一个if()在其测试表达式时运行多个语句的子句是true。

例3-2。if()代码块中的多个语句

要在if()测试表达式中运行不同的语句,请在语句中false添加一个else子句if()。 这显示在 例3-3中。

例3-3。在if()中使用else

在例3-3中,第一个print 语句仅在if()测试表达式(变量$logged_in) 为时执行true。子句中的第二个print 语句else仅在测试表达式时运行false。

这些if()和else构造进一步扩展与elseif()构造。您可以将一个或多个elseif()子句与a 配对,if()以分别测试多个条件。例3-4说明 elseif()。

例3-4。使用elseif()

如果if()语句的测试表达式是 true,则PHP引擎执行代码块内的语句,if()并忽略elseif()子句及其代码块。如果if()语句的测试表达式是 false,则引擎转到第一个 elseif()语句并应用相同的逻辑。如果该测试表达式是true,则它运行该elseif()语句的代码块。如果是 false,则引擎继续前进到下一个 elseif()。

对于给定的一组if()和elseif()语句,最多运行一个代码块:第一个语句的代码块,其测试表达式为 true。如果if()语句的测试表达式是true,则不elseif()运行任何 代码块,即使它们的测试表达式是true。一旦其中一个if()或elseif()测试表达式出现 true,其余部分将被忽略。如果if()和elseif()语句中没有任何测试表达式true,则不运行任何代码块。

你可以用else与elseif() 包括一个运行的代码块如果没有if()或elseif()测试表达式 true。例3-5else在例3-4中添加了一个 代码。

例3-5。elseif()with else

到目前为止我们使用的所有代码块都被花括号括起来。严格地说,您不需要在仅包含一个语句的代码块周围放置花括号。如果将它们遗漏,代码仍然可以正确执行。但是,如果省略花括号,阅读代码可能会令人困惑,因此包含它们总是一个好主意。PHP引擎并不关心,但阅读您的程序的人(特别是您,在您最初编写代码几个月后查看代码)将会欣赏花括号提供的清晰度。

建立复杂的决策
比较 PHP中的逻辑运算符可以帮助您将if()构造可以决定的更复杂的表达式组合在一起。 这些运算符允许您比较值,否定值以及将多个值链接在一起一个if()语句中的表达式。

等于运算符是==(两个等号)。 true如果您使用它测试的两个值相等,则返回 。值可以是变量或文字。例3-6中显示了相等运算符的一些用法。

例3-6。平等的运营商

作业与比较
=你的意思是小心不要使用==。单个等号分配一个值并返回指定的值。true如果值相等,则两个等于符号测试相等并返回。如果你不用第二个等号,你通常会得到一个if()测试,true如下所示:

这里显示的代码设置 为而不是测试是否$new_messages等于 。此赋值返回,分配的值。该测试表达式始终 ,无论什么价值 的。此外,值 被覆盖。避免使用的一种方式,而不是就是把变量比较的右侧和左侧的文字,如下所示:12$new_messages1212if()true$new_messages$new_messages===

上面的测试表达可能看起来有点滑稽,但如果你不小心使用它=而不是给你一些保险==。使用一个等号,测试表达式是12 = $new_messages,这意味着“赋值$new_messages为12。”这没有任何意义:你不能改变它的值12。如果PHP引擎在您的程序中看到这一点,它会报告解析错误并且程序不会运行。解析错误会提醒您丢失=。使用表达式右侧的文字,代码可由引擎解析,因此它不会报告错误。

相等运算符的反面是 !=。它返回true如果你用它测试两个值不相等。参见例3-7。

例3-7。不等于运营商

使用小于运算符(<)和大于运算符(>),您可以比较金额。 类似于 <并且>是 <=(“小于或等于”)和>= (“大于或等于”)。 例3-8显示了如何使用这些运算符。

例3-8。小于和大于(或等于)

正如“数字”中提到的,浮点数内部存储的方式可能与指定的值略有不同。例如,50.0可以在内部存储为50.00000002。要测试两个浮点数是否相等,请检查两个数字是否相差小于某个可接受的小阈值,而不是使用等于运算符。例如,如果您要比较货币金额,则可接受的阈值可能是0.00001。例3-9演示了如何比较两个浮点数。

例3-9。比较浮点数

例3-9中abs()使用的函数返回其参数的绝对值。使用时abs(),无论$price_1是大于$price_2还是 $price_2大于 ,比较都能正常工作$price_1。

小于号和大于号的运算符(及其“或等于”伙伴)可以与数字或字符串一起使用。通常,将字符串进行比较,就像在字典中查找字符串一样。字典中较早出现的字符串是“小于”字典中稍后出现的字符串。实例3-10中显示了一些这样的例子。

例3-10。比较字符串

但是,如果字符串仅包含数字或以数字开头,则字符串比较会产生意外结果。 当PHP引擎看到这样的字符串时,它会将它们转换为数字以进行比较。例3-11显示了这种自动转换的实际操作。

例3-11。比较数字和字符串

例3-11中的四个测试的输出是:

在第一个测试中,因为两个字符串都以字母开头,所以它们被视为常规字符串并使用字典顺序进行比较。它们的前两个字符(x5)是相同的,但第一个单词(4)的第三个字符小于第二个单词(6)的第三个字符,2因此大于比较返回 false。在第二个测试中,每个字符串完全由数字组成,因此字符串将作为数字进行比较。数字54,321大于数字5,678,因此大于比较返回true。在第三个测试中,因为两个字符串都由数字和其他字符组成,所以它们被视为字符串并使用字典顺序进行比较。数字6在引擎字典中的5之后,因此小于测试返回false。在上一次测试中,PHP引擎将字符串6 pack转换为数字6,然后55使用数字顺序将其与数字进行比较。由于 6小于55,小于测试返回true。

如果要确保PHP引擎使用字典顺序比较字符串而不在后台转换为数字,请使用 内置功能strcmp()。它总是按字典顺序比较它的参数。

该strcmp()函数接受两个字符串作为参数。如果第一个字符串大于第二个字符串,则返回正数;如果第一个字符串小于第一个字符串,则返回负数。“大于”和“小于”for strcmp()由字典顺序定义。0如果字符串相等,则返回该函数。

同样的比较 从实施例3-11是使用示出strcmp()在实施例3-12。

例3-12。用strcmp()比较字符串

例3-12的输出如下:

对于第二次和第四次比较,使用strcmp()和字典顺序产生与示例3-11不同的结果。在第二个比较中,strcmp()计算字符串54321小于5678因为字符串的第二个字符不同而且4之前 6。这不要紧, strcmp()这5678是比较短的54321,或者是数值越小。在字典顺序中,54321来之前 5678。第四个比较结果不同,因为strcmp()没有转换 6 pack为数字。相反,它比较 6 pack和55作为字符串和计算6 pack更大,因为它的第一个字符,6,后来在字典中比第一个字符55。

宇宙飞船运营商(<=>)做的比较类似strcmp(),但对于任何数据类型。 当左手操作数小于右手操作数时,它评估为负数;当右手操作数大于右手数时,它评估为正数,0当它们相等时,它评估为负数。例3-13显示了飞船运营商的工作情况。

例3-13。将数据类型与宇宙飞船运营商进行比较

警告
太空飞船运营商是在PHP 7中引入的。如果您使用的是旧版本的PHP,请坚持使用其他比较运算符。

例3-13打印:

宇宙飞船运营商遵循与其他比较运算符相同的字符串和数字转换规则。它把“数值”字符串的数字就像==,<和其他人。

否定一个 真值,用法!。放在!表达之前就像测试看表达式是否等于 false。例3-14中的两个if()语句是等效的。

例3-14。使用否定运算符

您可以将否定运算符与任何值一起使用。如果值是 true,那么它与否定运算符的组合是false。如果值是 false,那么它与否定运算符的组合是true。例3-15显示了否定操作员在工作时打电话给strcasecmp()。

例3-15。否定运算符

在例3-15中,if()代码块中的语句仅在整个测试表达式执行时执行 true。当提供的两个字符串 strcasecmp()相等(忽略大写)时, strcasecmp()返回0,即 false。测试表达式是应用于此false值的否定运算符。否定false是true。因此,整个测试表达式是true在给出两个相等的字符串时strcasecmp()。

使用逻辑运算符,您可以在一个if() 语句中组合多个表达式。逻辑AND运算符(&&)测试一个表达式和另一个表达式是否都是true。逻辑OR运算符(||)测试是否一个表达式或另一个表达式(或两者)是true。这些逻辑运算符用于例3-16。

例3-16。逻辑运算符

实施例3-16中的第一个测试表达式是 true当它们的两个子表达式都是 true- $age至少13但不超过时65。第二测试表达是 true当它的子表达式中的至少一个是 true:当$meal是 breakfast或$dessert为 souffle。

关于运算符优先级的警告 第2章中的括号和测试表达式中的逻辑运算符也适用。 为避免歧义,请在较大的测试表达式中用括号括起每个子表达式。

重复自己

当一个计算机程序 反复的东西,它被称为循环。这种情况发生了很多 – 例如,当您想要从数据库中检索一组行,打印HTML表的行或在HTML <select>菜单中打印元素时。本节中讨论的两个循环结构是while()和for()。它们的细节有所不同,但每个都要求您指定任何循环的两个基本属性:重复执行的代码和何时停止。要执行的代码是一个代码块,就像if()构造后的花括号内部一样 。停止循环的条件是逻辑表达式,就像if() 构造的测试表达式一样。

该while() 构建体是像的重复if()。你提供一个表达式while(),就像 if()。如果表达式是true,则执行代码块。if()但是, 与while()执行代码块后再次检查表达式不同。如果它仍然存在 true,则再次执行代码块(并且再次执行,只要表达式为 true。)表达式完成后 false,程序继续执行代码块之后的行。正如您可能已经猜到的那样,您的代码块应该执行一些更改测试表达式结果的操作,以便循环不会永远持续下去。

例3-17用于while()打印HTML表格 <select>菜单有10种选择。

例3-17。使用while()打印<select>菜单

例3-17打印:

在之前while()循环运行,代码集 $i,以1和打印开放 <select>标记。测试表达式相比较 $i来10。只要 $i小于或等于10,就执行代码块中的两个语句。第一个打印菜单的 <option>标签 <select>,第二个增量 $i。如果你没有$i在while()循环内增加 , 例3-17将<option>1</option>永远打印出来 。

代码块打印后 <option>10</option>,该 $i++行$i等于11。然后$i <= 10评估测试表达式()。由于它不是true (11不小于或等于10),程序继续经过 while()循环的代码块并打印结束</select>标记。

该for() 结构还提供了一种多次执行相同语句的方法。例3-18用于for()打印与例3-17相同的HTML表单<select>菜单。

例3-18。使用for()打印<select>菜单

使用for() 比使用复杂一点 while()。除了括号中的一个测试表达式,有三个用分号分隔的表达式:初始化表达式,测试表达式和迭代表达式。然而,一旦掌握了它,for()就会有一种更简洁的方法来获得一个易于表达初始化和迭代条件的循环。

第一表达在实施例3-18,$i = 1是在初始化表达式。它被评估一次,当循环开始时。这是您放置变量初始化或其他设置代码的地方。第二个表达式在实施例3-18,$i <= 10是测试表达式。在循环体中的语句之前,每次循环评估一次。如果是true,则执行循环体(print “<option>$i</option>”; 在例3-18中)。第三个表达式在实施例3-18,$i++是在迭代 表达。它在每次循环体执行后运行。在例3-18中,语句的顺序如下:

 

  1. 初始化表达式: $i = 1;
  2. 测试表达式:$i <= 10true$i是 1
  3. 代码块: print "<option>$i</option>";
  4. 迭代表达式: $i++;
  5. 测试表达式:$i <= 10true$i是 2
  6. 代码块: print "<option>$i</option>";
  7. 迭代表达式: $i++;
  8. (循环继续增加值$i
  9. 测试表达式:$i <= 10true$i是 9
  10. 代码块: print "<option>$i</option>";
  11. 迭代表达式: $i++;
  12. 测试表达式:$i <= 10true$i是 10
  13. 代码块: print "<option>$i</option>";
  14. 迭代表达式: $i++;
  15. 测试表达式:$i <= 10false$i是 11 

您可以for()通过用逗号分隔每个单独的表达式,在初始化表达式和循环的迭代表达式中组合多个表达式。当您想要在循环进行时更改多个变量时,通常会执行此操作。例3-19将此应用于变量$min和$max。

例3-19。for()中的多个表达式

每次循环,$min并且 $max每次都递增10. 示例3-19 打印:

章节总结

  • 评估表达式的真值: truefalse
  • 做出决定 if()
  • 延伸if()else
  • 延伸if()elseif()
  • 把多个语句内的if(), elseif()else代码块
  • 在测试表达式中使用equal(==)和not-equal(!=)运算符
  • 区分赋值(=)和相等比较(==
  • 在测试表达式中使用less-than <,大于(>),小于或等于(<=)和大于或等于(>=)运算符
  • 比较两个浮点数 abs()
  • 比较两个字符串与运算符
  • strcmp()或 比较两个字符串strcasecmp()
  • 将两个值与太空飞船运营商进行比较(<=>
  • !在测试表达式中使用否定运算符()
  • 使用逻辑运算符(&&和 ||)来构建更复杂的测试表达式
  • 用。重复代码块 while()
  • 用。重复代码块 for()

演习

1. 如果不使用PHP程序,以评估它们,确定每一个这些表情是否是true或false:

  1. 100.00 - 100
  2. "zero"
  3. "false"
  4. 0 + "true"
  5. 0.000
  6. "0.0"
  7. strcmp("false","False")
  8. 0 <=> "0"

2. 不通过PHP引擎运行它,找出这个程序打印的内容:

3. 用于while()以-50华氏度到50华氏度,以5度为单位打印华氏温度和摄氏温度当量表。在华氏温标上,水在32度冻结,沸腾在212度。在摄氏温度下,水在0度时冻结,在100度时沸腾。因此,要从华氏温度转换为摄氏温度,您将从温度中减去32,乘以5,然后除以9.要从摄氏温度转换为华氏温度,您乘以9,除以5,然后再加上32。

4. 将练习3的答案修改为使用for() 而不是while()。
1 也是一个空数组 false。这将在第4章中讨论。

2 PHP引擎用于比较字符串的“字典”是字符的ASCII代码。这将数字放在字母之前,并将数字从0到9排序。它还将大写字母放在小写字母之前。

如果有不懂的地方请留言,SKY8G网站编辑者专注于研究IT源代码研究与开发。希望你下次光临,你的认可和留言是对我们最大的支持,谢谢!

上一篇: 如何在Magento 2中创建自定义控制器Controller

下一篇: 第4章数据组:使用数组

登录 评论
avatar