PHP学习杂记之语法基础一

时间:2022-01-21 16:09:44

1. 赋值运算将原变量的值拷贝到新变量中(传值赋值),所以改变其中一个并不影响另一个。这也适合于在密集循环中拷贝一些值例如大数组。

在 PHP 中普通的传值赋值行为有个例外就是碰到对象 object 时,在 PHP 5 中是以引用赋值的,除非明确使用了 clone 关键字来拷贝。 

 

2. 自 PHP 5 起,new 运算符自动返回一个引用,因此再对 new 的结果进行引用赋值在 PHP 5.3 以及以后版本中会发出一条 E_DEPRECATED 错误信息,在之前版本会发出一条 E_STRICT 错误信息。

例如以下代码将产生警告:

<?php
class C {}

/* The following line generates the following error message:
 * Deprecated: Assigning the return value of new by reference is deprecated in...
 */
$o = &new C;
?>  

 

3. 如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。此规则也适用于 switch 语句。当用 === 或 !== 进行比较时则不进行类型转换,因为此时类型和数值都要比对。

<?php
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
var_dump("10" == "1e1"); // 10 == 10 -> true
var_dump(100 == "1e2"); // 100 == 100 -> true

switch ("a") {
case 0:
    echo "0";
    break;
case "a": // never reached because "a" is already matched with 0
    echo "a";
    break;
}
?>

  

4. 三元运算符

表达式 (expr1) ? (expr2) : (expr3)expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3。

自 PHP 5.3 起,可以省略三元运算符中间那部分。表达式 expr1 ?: expr3expr1 求值为 TRUE 时返回 expr1,否则返回 expr3。 

 

5. 错误控制运算符

PHP 支持一个错误控制运算符:@。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。 

如果用 set_error_handler() 设定了自定义的错误处理函数,仍然会被调用,但是此错误处理函数可以(并且也应该)调用 error_reporting(),而该函数在出错语句前有 @ 时将返回 0。

如果激活了 track_errors 特性,表达式所产生的任何错误信息都被存放在变量 $php_errormsg 中。此变量在每次出错时都会被覆盖,所以如果想用它的话就要尽早检查。 

 

6. 字符变量的自增运算

在处理字符变量的算数运算时,PHP 沿袭了 Perl 的习惯,而非 C 的。例如,在 Perl 中 $a = 'Z'; $a++; 将把 $a 变成'AA',而在 C 中,a = 'Z'; a++; 将把 a 变成 '[''Z' 的 ASCII 值是 90,'[' 的 ASCII 值是 91)。注意字符变量只能递增,不能递减,并且只支持纯字母(a-z 和 A-Z)。递增/递减其他字符变量则无效,原字符串没有变化。

Example #1 涉及字符变量的算数运算

<?php
$i = 'W';
for ($n=0; $n<6; $n++) {
    echo ++$i . "\n";
}
?>

以上例程会输出:

X
Y
Z
AA
AB
AC

  

7. "与"和"或"有两种不同形式运算符的原因是它们运算的优先级不同

Example #1 逻辑运算符示例

<?php

// --------------------
// foo() 根本没机会被调用,被运算符"短路"了

$a = (false && foo());
$b = (true  || foo());
$c = (false and foo());
$d = (true  or  foo());

// --------------------
// "||" 比 "or" 的优先级高

// 表达式 (false || true) 的结果被赋给 $e
// 等同于:($e = (false || true))
$e = false || true;

// 常量 false 被赋给 $f,true 被忽略
// 等同于:(($f = false) or true)
$f = false or true;

var_dump($e, $f);

// --------------------
// "&&" 比 "and" 的优先级高

// 表达式 (true && false) 的结果被赋给 $g
// 等同于:($g = (true && false))
$g = true && false;

// 常量 true 被赋给 $h,false 被忽略
// 等同于:(($h = true) and false)
$h = true and false;

var_dump($g, $h);
?>

以上例程的输出类似于:

bool(true)
bool(false)
bool(false)
bool(true)

  

8. elseif和else if语句的区别

elseifelse if 只有在类似上例中使用花括号的情况下才认为是完全相同。如果用冒号来定义 if/elseif 条件,那就不能用两个单词的 else if,否则 PHP 会产生解析错误。

 

<?php

/* 不正确的使用方法: */
if($a > $b):
    echo $a." is greater than ".$b;
else if($a == $b): // 将无法编译
    echo "The above line causes a parse error.";
endif;


/* 正确的使用方法: */
if($a > $b):
    echo $a." is greater than ".$b;
elseif($a == $b): // 注意使用了一个单词的 elseif
    echo $a." equals ".$b;
else:
    echo $a." is neither greater than or equal to ".$b;
endif;

?>

  

9. break语句

break 结束当前 forforeachwhiledo-while 或者 switch 结构的执行。

break 可以接受一个可选的数字参数来决定跳出几重循环。

 

<?php
$arr = array('one', 'two', 'three', 'four', 'stop', 'five');
while (list (, $val) = each($arr)) {
    if ($val == 'stop') {
        break;    /* You could also write 'break 1;' here. */
    }
    echo "$val<br />\n";
}

/* 使用可选参数 */

$i = 0;
while (++$i) {
    switch ($i) {
    case 5:
        echo "At 5<br />\n";
        break 1;  /* 只退出 switch. */
    case 10:
        echo "At 10; quitting<br />\n";
        break 2;  /* 退出 switch 和 while 循环 */
    default:
        break;
    }
}
?>

 

10. continue语句

continue 在循环结构用用来跳过本次循环中剩余的代码并在条件求值为真时开始执行下一次循环。

Note: 注意在 PHP 中 switch 语句被认为是可以使用 continue 的一种循环结构。

