php易錯筆記-流程控制,函數

流程控制

PHP 提供了一些流程控制的替代語法,包括 ifwhileforforeachswitch。替代語法的基本形式是把左花括號({)換成冒號(:),把右花括號(})分別換成 endif;,endwhile;,endfor;,endforeach; 以及 endswitch;。
Note: 不支持在同一個控制塊內混合使用兩種語法。

特別注意:php

switch 和第一個 case 之間的任何輸出(含空格)將致使語法錯誤。例如,這樣是無效的:數組

<?php switch ($foo): ?>
    <?php case 1: ?>
    ...
<?php endswitch ?>

而這樣是有效的,由於 switch 以後的換行符被認爲是結束標記 ?> 的一部分,因此在 switchcase 之間不能有任何輸出:安全

<?php switch ($foo): ?>
<?php case 1: ?>
    ...
<?php endswitch ?>

if/else

Note: 必需要注意的是 elseif 與 else 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;

?>

for

for 循環是 PHP 中最複雜的循環結構。它的行爲和 C 語言的類似。 for 循環的語法是:閉包

for (expr1; expr2; expr3)
    statement

第一個表達式(expr1)在循環開始前無條件求值(並執行)一次。less

expr2每次循環開始前求值。若是值爲 TRUE,則繼續循環,執行嵌套的循環語句。若是值爲 FALSE,則終止循環。函數

expr3每次循環以後被求值(並執行)。oop

每一個表達式均可覺得空或包括逗號分隔的多個表達式
表達式 expr2 中,全部用逗號分隔的表達式都會計算,但只取最後一個結果expr2 爲空意味着將無限循環下去(和 C 同樣,PHP 暗中認爲其值爲 TRUE)。這可能不像想象中那樣沒有用,由於常常會但願用有條件的 break 語句來結束循環而不是用 for 的表達式真值判斷。ui

考慮如下的例子,它們都顯示數字 1 到 10:this

/* example 2 */    
for ($i = 1; ; $i++) {
    if ($i > 10) {
        break;
    }
    echo $i;
}

/* example 3 */    
$i = 1;
for (;;) {
    if ($i > 10) {
        break;
    }
    echo $i;
    $i++;
}

/* example 4 */    
for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++);

/* example */
$people = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for($i = 0, $size = count($people); $i < $size; ++$i)
{
    print $people[$i];
}

excel中可使用:編碼

<?php
for($col = 'R'; $col != 'AD'; $col++) {
    echo $col.' ';
}

//returns: R S T U V W X Y Z AA AB AC

//Take note that you can't use $col < 'AD'. It only works with !=
//Very convenient when working with excel columns.
?>

foreach

在 $value 以前加上 & 來修改數組的元素。此方法將以 引用賦值而不是拷貝一個值( 最後切記unset()變量,不然可能出現一些意料以外的結果)。
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // 最後取消掉引用
?>

如下的代碼功能徹底相同:

<?php
$arr = array("one", "two", "three");
reset($arr);
while (list(, $value) = each($arr)) {
    echo "Value: $value<br>\n";
}

foreach ($arr as $value) {
    echo "Value: $value<br />\n";
}
?>

如下代碼功能也徹底相同:

<?php
$arr = array("one", "two", "three");
reset($arr);
while (list($key, $value) = each($arr)) {
    echo "Key: $key; Value: $value<br />\n";
}

foreach ($arr as $key => $value) {
    echo "Key: $key; Value: $value<br />\n";
}
?>
list() 給嵌套的數組解包

(PHP 5 >= 5.5.0, PHP 7)
PHP 5.5 增添了遍歷一個數組的數組的功能而且把嵌套的數組解包到循環變量中,只需將 list() 做爲值提供。

<?php
$array = [
    [1, 2],
    [3, 4],
];    
foreach ($array as list($a, $b)) {
    // $a contains the first element of the nested array,
    // and $b contains the second element.
    echo "A: $a; B: $b\n";
}
?>

以上例程會輸出:

A: 1; B: 2
A: 3; B: 4

break

