2009-10-16 35 views
16

如何編寫可以接受無限數量參數的函數?具有無限數量參數的PHP函數

什麼我試圖做的是一個封裝下面一個類中創建一個函數:

$stmt->bind_param('sssd', $code, $language, $official, $percent); 
+0

你離不開辛苦努力做到這一點。我建議或者建立一個查詢通常的方式,或者如果你想不惜任何代價的本地準備的語句移動到PDO。他們有綁定價值,介意你 – 2013-01-31 17:00:28

+0

感謝您的信息。不幸的是,與編寫我自己簡單的東西相比,PDO似乎是過度殺傷,更加努力和樣板。 – 2013-01-31 17:02:44

+0

對於簡單的東西,你可以使用我的用戶信息庫。儘管這很簡單。 – 2013-01-31 17:11:26

回答

4

以上建議都是不錯的,但我不認爲他們會適合你的情況。

$stmt->bind_param('sssd', $code, $language, $official, $percent); 

如果你想換這個功能,你需要傳遞給bind_param功能引用原來的參數變量。我不認爲func_get_args()給你這個,它給你的值而不是。因此將不可能使用這些傳遞給父函數。在嘗試擴展mysqli_stmt時,我遇到了類似的問題,但從未達到滿意的解決方案。

這恐怕不是您的問題的答案,我只是警告說其他參數可能無法在您的特定應用程序的任意數量的參數中工作。

+1

確實。我上次檢查(1年前)沒有辦法包裝/擴展'bind_param()',因爲'func_get_args()'不會返回引用。 – 2009-10-16 13:50:39

23

你已經採取了看func_get_argsfunc_get_argfunc_num_args

因此,例如:

function foo(){ 
    if (func_num_args() > 0){ 
     var_dump(func_get_args()); 
    } 
} 

或者:

function bind_param(){ 
    if (func_num_args() <= 1){ 
     return false; //not enough args 
    } 
    $format = func_get_arg(0) 
    $args = array_slice(func_get_args(), 1) 

    //etc 
} 

編輯
關於伊萬Todds評論:
我沒有你正在製作包裝基本的API的任何knowlege,但另一個選擇可能是做鏈接功能的東西,所以你得到的界面看上去是這樣的:

$var->bind()->bindString($code) 
      ->bindString($language) 
      ->bindString($official) 
      ->bindDecimal($percent); 

哪我寧願在使用func_get_args作爲代碼的可能是更具可讀性和更重要的是不太可能導致由於缺乏格式變量的錯誤。

+0

我不時地使用func_get_args。它難以一目瞭然地看到該方法的輸入是什麼。另外,它在你的代碼中引入了一個蹩腳的醜陋語法塊。我會推薦這種方法只是作爲最後的手段。首選參數對象重構。 – 2009-10-16 11:38:51

+0

我同意你這是做可變參數的不好的方法。我在回答中添加了另一個想法 – Yacoby 2009-10-16 11:56:07

+0

我比「func_get_args」更喜歡「鏈接函數」提案。我知道這個設計是FLUENT接口。它是通過bindString(),bindDecimal()等完成的「返回$ this;」作爲他們的最後一行。 FLUENT界面是cetain類型工廠的理想選擇。 – 2009-10-16 12:10:31

0

有一個叫func_get_args()的函數,它是傳遞給函數的所有參數的數組。從PHP.net

function foo() 
{ 
    $numargs = func_num_args(); 
    echo "Number of arguments: $numargs<br />\n"; 
    if ($numargs >= 2) { 
     echo "Second argument is: " . func_get_arg(1) . "<br />\n"; 
    } 
    $arg_list = func_get_args(); 
    for ($i = 0; $i < $numargs; $i++) { 
     echo "Argument $i is: " . $arg_list[$i] . "<br />\n"; 
    } 
} 

foo(1, 2, 3); 

上面的示例將輸出:

數目的參數:3
第二個參數是:2
參數0是:1個
參數1是:2
參數2是:3

5

使用func_get_args()

function my_func() { 
    $args = func_get_args(); 
    foreach ($args as $arg) { 
    echo "Arg: $arg\n"; 
    } 
} 
+0

如果未設置參數,則這不起作用,然後通過引用傳遞,以在函數內部進行設置。 func_get_args嘗試訪問引發錯誤的未設置變量。 – Danack 2013-01-12 02:15:08

0

func_get_args()的答案對於非參考參數可以很好地工作。 但是,通過參考傳遞參數的工作有一個技巧。 此外,它在技術上不是一個函數,它接受無限制的參數,而只是一些任意大的數字,例如一百個。

你可以做的是定義一個函數,它需要大量的參數,並且默認爲null。 然後,在該函數內部,將每個非空引用附加到一個數組,然後使用* call_user_func_array()*調用* bind_param()*。

function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...) 
{ 
    $vars = array($types); 
    $vars[] = $arg1; 

    if ($arg2 != null) 
     $vars[] = &$arg2; 
    if ($arg3 != null) 
     $vars[] = &$arg3; 
    ... 

    if (!call_user_func_array(array($stmt, "bind_param"), $vars)) 
    { 
     if ($stmt->errno == 0) 
      return array(-1, "Unknown error binding parameters."); 
     else 
      return array(-1, "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error); 
    } 

    return array(0, ""); 
} 

真正的訣竅是你不想親手寫這個東西。 只需製作另一個腳本,它將輸出此函數的主體(所有字形在括號中)作爲* my_bind_param_body.php *。 然後,只需在主文件中定義該函數的標題,並將該正文包含到該函數定義中。 即

function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...) 
{ 
    return include "my_bind_param_wrapper_body.php"; 
} 
8

以前,你應該使用func_get_args(),但在PHP 5.6,您可以使用... operator

因此,例如,你可以寫返回您所有的號碼,發送給函數的總和功能:

function bind_param(...$params){ 
    var_dump($params); 
} 

params實際上是所有元素的數組。

2

如果您使用PHP 5.6或更高版本,參數列表可能包括...標記以表示函數接受可變數量的參數。參數將作爲一個數組傳遞給給定的變量;只需使用...您可以訪問無限可變參數。

例如:

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

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

如果您正在使用PHP版本< = 5.5即可進入無限parameterusing的func_num_args()func_get_arg()func_get_args()功能。

例如:

<?php 
function foo() 
{ 
    $numargs = func_num_args(); 
    echo "Number of arguments: $numargs \n"; 
    if ($numargs >= 2) { 
     echo "Second argument is: " . func_get_arg(1) . "\n"; 
    } 
    $arg_list = func_get_args(); 
    for ($i = 0; $i < $numargs; $i++) { 
     echo "Argument $i is: " . $arg_list[$i] . "\n"; 
    } 
} 

foo(1, 2, 3); 
?>