2011-08-11 32 views
9

Tôi có hàm php có số lượng arg không giới hạn mà tôi nhận được từ func_get_args(). Tôi có một số hoạt động với các đối số (thay đổi chuỗi hoặc làm một cái gì đó) và tôi muốn điều này giống như một đối số đi qua tham chiếu. là nó có thể?cách vượt qua đối số không giới hạn bằng cách tham chiếu trong php

dụ:

$test = 'foo'; 
$test2 = 'bar'; 

function test(){ 
    $args = func_get_args(); 
    foreach($args as $arg) 
     $arg .= 'baz'; 
} 

test($test, $test2); 
+0

có thể trùng lặp của [PHP: chiều dài thay đổi danh sách đối số bằng cách tham khảo] (http://stackoverflow.com/questions/1925253/php-variable-length-argument-list-by-reference) –

Trả lời

4

Tôi rất nghi ngờ đó là có thể, nhưng tôi biết một cách để bạn có thể có được những gì bạn muốn:

function test(&$args) { 
    foreach ($args as $arg) { 
     $arg .= 'baz'; 
    } 
} 

test(array(&$test, &$test2)); 
+0

Nó có vẻ như chúng ta sẽ sớm có thể làm điều này bằng cách sử dụng toán tử '...' mới trong PHP 5.6. –

1

này hoạt động:

$test = 'foo'; 
$test2 = 'bar'; 

function test(){ 
    $backtrace = debug_backtrace(); 
    foreach($backtrace[0]['args'] as &$arg) 
     $arg .= 'baz'; 
} 

test(&$test, &$test2); 

Tuy nhiên , điều này sử dụng thời gian gọi qua tham chiếu không được chấp nhận.

+0

Không được phép ở tất cả trong PHP 5.4+ –

12

Như được trả lời trong PHP: variable-length argument list by reference?, không có cách nào trong PHP để kết hợp độ dài biến và vượt qua bởi đối số hàm tham chiếu. Thay vào đó, câu trả lời được liên kết sử dụng một hack tuyên bố 100 &argx s, sau đó sử dụng get_num_args() để tìm ra số lượng đã thực sự được sử dụng. Xin chúc mừng, bạn đã tìm thấy một góc đặc biệt khó khăn trong PHP;)

0

Tôi cũng cần chức năng này, tôi đã đưa ra giải pháp.

function sayhello($params) { 
    //params hold an unlimited amount of references 
} 

sayhello([&$one, &$two]); 

Điều này tùy thuộc vào php> = 5.4. Nếu bạn đang sử dụng < = 5.4, hãy sử dụng cú pháp mảng() thay vì [].

Tôi yêu [] tho, tốt hơn nhiều :)

+1

Bạn truyền chính xác một đối số là một mảng (và làm việc bên cạnh cú pháp đó trong

0

Sử dụng đối tượng là giải pháp

class O { 
    public $v; 
    public function __construct(&$p){ 
     $this->v = &$p; 
    } 
} 

function append_baz_to_all(){ 
    foreach(func_get_args() as &$arg){ 
     $arg->v .= 'baz'; 
    } 
} 

function test1(){ 
    echo "test1\n"; 
    $a='A';$b='B';$c='C';$d='D';$e='E';$f='F';$g='G'; 
    echo("\$a=$a \$b=$b \$c=$c \$d=$d \$e=$e \$f=$f \$g=$g\n"); 
    append_baz_to_all(new O($a), new O($b)); 
    echo("\$a=$a \$b=$b \$c=$c \$d=$d \$e=$e \$f=$f \$g=$g\n\n"); 
} 

//shortcutting 
function o(&$v){return new O($v);} 

function test2(){ 
    echo "test2\n"; 
    $a='A';$b='B';$c='C';$d='D';$e='E';$f='F';$g='G'; 
    echo("\$a=$a \$b=$b \$c=$c \$d=$d \$e=$e \$f=$f \$g=$g\n"); 
    append_baz_to_all(o($c), o($d), o($e)); 
    echo("\$a=$a \$b=$b \$c=$c \$d=$d \$e=$e \$f=$f \$g=$g\n\n"); 
} 


test1(); 
test2(); 
7

Kể từ PHP-5.6 bạn có thể sử dụng một tài liệu tham khảo variadic:

function test(&...$args) { 
    foreach ($args as &$arg) { 
     $arg .= 'baz'; 
    } 
} 
+0

Hỗ trợ hoàn hảo và 5,6, không thể yêu câu trả lời này nhiều hơn, cảm ơn bạn đã cập nhật! –

0
function byref_alias() 
{ 
//$argz=func_get_args(); //byval, not what you want 
$argz=debug_backtrace()[0]['args']; //byref hack 
$argz[0]++; works 
} 
+0

Hãy nhớ rằng mặc dù các đối số này là byreference, chúng không sửa đổi đối số ban đầu được gửi đến hàm, nhưng chúng sẽ được gửi bởi byreference. – AbiusX

0

Làm việc tốt cho tôi khi làm một cái gì đó giống như ví dụ dưới đây. Tôi nghĩ rằng chìa khóa là thiết lập các tài liệu tham khảo trong foreach.

$var1 = '%DIR%/test'; 

replaceParameters(
    $var1, 
    $var2, 
    $var3 
); 

function replaceParameters(&$variables) { 

    $variables = array_filter(func_get_args()); 

    $parameters = [ 
     '%DIR%' => __DIR__, 
     '%FILE%' => __FILE__, 
    ]; 

    foreach($variables as &$variable) { 
     $variable = str_replace(array_keys($parameters), array_values($parameters), $variable); 
    } 

} 
Các vấn đề liên quan