仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3285|回复: 20
打印 上一主题 下一主题

[学习教程] PHP网页编程之《PHP法式设计》 第四章 法式掌握

[复制链接]
再见西城 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-2-16 00:25:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
把例子全部敲进去试验,完成一遍以后就会有心得了,因为你会发现为啥我的程序和书上的一模一样就是结果不正确。新手学习的时候必须承认,不容易,因为我也是过来人,你会发现原来有那么多常用的语句,函数都要记。   

第四章 法式掌握
   
  本章深切PHP外部,讲述若何利用函数、表达式和语句以完成对法式的掌握。
   
  后面的章节初步引见了如何操作数据,假如咱们将操作数和操作符看做是修建元件的话,那末它们组合起来便可构成表达式。进一步讲,表达式可以组成语句,语句用于构成函数,而函数则可用来构成法式。
   
  提醒:在进修有关编程言语的根基元素时,从全局了解--即了解这些元素是若何构成一个完全法式的--能够十分坚苦。但也不用焦急,悲观一点。接上去的章节将慢慢的显示全部法式,而且一点一点的注释它们是若何机关的。
   
  4.1 表达式
  当操作数和操作符组合到一同时,它们即构成表达式。本书的例子中已展现了很多表达式,但是直到如今,咱们才入手下手将注重力集中在它们身上。
   
  表达式是由一个或多个操作符毗连起来的操作数,用来盘算出一个值--标量或数组。
   
  最根基的表达式就是数字:
   
  12
   
  从这个粗陋的入手下手,将慢慢会商愈来愈庞杂的表达式:
   
  -12
  -12 + 14
  -12 + 14 * (24 / 12)
  (-12 + 14 * (24 / 12))&& calculate_total_cost()
   
  注重每一个表达式,在不思索庞杂性的情形下,每个表达式现实上是由较小的表达式和一个或多个操作数配合构成的。当盘算机编程者利用要界说的概念为该概念下界说时,这称为递归。当一个递归完成时,表达式能被分红较更复杂的局部,直到盘算性能完整的履行每局部。
   
  4.1.1 复杂表达式
  复杂表达式是由一个单一的赋值符或一个单一函数挪用构成的。因为这些表达式很复杂,所以也没需要过量会商。上面是一些例子:
  * initialize_pricing_rules() -- 挪用函数。
  * $str_first_name = 'John' -- 初始化标量。
  * $arr_first_names = array( 'John', 'Marie') -- 初始化数组。
   
  4.1.2有反作用的复杂表达式
  表达式在它的次要义务以外,还有其它的反作用。当一个或几个变量改动了它们的值,而且这些改动并非赋值操作符的操作了局时,就会呈现这类反作用。例如,一个函数挪用可以设置全局变量(全局变量是指在函数外部用global关头字来指定的变量),或加一操作符也能够改动变量的值。反作用会使得法式很难读懂,因而编程的一个方针就是应当尽量地削减这类反作用。
   
  不利用global关头字是防止反作用的一个好选择。
   
  让咱们看看以下有反作用的表达式例子:
  * $int_total_glasses = ++$int_number_of_glasses
  -- $int_number_glasses变量在加一今后,再把值付与$int_total_glasses。
  * function one() {global $str_direction_name; $str_directory_name = '/dos_data'; }
  -- 当one()函数挪用后,全局变量的值将被改动。
   
  4.1.3 庞杂表达式
  庞杂表达式可以以任何按次利用恣意数目的数值、变量、操作符和函数。
   
  尽量利用冗长的表达式,这意味着它们更轻易保护。
   
  以下是一些例子:
  * ((10+2) /count_fishes() * 114)
  -- 包括有三个操作符和一个函数挪用的庞杂表达式。
  * initialize_count( 20 -($int_page_number -1) * 2)
  -- 有一个庞杂表达式参数的复杂函数挪用。
   
  提醒:有时很难分清左括号和右括号的数量是不是不异。从左到右,当左括号呈现时,就加一,当右括号呈现时,就从总数中减一。假如在表达式的开头时,总数为零时,左圆括号和右圆括号的数量就必定不异了。
   
  4.2 语句
  一切的PHP法式都是由语句组成的,不管是复杂的语句,仍是庞杂的语句,这些语句按按次履行每时辰履行一句,直到碰到法式停止、跳转语句、分支语句。
  最根基的语句是:
   
  ;
   
  此语句甚么也没有做,但它还是正当的。分号符是语句停止的标记。假如需求,语句也能够相当庞杂。例如:
   
  $str_house_size =(
  $int_number_of_rooms > 9 ?
  "large" :
  "small"
  );
   
  这行代码在房子的数量大于9时,给$str_house_size付与"large",不然给$str_house_size付与"small"。
  就象人类言语中的语句一样,PHP语句可以分为几个构成局部。在PHP中,构成局部可所以数值、变量、函数和关头字。关头字是PHP留作本人用的单词。这些关头字(_FILE_, _LINE_, if, else, elseif, while, do, for, break, continue, switch, case, default, require, include, function),是构成PHP言语必不成少的,利用它们可以掌握法式的流程。
  本书将不合错误关头字_FILE_和_LINE_作引见,相干内容请参考PHP文档。关头字require和include用来读取和履行PHP剧本, 在PHP手册中有具体引见。以下局部将重点讲述其他的关头字。
   
  4.2.1 语句类型
  PHP共有6品种型语句,如表4.1所示。
   
  表4.1 PHP数据类型
  语句类型
  描写
  非履行语句
  需求盘算但不履行举措。
  履行语句
  履行某一举措。
  赋值语句
  给变量赋值。
  判别语句
  判别前提,并决意履行哪个举措。
  轮回语句
  反复履行一系列语句直到某前提为真或直到某前提为假为止。
  跳转语句
  无前提改动法式流程到法式中另外一行持续履行。
   
  非履行语句:
  所谓非履行语句,就是PHP需求盘算,但其实不需求履行甚么举措的语句。例如:语句10 + 20,其值是30,但因为没有改动哪一个变量值,所以也不需求作甚么举措。了局值将不保存,当下一条语句呈现时,它很快就被抛弃了。
  甚么举措也不需求做,那末非履行语句又有甚么用呢?我不清晰,假如你能发明它们的用处请告知我。
  履行语句:
  履行语句是经由过程表达式来履行某些举措。它们可以增添或减小某一变量值,或挪用一个函数。履行语句是PHP中利用最多的一种语句类型。
  赋值语句:
  赋值语句其实不庞杂,它们可以给一个变量付与一个数值。关于赋值操作符在前一章“PHP中的数据处置”中已讲过,在此不再过量赘述。
  判别语句:
  判别语句利用if 和switch关头字,基于一个表达式的盘算了局以决意履行某一段语句,或基于表达式的了局在两段语句行当选择履行个中的一个。例如,假如要处置的支票值大于1000美圆,则履行一段法式;假如支票数小于1000美圆,就履行另外一段法式。
  if关头字
  在if语句中经由过程盘算表达式,得出真或假值,依据所求出的真、假值来决意履行哪一段法式。
  最多见的有以下三品种型的if语句:
  1.
  if ( EXPRESSION ) {
  // code block to be executed when
  // expression is true.
  }
  2.
  if ( EXPRESSION ) {
  // code block to be executed when
  // expression is true.
  }
  else {
  // code block to be executed when
  // expression is false.
  }
  3.
  if ( EXPRESSION_1 ) {
  // code block to be executed when
  // expression_1 is true.
  }
  elseif ( EXPRESSION_2 ) {
  // code block to be executed when
  // expression_2 is true.
  }
  else {
  // code blcok to be executed when
  // all expression are false.
  }
   
  表达式可以包括第三章“PHP中的数据处置”中的任一个操作符,乃至可所以赋值操作符,这是由于赋值操作符要赋的值,能够就是需求判别的值。以上最初一个例子能够有点难以了解,如今让咱们再看一个例子:
   
  $int_a = 10;
  if ($int_a -= 5)
  echo "a = $int_a<br>";
   
  这些代码将显示
   
  a = 5
   
  该if语句对表达式$int_a -= 5的处置是,$int_a的值先减5,了局值再赋给$int_a。假如了局值为真(即不为零),则履行echo语句。
  在这个例子中,除申明了在只要一个需求履行的语句时,语句段内部的大括号是可选的外,还申明了赋值操作符是可以在if语句中利用的。
   
  提醒:即便唯一单个语句时可以不利用大括号,凡是仍是要利用大括号。如许在今后增添语句时就加倍便利。同时也削减了在今后增添语句时忘了添加大括号(如许能够引发纤细的逻辑毛病)的能够性。
   
  上面的代码将申明else关头字是若何利用的:
   
  $int_a = 5;
  if ($int_a -= 5) {
  echo "a = $int_a<br>";
  }
  else {
  echo "a is zero.<br>";
  }
   
  这些代码将显示
   
  a is zero.
   
  elseif关头字依照以下的办法利用:
   
  $str_name = 'John';
  if ($str_name == 'Joe') {
  echo "Your appointment is on Monday.<br>";
  }
  elseif ($str_name == 'John') {
  echo "Your appointment is on Wednesday.<br>";
  }
  else {
  echo "Your appointment is on Firday.<br>";
  }
   
  这些代码将显示:
   
  Your appointment is on Wednesday.
   
  当变量$str_name即不是'Joe',又不是'John'时,将履行if语句的else子语句,不然,将履行其它两个子语句中的一个。经由过程把毛病信息放在else语句块中,以便显示未知的值,else关头字关于捕捉未知或未预期的值也十分有效。例如:
   
  if ($str_input == 'A') {
  // do A statements.
  }
  elseif ($str_input == '8') {
  // do B statements.
  }
  else {
  echo "Unrecognized Input Error: '$str_input' is unknown.<br>";
  }
   
  在迄今为止所举的例子中,一切if语句的子句中利用的都是统一个的变量。不外,正以下例给出的一个虚拟的有关房子和智能型盘算机的例子那样,可以充实发扬发明力:
   
  if ($int_left_window_open == 1) {
  $int_outside_temperature = check_outside_temperature();
  if ($int_outside_temperature < 70) {
  close_window('left');
  }
  }
  elseif ($int_right_window_open == 1) {
  $bln_mail_exists = look_outside_check_mailbox();
  if ($bln_mail_exists) {
  make_announcement("The mail is here.');
  }
  }
  else {
  $str_window_side = select_side_of_house();
  open_window($str_window_side);
  }
   
  switch关头字
  假如需求同时测试、判别多个前提值时,if语句处置起来就显得对照烦琐--由于一切的elseif语句都要履行过一遍。在这类情形下很多人会发明,利用switch语句会更轻易、疾速。
  switch语句句法布局以下
   
  switch ( VARIABLE ) {
  case VALUE1:
  break;
  case VALUE2:
  break;
  case VALUEn:
  break;
  default:
  break;
  }
   
  在switch语句中,每个需求反省的值都对应一个响应的case 语句。被反省的变量可所以恣意标量值,(也就是说,数字和字符串都可以被反省)。
  假如case语句中没有break关头字,那末PHP将履行下一个case语句;假如这个case语句中仍没有break语句,那末就接着履行再下一个case语句,如斯下去直至找到break关头字为止。
  上面给出一个冗长但很完全的例子,讲的是用switch语句来处置号令的号令行法式。每当用户输出一条号令,就会挪用switch语句,以决意该履行甚么义务。固然,PHP经常使用于创立Web阅读器法式,能够历来不会如许利用PHP。
   
  switch ($str_input) {
  // The print and echo case perform the same task,so
  // the print case needs no break keyword.
  case 'print':
  case 'echo':
  // do the echo task.
  break;
  case 'check_balance':
  // do the check balance task.
  break;
  case 1:
  case 2:
  // add $str_input to something.
  break;
  default:
  echo "You have entered an unrecognized command or are ";
  echo "trying to add a number other than 1 or 2.";
  break;
  }
   
  利用分支语句的限制是,只能对一个变量停止判别。从另外一角度看,这类限制恰好就是switch语句比if语句轻易让人了解的缘由。
   
  轮回语句:
  轮回语句就是依据法式需求,反复履行一段法式直到一个指定的表达式值为真或假为止。
  PHP中有三个掌握法式轮回的关头字,分离是for,while和do,且这三个关头字处置的轮回语句又有纤细的不同。然而,不管哪一种请况,表达式值都是用来决意轮回语句什么时候应当中断的。利用关头字for的轮回语句最为庞杂,让咱们起首来看它。
  for关头字:
  从句法布局讲,for语句是由三个表达式和一段语句构成的。模式以下:
   
  for (INITIALIZATION; CONDITION; OPERATION) {
  // statement block
  }
   
  在轮回语句入手下手之前,起首需求对表达式停止初始化。此时的初始化合用于恣意变量,但大多半编程者只对轮回语句段中要用到的变量停止初始化。初始化任务可以在for语句之行进行,之所以在for语句外部履行对表达式的初始化任务,是为了有助于生成一自我完整的法式。
   
  提醒:初始化表达式凡是是赋值表达式。注重在初始化赋值时,不要将等于操作符(==)和赋值操作符(=)弄搅浑了。不然,这将会在法式中留下隐患。例如:$iindex == 0就是毛病的,准确的表达式应当是$iindex = 0。
   
  前提表达式用于掌握轮回局部是持续履行,仍是中断轮回。当前提表达式值判别为假时(就是说为零),则轮回终止。
   
  轮回变量是前提表达式中利用的变量,用于掌握轮回甚么时分停止。
   
  运算表达式用于在每次履行完轮回外部的代码段今后,以某种体例修正在前提表达式中利用的变量(即轮回变量)值。
  for语句的最根基利用办法就是从零入手下手盘算,直到某一值为止。例如:
   
  for ($loop_variable = 0;
  $loop_variable < 100;
  $loop_variable++) {
  echo "Inside Loop: loop_variable = $loop_variable<br>";
  }
   
  该语句显示了从0到99的数字:
   
  Inside Loop: loop_variable = 0
  Inside Loop: loop_variable = 1
  ...
  Inside Loop: loop_variable = 98
  Inside Loop: loop_variable = 99
   
  当轮回语句停止时,变量$loop_variable值为100,但这个值不再显示出来,这是由于打印完99今后,又对表达式停止加一运算,失掉的变量值为100。这时候,判别前提表达式值为假,轮回停止。
   
  注重:很关头的一点是,运算表达式(或语句段中的代码)必需要改动轮回变量的值,或利用本章稍后讲到的break关头字。不然,轮回语句将永久不会停止而成为一逝世轮回。
   
  for轮回语句也能够经由过程对表达式停止递加运算来减小轮回变量值:
   
  for ($loop_variable = 100;
  $loop_variable < 0;
  $loop_variable --) {
  echo "Inside Loop: loop_variable = $loop_variable<br>";
  }
   
  该语句履行后会输入从100到1的数字:
   
  Inside Loop: loop_variable = 100
  Inside Loop: loop_variable = 99
  ...
  Inside Loop: loop_variable = 2
  Inside Loop: loop_variable = 1
   
  在初始化表达式中能经由过程逗号离隔的办法对多个变量停止初始化赋值,下例给出了若何对多个变量初始化,和怎样在一个轮回语句中再包括另外一个轮回语句
   
  for ($row = 0;$row <=2; $row++) {
  for ($col_value = 0, $col = 0; $col <= 2; $col++) {
  $col_value += $row + $col;
  echo "[$row,$col] = $col_value<br>";
  }
  }
   
  显示输入为:
   
  [0,0] = 0
  [0,1] = 1
  [0,2] = 3
  [1,0] = 0
  ...
  [2,1] = 5
  [2,2] = 9
   
  每次启动外部轮回时,$col_calue就会从头初始化为零。
  迄今为止,咱们只讲了轮回变量递减一或递加一的情形。但是,运算表达式是非常天真的,可以按需求以任何体例改动轮回变量值,也能够经由过程用逗号离隔的举措同时停止多个操作。例如:
   
  $int_number_of_items = 10;
   
  // The following for loop places each
  // expression in the loop header on a separate
  // line to enhance readability.
  For ($first_time = 1,$index =1;
  $index <= $int_number_of_items;
  $index += 2, $first_time = 0
  ) {
   
  if ($first_time) {
  echo "Report Header<br><br>";
  }
   
  each "Report Line $index<br>";
   
  }
  if (! $first_time) {
  echo "<br>Report Footer<br>";
  }
   
  代码行输入显示以下:
   
  Report Line 1
  Report Line 3
  Report Line 4
  Report Line 5
  Report Line 9
   
  Report Footer
   
  注重,每反复一次轮回今后,轮回变量($index)会递增2。别的,变量$first_time掌握呈报的页眉和页脚的输入。
  假如改动变量$int_number_of_items的初始值为零的话,那末甚么也不会显示出来。第一次对前提表达式值停止判别时,变量$index值为1,变量$int_number_of_item值为0,所以不会进入语句段,也不履行运算表达式。这招致变量$first_time值还是1,在轮回停止时,也不会输入呈报的页脚。
   
  while关头字:
  当前提为真时,while轮回反复一段语句块。假如前提在履行while语句时不为真,语句块就不会被履行。
  while轮回的语法以下
  1.
  while ( CONDITION ) {
  // statement block.
  }
  2.
  while ( CONDITION ) :
  // statement block.
  Endwhile;
   
  以下例子显示了利用while语句是若何复杂:
   
  $iindex = 0;
  while ( $iindex < 5 ) :
  echo "inside while statement: $iindex<br>";
  $iindex++;
  endwhile;
  echo "outside while statement: $iindex<br>";
   
  此例子了局将显示
   
  inside while statement: 0
  inside while statement: 1
  inside while statement: 2
  inside while statement: 3
  inside while statement: 4
  outside while statement: 5
   
  注重当while语句完成今后,$iindex的值为5 -- 而不是前提表达式($iindex < 5)中所但愿的4。当$iindex为4时,前提表达式为真,将履行语句块,然后$iindex值付与5,这时候前提语句再次履行,而表达式为假,语句停止。
  假如$iindex有大于5的值时(随意说一个数,8),当运转到while语句时,以上的例子将显示
   
  outside while statement: 8
   
  do关头字:
  当表达式为假时,do轮回履行语句块。此语句的测试前提正好和while轮回相反,while轮回测试表达式是不是为真,而且前提表达式是在语句块履行后测试,而不是在语句块前测试,这也是do轮回和while轮回的分歧点,这意味着语句块最少履行一次。
  do轮回的语法以下
   
  do {
  // statement block
  } ( CONDITION );
   
  几近一切的轮回都可以用while语句或do语句来暗示。喜好如何表达法式的逻辑布局,感觉哪一种办法利用起来更随手,都可有可无。有时,利用do print_the_page while the number of pages is less than 20如许表述比while the number of page is less than 20的表述更容易于了解。
  以下do语句是本章较早利用while表述例子的另外一个版本。
   
  $iindex = 0;
  do {
  echo "Inside Do Statement: $iindex<br>";
  $iindex++;
  } while ($iindex < 5);
  echo "Outside Do Statement: $iindex<br>";
   
  此例子的了局将显示
   
  Inside Do Statement: 0
  Inside Do Statement: 1
  Inside Do Statement: 2
  Inside Do Statement: 3
  Inside Do Statement: 4
  Outside Do Statement: 5
   
  象while轮回一样,$iindex变量的停止值也为5。但是和while轮回纷歧样,假如$iindex的启始值为8时语句块最少会履行一次。当$iindex的初始值为8时,将显示以下行:
   
  Inside Do Statement: 8
  Outside Do Statement: 9
   
  跳转语句:
  PHP供应了两个语句以匡助掌握轮回的行动:break和continue。
  break关头字:
  break关头字使PHP中断履行以后的语句块,从紧随着以后语句块的语句入手下手运转。上面的例子显示了若何在一个复杂的for轮回中利用break语句。
   
  清单4.1 break.php3--利用break语句从轮回中加入
  <?php
  for ($index = 0; $index < 10; $index++) {
  // A. When $index is three, the loop ends.
  if ($index == 3) {
  break;
  }
  echo "$index<br>";
  }
  // B. After the break,execution starts here.
  echo "After the loop: index=$index<br>";
  ?>
   
  此剧本了局将显示:
   
  0
  1
  2
  After the loop: index=3
   
  break语句的另外一个方面是使人厌恶的,在轮回语句停止今后(在下面代码的B地位),将没有举措分辩轮回语句停止是因为break语句停止的,仍是以天然体例停止的。最少,在没有测试$index的值前是没有举措的,这个值依附于激发break语句而使轮回停止的前提。关于分歧的轮回测试$index变量城市有所分歧。因而在没有正文的情形下,轮回后测试$index变量长短常使人隐晦的。
  为懂得决这个成绩,可使用一个变量作为标记。假如变量值为1时(意味着赞同),那末履行break语句;不然,轮回是正常终止的。下一个例子,清单4.2显示了若何利用标记变量。
   
  清单4.2 flag.php3--在break语句中利用标记变量
  <?php
  $flg_break_happened = 0;
  for ($index = 0; $index < 10; $index++) {
  if ($index == 3) {
  $flg_break_happened =1;
  break;
  }
  echo "$index<br>";
  }
  if ($flg_break_happened) {
  echo "Loop ended because of break.<br>";
  }
  else {
  echo "Loop ended naturally.<br>";
  }
  ?>
   
  此剧本了局将显示:
   
  0
  1
  2
  Loop ended naturally.
   
  咱们还需求进一步探究break语句的其它方面,就是若何从嵌套的轮回中加入。清单4.3显示了若何利用这类手艺。
   
  清单4.3 nested_break.php3--从嵌套的轮回中加入
  <?php
  for ($row = 0; $row < 10; $row++) {
  for ($col = 0; $col < 10; $col++) {
  if ($col == 5) {
  break 2;
  }
  echo "[$row,$col]<br>";
  }
  }
  ?>
   
  此剧本了局将显示:
   
  [0,0]
  [0,1]
  [0,2]
  [0,3]
  [0,4]
   
  正如所看到的,给break语句增添的表达式是告知PHP需求加入几重嵌套。
   
  continue关头字:
  continue关头字中断轮回确当前反复,并当即入手下手下一个反复。在for轮回的情形下,下一个反复在操作表达式处入手下手。清单4.4显示了运转中的continue关头字。
   
  清单4.4 continue.php3--利用continue关头字
  <?php
  for ($index = 0;$index < 5;$index++) {
  if ($index == 3) {
  continue;
  }
  echo "$index<br>";
  }
  ?>
   
  此剧本了局将显示:
   
  0
  1
  2
  4
   
  请注重3没有显示出来。在语句块外部的if语句使得该语句块中断运转,而且在for轮回的操作子句处从头入手下手。如许,在轮回的第三次反复时,将疏忽echo语句。
  当利用嵌套的轮回时,可以在continue语句中利用表达式,如清单4.5所示。
   
  清单4.5 nested_continue.php3-在嵌套轮回中利用continue语句
  <?php
  for ($row = 0; $row < 3; $row++) {
  for ($col = 0; $col < 3; $col++) {
  if ($col == 2) {
  continue 2;
  }
  echo "[$row,$col]<br>";
  }
  echo "<br>";
  }
  ?>
   
  此剧本了局将显示:
   
  [0,0]
  [0,1]
  [1,0]
  [1,1]
  [2,0]
  [2,1]
   
  请注重外部轮回老是在2停止,echo "<br>";语句也从没有履行(因为没有输入空行)。因而,conutinue 2语句必定是中断了外部轮回,而且从内部for轮回的操作子句$row++从头入手下手。
  假如切实其实需求在外部for轮回完成今后显示空行,该怎样办呢?清单4.5显示了仅仅复杂的把echo语句放到for外部轮回的开头是不敷的,这是由于continue语句会疏忽此语句。可以思索在内部for轮回的操作子句的前面利用逗号。例如:
   
  for ($row = 0; $row < 3; $row++ ,echo "<br>") {
  for ($col = 0; $col < 3; $col++) {
  if ($col == 2) {
  continue 2;
  }
  echo "[$row,$col]<br>";
  }
  }
   
  以上轮回将显示:
   
  Parse Error: parse error in
  nested_continue.php3 on line 3
   
  产生甚么了?很分明,语律例则制止在操作子句中利用echo号令。取而代之,可使用print号令:
   
  for ($row = 0; $row < 3; $row++ ,print "<br>") {
  for ($col = 0; $col < 3; $col++) {
  if ($col == 2) {
  continue 2;
  }
  echo "[$row,$col]<br>";
  }
  }
   
  此剧本了局将显示:
   
  [0,0]
  [0,1]
   
  [1,0]
  [1,1]
   
  [2,0]
  [2,1]
   
  4.3 函数
  函数匡助法式员组织本人的代码,使其成为对照轻易了解和利用的代码段。函数让法式员一步步地编写出法式,并以这类体例测试代码。
  在对所编法式有一个初步构思以后,会需求在头脑里或在纸上列出编程纲目。所列纲目中的每一个步调,能够就是一个函数,这就称之为模块化的法式设计,这类手艺将编程的具体进程埋没起来,以便读源法式的人分明全部的法式的设计方针。
  例如,假如在所编法式中包括有一个盘算圆面积的函数,可以挪用以下一行法式编码:
   
  $flt_area_of_circle = area_of_circle(5);
   
  读者在看到所挪用的函数今后,普通城市分明法式在做甚么了,而对函数的实践内容其实不需求过量懂得。
   
  提醒:仔细设计的函数和变量名将有助于了解法式。假如呈现$areaFC = areaCirc($fRad)如许的代码,其寄义就不是非常明晰。
   
  注重:挪用函数意味着PHP将中断法式以后行的履行,跳转到所挪用的函数中去。在函数履行终了今后,PHP会从头跳回到法式中挪用函数的中央,持续往下停止。
   
  让咱们更清晰地看一看函数挪用,在号令行中起首呈现的是一个标量和一个赋值操作符。应当晓得其感化是将赋值操作符右侧的数值付与变量$flt_area_of_circle,然而赋值符右侧的事实是些甚么呢?
  最早看到的是函数名:area_of_circle(),紧跟厥后的圆括号暗示这是一次函数挪用,在圆括号中的是筹办传给函数的一些参数或数值。可以将参数假想为一个足球,传球时,吸收方(好比函数)会有几种选择:运球(以某种体例停止修正),传球出去(挪用其他法式),犯规(挪用毛病处置法式)。
  一个函数的语法布局以下:
   
  function functionName ( parameterList ) {
  // lines of code
  }
   
  函数取名有几个划定 -- 个中最主要的一条就是,函数名不克不及以数字开首,且两头不克不及有空格。参数表可以任选,它供应了函数可使用的特定命值。
   
  4.3.1 函数前往值
  每个PHP函数城市前往一个数值给挪用者。究竟,在设计一个盘算圆面积的函数时,其意义就在于需求将该值付与某个变量。清单4.6给出了一个法式,它界说并挪用area_of_circle()函数。
   
  清单4.6 area_of_circle.php3--盘算圆的面积
   
  <?php
  function area_of_circle( $flt_radius ) {
  return(3.1415 * ($flt_radius * $flt_radius));
  }
   
  $flt_area_of_circle = area_of_circle(5);
   
  echo "The area is $flt_area_of_circle.<br>";
  ?>
   
  该法式输入以下:
   
  The area is 78.5375.
   
  该例显示了是若何将一个参数传给函数的(记得足球的比方吗?)。参数是在紧跟函数名前面的圆括号中给定的。在表4.6中的函数挪用语句是 area_of_circle(5),个中只给出了一个参数,即数字5。一旦传给函数今后,它就以为是变量$flt_radius的值了。
  该函数的第一行动:
   
  return(3.1415 * ($flt_radius * $flt_radius));
   
  它盘算圆的面积,并将盘算得出的新值前往。现实上打印出的内容申明挪用area_of_circle()函数今后的法式流程已前往,而且盘算得出的值将赋给变量$flt_area_of_circle。
   
  注重:一些法式设计言语在函数和子法式之间有些不同,区分在于函数会前往数值,而子法式不会。PHP中不存在这类不同,不论是否前往数值都是函数。
   
  挪用函数后前往一个数值是一个不错的特色,同时这也是PHP最关怀的工作。你也可以前往一个数组,在清单4.7中界说了一个叫做create_list的函数,其前往值赋给变量$temp,了局输入在图4.1中给出。
   
  清单4.7 create_list_php3--若何从函数前往数值列表
   
  <?php
  require( 'common.inc');
   
  function create_list( ) {
  return array( 100, 200, 300, 400 );
  }
   
  $temp = create_list();
   
  dump_array( $temp );
  ?>
   
   
  Page 91 图4.1
   
  图4.1 显示函数create_list()的前往值
   
  本例中,将全部前往的数组值赋给了一个变量,有时,如许做并非处置前往数组的最简捷办法。假如利用PHP的list功效,就可以够将每个前往单位值付与响应的变量,例如:
   
  list( $a, $b, $c ) = create_list();
   
  该赋值语句履行今后,$a,$b和 $c的值分离是100,200和300,由于函数中没有指定变量寄存第四个数组元素,所以其值丢失落了。
  到今朝为止,咱们只注重了复杂数组--即在法式中没有界说下标/数值对的数组。假如前往的数组指定了下标的话,PHP的反响就会有所分歧。在清单4.8中对前往的数组作了修正,所以第二个数组元素就有了指定的下标,在图4.2中给出了该法式的了局输入。
   
  清单4.8 create_list2.php3--若何让函数前往数值列表
   
  <?php
  require( 'common.inc');
   
  function create_list( ) {
  return array(100, 'age' => 200, 300, 400 );
  }
   
  list ( $a, $b, $c ) = create_list();
   
  dump_array( create_list() );
   
  echo "a=$a<br>";
  echo "b=$b<br>";
  echo "c=$c<br>";
  ?>
   
   
  Page 92, 图4.2
   
  图4.2 具有指定下标的数组前往了局
   
  注重,正如所预期的那样,赋给$b的值是300,而不是200。利用list赋值时,指定下标的元素被疏忽了。
   
  4.3.2 向函数传递参数
  普通来讲,PHP会将参数的值传递给函数,这就意味着函数不克不及改动参数表中任何变量的值。在看过下例今后,就会对照清晰为何会如许了:
   
  function one( $parameter ) {
  $parameter++;
  }
   
  $a = 10;
  one($a);
  echo "a=$a<br>";
   
  假如函数one()中的加一操尴尬刁难变量$a有影响的话,那末可以预期函数echo的输入了局为 a=11,而现实上并不是如斯。与此相反,本例的输入显示为a=10。
  设计要改动其参数的函数并非一个好主张。假如要弄分明这是为何,就要研讨一下编程道理。当两段代码同享信息时,它们就被称为是紧耦合的,此时当一段法式改动时--好比到场某种功效--极可能,别的一段法式也要随着改动。由于两段法式需求同时停止修改,所以这时候产生过失的概率就对照高。另外一方面,假如编制的两段法式的关系是松耦合的话,那样,对法式的修正是互相隔离的,所以产生毛病的概率响应就会下降。只要在某些特定的情形下,有些函数需求修正其参数值。
  当函数必需要修正其参数时,那些参数需求经由过程援用的体例传递给函数。在函数中利用变量援用作为参数时,供应的是寄存变量的内存地址,上面给出的函数one就是利用援用变量的例子:
   
  function one( &$parameter ) {
  $parameter++;
  }
   
  $a = 10;
  one($a);
  echo "a=$a<br>";
   
  这段小法式的了局输入为a=11,标明函数one()改动了变量$a的值。注重,采取援用变量的独一分歧就是,需在所界说函数的参数名后面加上&号。
  假如利用另外一个法式员编的法式,就不要奢望去改动函数的界说。在那种情形下,可以在所挪用函数的参数后面加上一个&号,以下示:
   
  one(&$a);
   
  在停止参数传递这一个话题之前,有需要也许讲一讲数组作为函数的参数传递的情形,下例显示了若何从函数中传递出数组元素值:
   
  function array_first( $arr_parameter ) {
  return($arr_parameter[0]);
  }
   
  $a = array_first( array(3,5) );
  echo "a=$a<br>";
   
  在这个例子中界说了一个查找第一个数组元素的函数。请注重,在此用到了尺度的数组元素记号。函数利用数组作为参数和利用标量作为参数的情形并没有太大的区分。
  4.3.3 给函数付与缺省值
  PHP答应为函数的一些或全体参数付与缺省值,这一特征使得函数利用起来加倍轻易了解,由于如许一来,函数挪用时用到的参数就会很少。在清单4.9中界说了函数font,个中供应了色彩和巨细等参数的缺省值。图4.3显示了运转该法式后的输入了局。
   
  清单4.9 default_values.php3--给参数赋缺省值
   
  <?php
   
  function font(
  $str_text,
  $str_color = 'blue',
  $int_size = 2
  ) {
  echo "<font size=\"$int_size\"
  color=\"$str_color\">$str_text</a>";
  }
  ?>
   
  <?php font('This line is blue - size 2.'); ?>
  <br>
  <?php font('This line is red - size 2.', 'red'); ?>
  <br>
  <?php font('This line is green - size 4', 'green',4); ?>
  <br>
   
  注重:付与缺省值的变量老是放在所界说函数参数的最初几个地位。
   
   
  Page 95,Figure 4.3
   
  图4.3 供应缺省值的font()函数
   
  4.3.4 掌握变量的感化域
  所谓变量的感化域,指的是在法式中哪一局部可以看到并利用这一变量。PHP只承认两品种型的感化域 -- 页面和函数感化域。页面感化域是指变量合用于全部 Web页面,函数感化域是指变量合用于单个函数。正常情形下PHP变量只在它们的界说的感化域局限内才可使用。
  当需求在函数外部界说页面感化域的变量时,可使用以下所示的global关头字:
   
  function one( ) {
  global $a;
  $a++;
  }
   
  $a = 10;
  one($a);
  echo "a=$a<br>";
   
  此函数了局将显示a=11,标明了在one()函数外部可使用页感化域的$a变量。利用global关头字与传递援用变量相相似,由于在这两种情形下都要改动函数内部的变量。
   
  注重:在法式中要利用global关头字之前,请稳重思索一下法式的设计思绪,也许利用函数参数一样可行。在函数外部利用页面感化域的变量,并非最好的法式设计办法,由于函数的外部代码应当与法式中的其它局部相隔离。试想去读一段在多个(或每一个)函数中都能改动页面感化域变量的法式 - 它很难读懂的,不是吗?
   
  4.3.5 嵌套函数挪用
  函数可以嵌套挪用,也就是说一个函数可以挪用另外一个函数,而被挪用的函数又可以挪用另外一个函数,然后还可以再挪用别的的函数,如斯等等。正确地讲,函数能嵌套层数的几何由良多要素决意。普通来讲,不用思索任何限制要素。清单4.10讲述了一个使用嵌套函数挪用的法式。
   
  清单 4.10 nested_function.php3--嵌套函数挪用长短常有效的
   
  <?php
  function increment_by_two( $int_parameter ) {
  $int_parameter += 2;
  return($int_parameter);
  }
   
  function increment_by_three( $int_parameter ) {
  $int_parameter++;
  // make a nested function call to increment_by_two().
  Return ( increment_by_two($int_parameter) );
  }
   
  $a = increment_by_three( 34 );
   
  echo "1 = $a<br>";
  ?>
   
  该法式输入显示以下:
   
  a = 37
   
  这个例子只是为了解说嵌套函数的挪用而做的,并没有甚么实践的用途。函数increment_by_three增添其参数值后,又挪用函数increment_by_two,最初招致总的增量为3。
  利用嵌套函数挪用最大的长处是可以将法式设计分为几个局部。每个义务转化为一个嵌套的函数挪用,例如:
   
  function do_task() {
  initialize_data();
  read_data_from_database();
  process_data_to_database();
  perform_cleanup();
  }
   
  4.3.6 递归函数
  挪用本人的函数就叫做递归函数。可以回想一下数组也是可递归的,(例如,一个数组中也能够包括另外一个数组)。
  为了演示递归事实是怎样一回事,让咱们先来看看数学上有名的数字序列--Fibonacci 序列。Fibonacci序列是如许的:
   
  0,1,1,2,3,5,8,13
   
  Fibonacci序列中的每个数字都是由前两个数字相加得出的。例如,第八个数字13就是5和8相加的了局值。清单4.11包含了Fibonacci函数,它是将序列按次号作为参数,前往与该按次号相干的Fibonacci数字。
   
  清单4.11 fibonacci.inc--利用递归函数盘算Fibonacci数
   
  <?php
  function Fibonacci( $var ) {
   
  // the fibonacci series is only defined for
  // positive values.
  if ($var < 0) {
  return( 0 );
  }
   
  // the first two elements in the series are
  // defined as zero and one and don't need
  // recursion.
  if ($var < 2) {
  return ( $var );
  }
   
  // use recursion to find the previous two elements
  // in the series.
  return( Fibonacci($var-1) + Fibonacci($var-2) );
  }
  ?>
   
  可以用以下体例挪用Fibonacci函数:
   
  <?php
  // include the fibonacci function in
  // this script.
  require('fibonacci.inc');
   
  // display the result of the fibonacci call.
  echo "$n<br>";
  ?>
   
  让咱们来反省一下当参数为4时挪用Fibonacci函数的履行了局。Fibonacci函数每挪用本人一次,就是又一级递归挪用。第零级是对该函数的初始挪用:
   
  Level 0:
   
  $n = Fibonacci(4);
   
  由于4大于3,履行最初一个return语句,并发生新的一级递归挪用。
   
  Lelel 1:
   
  return( fibonacci(3) + fibonacci(2) );
   
  此时,函数递归了两次,一次利用的参数是3,一次参数为2。这些Fibonacci挪用今后,由于3和2都不小于2,所以又发生了新一级的递归挪用:
   
  Level 2:
  return( fibonacci(2)+fibonacci(1) +
  fibonacci(1)+fibonacci(0) );
   
  Level 3:
  return( fibonacci(1)+fibonacci(0)+1 + 1+0 );
   
  Level 2:
  return( 1+0+1 + 1+0);
   
  Level 1:
  return( 2 + 1 );
   
  Level 0:
  return( 3 );
   
  如上例所示,递归睁开时,每级对函数递归挪用的了局又会用于再高一级的递归挪用中。Level 0的递归了局是3。十分主要的一点是每个递归函数都需求一个举措让递归中断。成心义的是,由于数组可以递归,所以利用数组变量的函数也必需可以递归。清单4.12给出了一个叫做array_dump的函数,了局显示了一个PHP数组的下标/数值对。
   
  清单4.12 array_dump.inc--利用递归函数显示数组的下标/数值对
   
  <?php
  function array_dump( $var ) {
   
  // The gettype function returns the data type
  // of its parameter.
  switch (gettype($var)) {
   
  // inter, double, and strings are simply
  // displayed.
  case 'integer':
  case 'double':
  case 'string':
  echo "$var";
  break;
   
  // array datatypes need to specially
  // handled.
  case 'array':
  // if the array has no entries, display
  // a message.
  if (! Count($var)) {
  echo 'Empty Array.<br>';
  }
  else {
   
  // the array has entries, so start an
  // HTML table to display them.
  echo '<table border="1" width="100%">';
  echo '<tr>';
  echo '<th>Key</th>';
  echo '<th>Value</th>';
  echo '</tr>';
   
  // use a do loop to iterate over the
  // entries in the array.
  do {
  echo '<tr><td align="left" valign="top">';
  echo key($var);
  echo '</td><td align="left" valign="top">';
  echo gettype(key($var));
  echo '</td><td align="left" valign="top">';
   
  // perform the magic of recursion using the
  // VALUE of the current key/value pair.
  array_dump($var[key($var)]);
   
  echo "</td></tr>";
  } while (next($var));
   
  // end the HTML table after all of the
  //array entries have been displayed.
  echo "</table>";
  }
  break;
   
  // switch statements should always have a default
  // clause - just in case the data has a value
  // your program doesn't expect.
  default:
  echo "unknown data type";
  break;
  }
  }
   
  ?>
   
  用以下体例挪用函数array_dump:
   
  <?php
  // include the array_dump function
  // in this script.
  require('array_dump.inc');
   
  // define an array.
  $arr_test = array(
  23, 24, 25
  ,'name' => 'Waswaldo'
  ,'address' => array(
  ,'line1' => 'Suite 300'
  ,'line2' => '43 Broad Lane'
  )
  );
   
  // display the array.
  Array_dump($arr_test);
  ?>
   
  数组$arr_test的输入了局如图4.4所示。
   
   
  Page 101,图4.4
   
  图 4.4利用函数array_dump显示数组
   
  4.4 总结
  本章触及了很多内容,侧重讲述了PHP的表达式、语句和函数。一切这些都为前面入手下手进修更成心义的使用法式开辟任务之前,供应了需要的最根基常识。
  咱们已学过,表达式是恣意操作数和操作符的组合。操作数可所以变量、数字或函数挪用。一些利用递增或递加操作符的函数能够会有某些反作用。正如本章中在会商语句时所看到的那样,表达式可用来掌握判别语句、轮回语句和跳转语句的。
  语句可所以一个以分号停止的单个表达式。例如,$n = 5;就是一个赋值语句。语句也能够对照庞杂,它们多是判别语句、轮回语句和跳转语句。
  if语句和switch语句都属于判别语句,这两种语句都是先对表达式停止盘算,然后依据表达式的值决意履行哪一段语句。
  轮回语句包含for、while和do轮回语句,它们的目标是为了屡次履行统一段语句。for轮回语句最庞杂 -- 它包含初始化、前提和操作子语句几局部,初始化子语句在for轮回入手下手时履行,当前提表达式为假时,for轮回停止,而每次轮回以后都要履行操作表达式。对while轮回语句来讲,由于要先对前提表达式值停止盘算判别,所以有能够一次也不履行其语句段。相反,do轮回则老是要先履行其语句段,尔后再对其前提表达式停止盘算判别。
  函数的利用使得法式加倍轻易处置。函数可以吸收多个参数,而且能给参数设置缺省值。一个函数的外部变量只可以只在函数的外部利用。当要利用感化域为全部Web页的变量时,就要利用关头字global停止界说。
  当处置数组或碰到一些其它的数学概念时,能够要利用到递归函数。递归函数是本人挪用本人的函数。记居处有的递归函数都必需具有能在需求时停止递归的体例。
  下一章“中场一:毗连数据库”,将从进修PHP的根基常识中中止一下。将进修若何毗连MySQL数据库和若何处置HTML表单。
   
   
  
多个成员之间重复做相同的工作,很容易因为交流沟通的时候没有进行一致性的文档要求而出现不明错误,严重影响开发进度,导致在预定时间内无法完成该项目或者完成的项目跟原先计划所要实现的项目功能不符合。
柔情似水 该用户已被删除
沙发
发表于 2015-2-16 01:55:28 | 只看该作者
Apache不是非得用80或者8080端口的,我刚开始安得时候就是80端口老占用,就用了个 81端口,结果照常,就是输localhost的时候,应该输入为 localhost:81
谁可相欹 该用户已被删除
板凳
发表于 2015-3-4 22:17:34 | 只看该作者
这些中手常用的知识,当你把我说的这些关键字都可以熟练运用的时候,你可以选择自己
海妖 该用户已被删除
地板
发表于 2015-3-11 21:14:09 | 只看该作者
这些中手常用的知识,当你把我说的这些关键字都可以熟练运用的时候,你可以选择自己
飘飘悠悠 该用户已被删除
5#
发表于 2015-3-19 13:30:15 | 只看该作者
微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox  支持的不是很好,所以能少用还是少用的好。
莫相离 该用户已被删除
6#
发表于 2015-3-25 03:46:44 | 只看该作者
刚开始安装php的时候,我图了个省事,把php的扩展全都打开啦(就是把php.ini 那一片 extension 前面的冒号全去掉啦),这样自然有好处,以后不用再需要什么功能再来打开。
活着的死人 该用户已被删除
7#
发表于 2015-4-1 12:10:11 | 只看该作者
我还是强烈建议自己搭建php环境。因为在搭建的过程中你会遇到一些问题,通过搜索或是看php手册解决问题后,你会更加深刻的理解它们的工作原理,了解到php配置文件中的一些选项设置。
乐观 该用户已被删除
8#
发表于 2015-4-9 13:00:28 | 只看该作者
最后祝愿,php会给你带来快乐的同时 你也会给他带来快乐。
老尸 该用户已被删除
9#
发表于 2015-4-16 10:10:32 | 只看该作者
,熟悉html,能用div+css,还有javascript,优先考虑linux。我在开始学习的时候,就想把这些知识一起学习,我天真的认为同时学习能够互相呼应,因为知识是相通的。
变相怪杰 该用户已被删除
10#
发表于 2015-4-21 07:11:58 | 只看该作者
php里的数组为空的时候是不能拿来遍历的;(这个有点低级啊,不过我刚被这个边界问题墨迹了好长一会)
只想知道 该用户已被删除
11#
发表于 2015-4-21 18:12:34 | 只看该作者
使用zendstdio 写代码的的时候,把tab 的缩进设置成4个空格是很有必要的
透明 该用户已被删除
12#
发表于 2015-4-21 19:12:04 | 只看该作者
其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎
深爱那片海 该用户已被删除
13#
发表于 2015-4-26 02:53:47 | 只看该作者
要进行开发,搭建环境是首先需要做的事,windows下面我习惯把环境那个安装在C盘下面,因为我配的环境经常出现诡异事件,什么事都没做环境有的时候就不能用啦。
山那边是海 该用户已被删除
14#
发表于 2015-4-28 22:27:33 | 只看该作者
遇到出错的时候,我经常把错误信息直接复制到 google的搜索栏,一般情况都是能搜到结果的,不过有时候会搜出来一大片英文的出来,这时候就得过滤一下,吧中文的弄出来,挨着式方法。
再现理想 该用户已被删除
15#
发表于 2015-5-8 16:42:46 | 只看该作者
真正的方向了,如果将来要去开发团队,你一定要学好smarty ,phplib这样的模板引擎,
分手快乐 该用户已被删除
16#
发表于 2015-5-11 20:51:01 | 只看该作者
至于模板嘛,各位高人一直以来就是争论不休,我一只小菜鸟就不加入战团啦,咱们新手还是多学点东西的好。
第二个灵魂 该用户已被删除
17#
发表于 2015-6-7 21:42:24 | 只看该作者
首推的搜索引擎当然是Google大神,其次我比较喜欢 百度知道。不过搜出来的结果往往都是 大家copy来copy去的,运气的的概率很大。
18#
发表于 2015-6-25 20:33:16 | 只看该作者
微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox  支持的不是很好,所以能少用还是少用的好。
冷月葬花魂 该用户已被删除
19#
发表于 2015-6-26 04:01:26 | 只看该作者
本文当是我的笔记啦,遇到的问题随时填充
小魔女 该用户已被删除
20#
发表于 2015-7-4 15:31:08 | 只看该作者
开发工具也会慢慢的更专业,每个公司的可能不一样,但是zend studio是个大伙都会用的。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-22 23:28

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表