break 結束當前 forforeachwhiledo-while 或者 switch 結構的執行。

break 能夠 接受一個可選的數字參數來決定跳出幾重循環
<?php
$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;
    }
}
?>
版本 說明
5.4.0 break 0; 再也不合法。這在以前的版本被解析爲 break 1;。
5.4.0 取消變量做爲參數傳遞(例如 $num = 2; break $num;)。
A break statement that is in the outer part of a program (e.g. not in a control loop) will end the script.
<?php 
echo "hello";
if (true) break;
echo " world";
?>

will only show "hello"

continue

continue 在循環結構用用來跳過本次循環中剩餘的代碼並在條件求值爲真時開始執行下一次循環。
Note: 注意在 PHP 中 switch 語句被認爲是可使用 continue 的一種循環結構。

continue 接受一個可選的數字參數來決定跳過幾重循環到循環結尾。默認值是 1,即跳到當前循環末尾。
<?php
$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";
}
?>
版本 說明
5.4.0 continue 0; 再也不合法。這在以前的版本被解析爲 continue 1;。
5.4.0 取消變量做爲參數傳遞(例如 $num = 2; continue $num;)。
<?php

    for( $i = 0; $i < 3; ++ $i )
    {
        echo ' [', $i, '] ';
        switch( $i )
        {
            case 0: echo 'zero'; break;
            case 1: echo 'one' ; XXXX;
            case 2: echo 'two' ; break;
        }
        echo ' <' , $i, '> ';
    }

?>

For XXXX I filled in

- continue 1//[0] zero <0>  [1] one <1>  [2] two <2>
- continue 2//[0] zero <0>  [1] one [2] two <2>
- break 1//[0] zero <0>  [1] one <1>  [2] two <2>
- break 2//[0] zero <0>  [1] one

switch

Note: 注意和其它語言不一樣,continue 語句做用到 switch 上的做用相似於 break。若是在循環中有一個 switch 並但願 continue 到外層循環中的下一輪循環,用 continue 2

Note: 注意 switch/case 做的是鬆散比較

<?php
$a = 0;

if(++$a == 3) echo 3;
elseif(++$a == 2) echo 2;
elseif(++$a == 1) echo 1;
else echo "No match!";

// Outputs: 2

$a = 0;

switch(++$a) {
    case 3: echo 3; break;
    case 2: echo 2; break;
    case 1: echo 1; break;
    default: echo "No match!"; break;
}

// Outputs: 1
?>

declare

(PHP 4, PHP 5, PHP 7)
declare 結構用來設定一段代碼的執行指令。declare 的語法和其它流程控制結構類似:

declare (directive)
    statement

directive 部分容許設定 declare 代碼段的行爲。目前只認識兩個指令:ticks 以及 encoding(PHP 5.3.0+)。

declare 代碼段中的 statement 部分將被執行——怎樣執行以及執行中有什麼反作用出現取決於 directive 中設定的指令。

declare 結構也可用於全局範圍,影響到其後的全部代碼(但若是有 declare 結構的文件被其它文件包含,則對包含它的父文件不起做用)。
<?php
// these are the same:

// you can use this:
declare(ticks=1) {
    // entire script here
}

// or you can use this:
declare(ticks=1);
// entire script here
?>

Ticks

Tick(時鐘週期)是一個在 declare 代碼段中解釋器每執行 N 條可計時的低級語句就會發生的事件。N 的值是在 declare 中的 directive 部分用 ticks=N 來指定的。

不是全部語句均可計時。一般條件表達式和參數表達式都不可計時

在每一個 tick 中出現的事件是由 register_tick_function() 來指定的。更多細節見下面的例子。注意每一個 tick 中能夠出現多個事件。

Example #1 Tick 的用法示例

<?php

declare(ticks=1);

// A function called on each tick event
function tick_handler()
{
    echo "tick_handler() called\n";
}

register_tick_function('tick_handler');

$a = 1;

if ($a > 0) {
    $a += 2;
    print($a);
}
/*
tick_handler() called
tick_handler() called
tick_handler() called
3tick_handler() called
 */
