2009-10-16 31 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); 
?>