continue 接受一个可选的数字参数来决定跳过几重循环到循环结尾。默认值是 1,即跳到当前循环末尾。

 

<?php
while (list ($key, $value) = each($arr)) {
    if (!($key % 2)) { // skip odd members
        continue;
    }
    do_something_odd($value);
}

$i = 0;
while ($i++ < 5) {
    echo "Outer<br />\n";
    while (1) {
        echo "Middle<br />\n";
        while (1) {
            echo "Inner<br />\n";
            continue 3;
        }
        echo "This never gets output.<br />\n";
    }
    echo "Neither does this.<br />\n";
}
?>

  

11. require、include、require_once、include_once
requireinclude 几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告(E_WARNING),脚本会继续运行。
require_once 语句和 require 语句完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含。

include_once 语句在脚本执行期间包含并运行指定文件。此行为和 include 语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次。

include_once 可以用于在脚本执行期间同一个文件有可能被包含超过一次的情况下,想确保它只被包含一次以避免函数重定义,变量重新赋值等问题。 

 
    查找路径:

    被包含文件先按参数给出的路径寻找,如果没有给出目录(只有文件名)时则按照 include_path 指定的目录寻找。如果在 include_path 下没找到该文件则 include 最后才在调用脚本文件所在的目录和当前工作目录下寻找。如果最后仍未找到文件则 include 结构会发出一条警告;这一点和 require 不同,后者会发出一个致命错误

    如果定义了路径——不管是绝对路径(在 Windows 下以盘符或者 \ 开头,在 Unix/Linux 下以 / 开头)还是当前目录的相对路径(以 . 或者 .. 开头)——include_path 都会被完全忽略。例如一个文件以 ../ 开头,则解析器会在当前目录的父目录下寻找该文件。

 变量范围

  当一个文件被包含时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。 

Example #1 基本的 include 例子

vars.php
<?php

$color = 'green';
$fruit = 'apple';

?>

test.php
<?php

echo "A $color $fruit"; // A

include 'vars.php';

echo "A $color $fruit"; // A green apple

?>

如果 include 出现于调用文件中的一个函数里,则被调用的文件中所包含的所有代码将表现得如同它们是在该函数内部定义的一样。所以它将遵循该函数的变量范围。此规则的一个例外是魔术常量,它们是在发生包含之前就已被解析器处理的。

   Example #2 函数中的包含

<?php

function foo()
{
    global $color;

    include 'vars.php';

    echo "A $color $fruit";
}

/* vars.php is in the scope of foo() so     *
 * $fruit is NOT available outside of this  *
 * scope.  $color is because we declared it *
 * as global.                               */

foo();                    // A green apple
echo "A $color $fruit";   // A green

?>

  当一个文件被包含时,语法解析器在目标文件的开头脱离 PHP 模式并进入 HTML 模式,到文件结尾处恢复。由于此原因,目标文件中需要作为 PHP 代码执行的任何代码都必须被包括在有效的 PHP 起始和结束标记之中。 

   返回值处理:

在失败时 include 返回 FALSE 并且发出警告。成功的包含则返回 1,除非在包含文件中另外给出了返回值。可以在被包括的文件中使用 return 语句来终止该文件中程序的执行并返回调用它的脚本。同样也可以从被包含的文件中返回值。可以像普通函数一样获得 include 调用的返回值。不过这在包含远程文件时却不行,除非远程文件的输出具有合法的 PHP 开始和结束标记(如同任何本地文件一样)。可以在标记内定义所需的变量,该变量在文件被包含的位置之后就可用了。

因为 include 是一个特殊的语言结构,其参数不需要括号。在比较其返回值时要注意。

Example #4 比较 include 的返回值

<?php
// won't work, evaluated as include(('vars.php') == 'OK'), i.e. include('')
if (include('vars.php') == 'OK') {
    echo 'OK';
}

// works
if ((include 'vars.php') == 'OK') {
    echo 'OK';
}
?> 

Example #5 includereturn 语句

return.php
<?php

$var = 'PHP';

return $var;

?>

noreturn.php
<?php

$var = 'PHP';

?>

testreturns.php
<?php

$foo = include 'return.php';

echo $foo; // prints 'PHP'

$bar = include 'noreturn.php';

echo $bar; // prints 1

?> 

$bar 的值为 1 是因为 include 成功运行了。注意以上例子中的区别。第一个在被包含的文件中用了 return 而另一个没有。如果文件不能被包含,则返回 FALSE 并发出一个 E_WARNING 警告。 

12. goto语句
goto 操作符可以用来跳转到程序中的另一位置。该目标位置可以用目标名称加上冒号来标记,而跳转指令是 goto 之后接上目标位置的标记。PHP 中的 goto 有一定限制,目标位置只能位于同一个文件和作用域,也就是说无法跳出一个函数或类方法,也无法跳入到另一个函数。也无法跳入到任何循环或者 switch 结构中。可以跳出循环或者 switch,通常的用法是用 goto 代替多层的 break。 

Example #1 goto 示例

<?php
goto a;
echo 'Foo';
 
a:
echo 'Bar';
?>

以上例程会输出:

Bar

 Example #2 goto 跳出循环示例

<?php
for($i=0,$j=50; $i<100; $i++) {
  while($j--) {
    if($j==17) goto end; 
  }  
}
echo "i = $i";
end:
echo 'j hit 17';
?>

以上例程会输出:

j hit 17

 Example #3 以下写法无效

<?php
goto loop;
for($i=0,$j=50; $i<100; $i++) {
  while($j--) {
    loop:
  }
}
echo "$i = $i";
?>

以上例程会输出:

Fatal error: 'goto' into loop or switch statement is disallowed in
script on line 2 

Note:

goto 操作符仅在 PHP 5.3及以上版本有效。