?>

Example #2 Ticks 的用法示例

<?php

function tick_handler()
{
  echo "tick_handler() called\n";
}

$a = 1;
tick_handler();

if ($a > 0) {
    $a += 2;
    tick_handler();
    print($a);
    tick_handler();
}
tick_handler();

?>

參見 register_tick_function() 和 unregister_tick_function()。

Encoding

能夠用 encoding 指令來對每段腳本指定其編碼方式。

Example #3 對腳本指定編碼方式

<?php
declare(encoding='ISO-8859-1');
// code here
?>
當和命名空間結合起來時 declare 的惟一合法語法是 declare(encoding='...');,其中 ... 是編碼的值。而
declare(encoding='...') {} 將在與命名空間結合時產生解析錯誤。 在 PHP 5.3 中除非在編譯時指定了
--enable-zend-multibyte,不然 declare 中的 encoding 值會被忽略。

注意除非用 phpinfo(),不然 PHP 不會顯示出是否在編譯時指定了 --enable-zend-multibyte。

參見 zend.script_encoding。

require/include(建議配合魔術常量使用)

requireinclude 幾乎徹底同樣,除了處理失敗的方式不一樣以外。require 在出錯時產生 E_COMPILE_ERROR 級別的錯誤。換句話說將致使腳本停止而 include 只產生警告(E_WARNING),腳本會繼續運行。

1.被包含文件先按參數給出的路徑尋找,若是 沒有給出目錄(只有文件名)時則按照 include_path 指定的目錄尋找。若是在 include_path 下沒找到該文件則 include 最後纔在 調用腳本文件所在的目錄當前工做目錄下尋找。
2.若是 定義了路徑——不論是 絕對路徑(在 Windows 下以盤符或者 \ 開頭,在 Unix/Linux 下以 / 開頭)仍是當前目錄的 相對路徑(以 . 或者 .. 開頭)——include_path 都會被徹底忽略。例如一個文件以 ../ 開頭,則解析器會在當前目錄的父目錄下尋找該文件。

做用域:

1.當一個文件被包含時,其中所包含的代碼 繼承了 include 所在行的變量範圍。從該處開始,調用文件在該行處可用的任何變量在被調用的文件中也均可用。
2.不過 全部在包含文件中定義的函數和類都具備全局做用域(引入了一個類stdClass,若是要實例化則使用 new \stdClass)。

當一個文件被包含時,語法解析器在目標文件的開頭脫離 PHP 模式並進入 HTML 模式,到文件結尾處恢復。因爲此緣由,目標文件中須要做爲 PHP 代碼執行的任何代碼都必須被包括在有效的 PHP 起始和結束標記之中。

返回值:

失敗時 include 返回 FALSE 而且發出警告。成功的包含則返回 1,除非在包含文件中另外給出了返回值。能夠在被包括的文件中使用 return 語句來終止該文件中程序的執行並返回調用它的腳本。一樣也能夠從被包含的文件中返回值。能夠像普通函數同樣得到 include 調用的返回值。
file.php
<?php 
$a = ['aa'];
 ?>

php.php
<?php 
return ['aa'];
 ?>

<?php 
if (false) {
    require 'file';
    require('file.php');
}
//include 'file';//Warning
var_export(include('file.php'));echo "\r\n";
if (true) {
    echo require 'file.php', "\r\n";
    var_dump(@include 'file');echo "\r\n";
    var_dump(require 'php.php');echo "\r\n";
    var_dump((include('php.php')) == ['aa']);echo "\r\n";//注意括號,等同(include 'php.php') == ['aa']
    var_dump(include('php.php') == ['aa']);echo "\r\n";//等同於include(('php.php') == ['aa'])
    require 'file';
}
echo 'End';
/*
1
1
bool(false)

array(1) {
  [0]=>
  string(2) "aa"
}

bool(true)

PHP Warning:  include(): Filename cannot be empty in D:\php\test\test.php on line 13

Warning: include(): Filename cannot be empty in D:\php\test\test.php on line 13
PHP Warning:  include(): Failed opening '' for inclusion (include_path='.;C:\php\pear') in D:\php\test\test.php on line 13

Warning: include(): Failed opening '' for inclusion (include_path='.;C:\php\pear') in D:\php\test\test.php on line 13
bool(false)

PHP Warning:  require(file): failed to open stream: No such file or directory in D:\php\test\test.php on line 14

Warning: require(file): failed to open stream: No such file or directory in D:\php\test\test.php on line 14
PHP Fatal error:  require(): Failed opening required 'file' (include_path='.;C:\php\pear') in D:\php\test\test.php on line 14

Fatal error: require(): Failed opening required 'file' (include_path='.;C:\php\pear') in D:\php\test\test.php on line 14
 */
 ?>

函數:

若是在包含文件中定義有函數,這些 函數不論是在 return 以前仍是以後定義的,均可以獨立在主文件中使用。若是文件 被包含兩次,PHP 5 發出致命錯誤由於函數已經被定義,可是 PHP 4 不會對在 return 以後定義的函數報錯。推薦使用 include_once 而不是檢查文件是否已包含並在包含文件中有條件返回。

另外一個將 PHP 文件「包含」到一個變量中的方法是用輸出控制函數結合 include 來捕獲其輸出,例如:

Example #6 使用輸出緩衝來將 PHP 文件包含入一個字符串

<?php
$string = get_include_contents('somefile.php');

function get_include_contents($filename) {
    if (is_file($filename)) {
        ob_start();
        include $filename;
        $contents = ob_get_contents();
        ob_end_clean();
        return $contents;
    }
    return false;
}

?>
Note: 由於是一個語言構造器而不是一個函數,不能被 可變函數(如:$var()) 調用。

require_once/include_once

require_once/include_once 語句和 require/include 語句徹底相同,惟一區別是 PHP 會檢查該文件是否已經被包含過,若是是則不會再次包含。

實例(php 7.0.12):

<?php 
var_dump(include_once 'file.php'); // int(1)
var_dump(include_once 'file.php'); // bool(true)
 ?>

goto

goto 操做符能夠用來跳轉到程序中的另外一位置。該目標位置能夠用目標名稱加上冒號來標記,而跳轉指令是 goto 以後接上目標位置的標記。

PHP 中的 goto 有必定限制,目標位置只能位於同一個文件和做用域,也就是說 沒法跳出一個函數或類方法,也 沒法跳入到另外一個函數。也 沒法跳入到任何循環或者 switch 結構中。能夠跳出循環或者 switch,一般的用法是用 goto 代替多層的 break

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

特別的例子:

Remember if you are not a fan of wild labels hanging around you are free to use braces in this construct creating a slightly cleaner look. 
Labels also are always executed and do not need to be called to have their associated code block ran. A purposeless example is below.
<?php 

$headers = Array('subject', 'bcc', 'to', 'cc', 'date', 'sender'); 
$position = 0; 

hIterator: { 

    $c = 0; 
    echo $headers[$position] . PHP_EOL; 

    cIterator: { 
        echo ' ' . $headers[$position][$c] . PHP_EOL; 

        if(!isset($headers[$position][++$c])) { 
            goto cIteratorExit; 
        } 
        goto cIterator; 
    } 

    cIteratorExit: { 
        if(isset($headers[++$position])) { 
            goto hIterator; 
        } 
    } 
} 
?>

函數

用戶自定義函數

函數 無需在調用以前被定義,除非是下面兩個例子中函數是有條件被定義時。

當一個函數是有條件被定義時,必須在調用函數以前定義

Example #2 有條件的函數

<?php    
$makefoo = true;

/* 不能在此處調用foo()函數,
   由於它還不存在,但能夠調用bar()函數。*/    
bar();

if ($makefoo) {
  function foo()
  {
    echo "I don't exist until program execution reaches me.\n";
  }
}    
/* 如今能夠安全調用函數 foo()了,
   由於 $makefoo 值爲真 */    
if ($makefoo) foo();

function bar()
{
  echo "I exist immediately upon program start.\n";
}

?>
PHP 中的 全部函數和類都具備全局做用域,能夠定義在一個函數以內而在以外調用,反之亦然。

PHP 不支持函數重載,也不可能取消定義或者重定義已聲明的函數

<?php
function foo() {
  function bar() {
    echo "I don't exist until foo() is called.\n";
  }
}

/* 如今還不能調用bar()函數,由於它還不存在 */
foo();

/* 如今能夠調用bar()函數了,由於foo()函數
   的執行使得bar()函數變爲已定義的函數 */    
bar();

?>

函數的參數

PHP 支持按值傳遞參數(默認),經過引用傳遞參數以及默認參數。也支持可變長度參數列表

引用傳遞:在函數定義(而不是使用時)中該參數的前面加上符號 &function xxx(&$a, $b) {}
默認參數:默認值必須是常量表達式(標量,array,NULL),不能是諸如變量類成員,或者函數調用等。
類型聲明(類型提示)
類型聲明容許函數在調用時要求參數爲特定類型。 若是給出的值類型不對,那麼將會產生一個錯誤: 在PHP 5中,這將是一個可恢復的致命錯誤,而在PHP 7中將會拋出一個TypeError異常

爲了指定一個類型聲明,類型應該加到參數名前。這個聲明 能夠經過將參數的默認值設爲NULL來實現容許傳遞NULL
Type Description Minimum PHP version
Class/interface name The parameter must be an instanceof the given class or interface name. PHP 5.0.0
self The parameter must be an instanceof the same class as the one the method is defined on. This can only be used on class and instance methods. PHP 5.0.0
array The parameter must be an array. PHP 5.1.0
callable The parameter must be a valid callable. PHP 5.4.0
bool The parameter must be a boolean value. PHP 7.0.0
float The parameter must be a floating point number. PHP 7.0.0
int The parameter must be an integer. PHP 7.0.0
string The parameter must be a string. PHP 7.0.0
注意:類型提示只能是以上表格中的類型(單詞),例如 bool不能寫做 boolean(boolean會被看成class或interface解析)。

類型提示:

<?php
 function test(boolean $param) {}
 test(true);
 ?>

以上例程會輸出:

Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of boolean, boolean given, called in - on line 1 and defined in -:1

嚴格類型:使用 declare 語句和strict_types 聲明來啓用嚴格模式(如declare(strict_types=1);)。
可變數量的參數列表
PHP 在用戶自定義函數中支持可變數量的參數列表。在 PHP 5.6 及以上的版本中,由 ... 語法實現(相似於js);在 PHP 5.5 及更早版本中,使用函數 func_num_args()func_get_arg(),和 func_get_args()

...既能夠用於 定義可變參數列表,也能夠用來提供 參數解包

Example #13 使用 ... 定義可變參數 in PHP 5.6+

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);//10
?>

Example #14 使用 ... 提供參數

<?php
function add($a, $b) {
    return $a + $b;
}

echo add(...[1, 2])."\n";//3

$a = [1, 2];
echo add(...$a);//3
?>

Example #15 部分可變參數以及可變參數列表的類型提示

<?php
function total_intervals($unit, DateInterval ...$intervals) {
    $time = 0;
    foreach ($intervals as $interval) {
        $time += $interval->$unit;
    }
    return $time;
}

$a = new DateInterval('P1D');
$b = new DateInterval('P2D');
echo total_intervals('d', $a, $b).' days';//3 days

// This will fail, since null isn't a DateInterval object.
echo total_intervals('d', null);
//Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, null given, called in - on line 14 and defined in - on line 2
?>

在php 5.5以及以前版本中使用可變參數

<?php
function sum() {
    $acc = 0;
    foreach (func_get_args() as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);//10
?>

返回值

若是省略了 return,則返回值爲 NULL。

Example #1 return 的使用

<?php
function square($num) {
    $sum = $num * $num;
}
function square2($num) {
    $sum = $num * $num;
    return;
}
var_dump(square(4));   // NULL
var_dump(square2(4));   // NULL
?>
從函數返回一個引用,必須在函數聲明和指派返回值給一個變量時都使用引用運算符 &

Example #3 從函數返回一個引用

<?php
function &returns_reference()
{
    return $someref;
}

$newref =& returns_reference();
?>

可變函數

PHP 支持可變函數的概念。這意味着若是一個變量名後有圓括號,PHP 將尋找與變量的值同名的函數,而且嘗試執行它。可變函數能夠用來實現包括回調函數,函數表在內的一些用途。

可變函數不能用於例如 echoprintunset()isset()empty()includerequire 以及相似的語言結構。須要使用本身的包裝函數來將這些結構用做可變函數。

當調用靜態方法時,函數調用要比靜態屬性優先

Example #3 Variable 方法和靜態屬性示例

<?php
class Foo
{
    static $variable = 'static property';
    static function Variable() {
        echo 'Method Variable called';
    }
}

echo Foo::$variable; // This prints 'static property'. It does need a $variable in this scope.
$variable = "Variable";
Foo::$variable();  // This calls $foo->Variable() reading $variable in this scope.

?>
As of PHP 5.4.0, you can call any callable stored in a variable.

Example #4 Complex callables

<?php
class Foo
{
    static function bar()
    {
        echo "bar\n";
    }
    function baz()
    {
        echo "baz\n";
    }
}

$func = array("Foo", "bar");
$func(); // prints "bar"
$func = array(new Foo, "baz");
$func(); // prints "baz"
$func = "Foo::bar";
$func(); // prints "bar" as of PHP 7.0.0; prior, it raised a fatal error
?>

匿名函數

匿名函數(Anonymous functions),也叫閉包函數(closures),容許 臨時建立一個沒有指定名稱的函數。最常常用做回調函數(callback)參數的值。固然,也有其它應用的狀況。

匿名函數目前是經過 Closure 類來實現的。

閉包能夠從父做用域中繼承變量。 任何此類變量都應該用 use 語言結構傳遞進去。 PHP 7.1 起,不能傳入此類變量: superglobals、 $this 或者和參數重名。

Example #3 從父做用域繼承變量(傳值傳引用

<?php
$message = 'hello';

// 沒有 "use"
$example = function () {
    var_dump($message);
};
echo $example();
//Notice: Undefined variable: message in /example.php on line 6
//NULL

// 繼承 $message
$example = function () use ($message) {
    var_dump($message);
};
echo $example();//string(5) "hello"

$message = 'world';
echo $example();//string(5) "hello"

// Reset message
$message = 'hello';

$example = function () use (&$message) {
    var_dump($message);
};
echo $example();//string(5) "hello"

$message = 'world';
echo $example();//string(5) "world"

// Closures can also accept regular arguments
$example = function ($arg) use ($message) {
    var_dump($arg . ' ' . $message);
};
$example("hello");//string(11) "hello world"
?>

閉包中 $this 的綁定

<?php

class Test
{
    public function testing()
    {
        return function() {
            var_dump($this);
        };
    }
    public function testing2()
    {
        return static function() {
            var_dump($this);
        };
    }
}

$object = new Test;
$function = $object->testing();
$function();
$object->testing2()();
?>

以上例程會輸出(PHP 5.4+):

object(Test)#1 (0) {
}
PHP Notice:  Undefined variable: this in D:\php\test\test.php on line 13

Notice: Undefined variable: this in D:\php\test\test.php on line 13
NULL

而在PHP 5.3中:

PHP Notice:  Undefined variable: this in D:\php\test\test.php on line 7

Notice: Undefined variable: this in D:\php\test\test.php on line 7
NULL

PHP Parse error:  syntax error, unexpected T_FUNCTION, expecting T_PAAMAYIM_NEKUDOTAYIM in D:\php\test\test.php on line 12

Parse error: syntax error, unexpected T_FUNCTION, expecting T_PAAMAYIM_NEKUDOTAYIM in D:\php\test\test.php on line 12
Note: 能夠在閉包中使用 func_num_args(),func_get_arg() 和 func_get_args()。

函數處理 函數

相關文章
相關標籤/搜索