Tôi có một hàm PHP có số lượng đối số (sử dụng func_num_args()
và func_get_args()
) thay đổi, nhưng số lượng đối số tôi muốn truyền hàm phụ thuộc vào độ dài của một mảng. Có cách nào để gọi một hàm PHP với số lượng đối số thay đổi không?
Tôi có một hàm PHP có số lượng đối số (sử dụng func_num_args()
và func_get_args()
) thay đổi, nhưng số lượng đối số tôi muốn truyền hàm phụ thuộc vào độ dài của một mảng. Có cách nào để gọi một hàm PHP với số lượng đối số thay đổi không?
Câu trả lời:
Nếu bạn có các đối số của mình trong một mảng, bạn có thể quan tâm đến call_user_func_array
hàm.
Nếu số lượng đối số bạn muốn vượt qua phụ thuộc vào độ dài của một mảng, điều đó có thể có nghĩa là bạn có thể tự đóng gói chúng thành một mảng - và sử dụng đối số đó cho tham số thứ hai call_user_func_array
.
Các phần tử của mảng mà bạn vượt qua sau đó sẽ được hàm của bạn nhận dưới dạng các tham số riêng biệt.
Chẳng hạn, nếu bạn có chức năng này:
function test() {
var_dump(func_num_args());
var_dump(func_get_args());
}
Bạn có thể đóng gói các tham số của mình thành một mảng, như thế này:
$params = array(
10,
'glop',
'test',
);
Và, sau đó, gọi hàm:
call_user_func_array('test', $params);
Mã này sẽ xuất ra:
int 3
array
0 => int 10
1 => string 'glop' (length=4)
2 => string 'test' (length=4)
tức là 3 tham số; chính xác như iof, hàm được gọi theo cách này:
test(10, 'glop', 'test');
Điều này hiện có thể với PHP 5.6.x , sử dụng toán tử ... (còn được gọi là toán tử splat trong một số ngôn ngữ):
Thí dụ:
function addDateIntervalsToDateTime( DateTime $dt, DateInterval ...$intervals )
{
foreach ( $intervals as $interval ) {
$dt->add( $interval );
}
return $dt;
}
addDateIntervaslToDateTime( new DateTime, new DateInterval( 'P1D' ),
new DateInterval( 'P4D' ), new DateInterval( 'P10D' ) );
Trong Php 5.6 mới , bạn có thể sử dụng ... operator
thay vì sử dụng func_get_args()
.
Vì vậy, bằng cách sử dụng này, bạn có thể nhận được tất cả các tham số bạn vượt qua:
function manyVars(...$params) {
var_dump($params);
}
Kể từ PHP 5.6 , một danh sách đối số biến có thể được chỉ định với ...
toán tử.
function do_something($first, ...$all_the_others)
{
var_dump($first);
var_dump($all_the_others);
}
do_something('this goes in first', 2, 3, 4, 5);
#> string(18) "this goes in first"
#>
#> array(4) {
#> [0]=>
#> int(2)
#> [1]=>
#> int(3)
#> [2]=>
#> int(4)
#> [3]=>
#> int(5)
#> }
Như bạn có thể thấy, ...
toán tử thu thập danh sách các đối số biến trong một mảng.
Nếu bạn cần chuyển các đối số biến sang hàm khác, ...
vẫn có thể giúp bạn.
function do_something($first, ...$all_the_others)
{
do_something_else($first, ...$all_the_others);
// Which is translated to:
// do_something_else('this goes in first', 2, 3, 4, 5);
}
Kể từ PHP 7 , danh sách biến của các đối số có thể bị buộc phải tất cả cùng loại quá.
function do_something($first, int ...$all_the_others) { /**/ }
Đối với những người tìm kiếm một cách để làm điều này với $object->method
:
call_user_func_array(array($object, 'method_name'), $array);
Tôi đã thành công với điều này trong một hàm xây dựng gọi một phương thức tên biến với các tham số biến.
$object->method_name(...$array);
$object->method_name(&...$args);
Bạn chỉ có thể gọi nó.
function test(){
print_r(func_get_args());
}
test("blah");
test("blah","blah");
Đầu ra:
Mảng ([0] => blah) Mảng ([0] => blah [1] => blah)
Tôi ngạc nhiên không ai ở đây đã đề cập chỉ đơn giản là vượt qua và trích xuất một mảng. Ví dụ:
function add($arr){
extract($arr, EXTR_REFS);
return $one+$two;
}
$one = 1;
$two = 2;
echo add(compact('one', 'two')); // 3
Tất nhiên, điều này không cung cấp xác nhận đối số . Vì thế, bất cứ ai cũng có thể sử dụng chức năng mong đợi của tôi: https://gist.github.com/iautomation/8063fc78e9508ed427d5
Một câu hỏi cũ, tôi biết, tuy nhiên, không có câu trả lời nào ở đây thực sự làm tốt công việc chỉ đơn giản là trả lời câu hỏi.
Tôi chỉ chơi xung quanh với php và giải pháp trông như thế này:
function myFunction($requiredArgument, $optionalArgument = "default"){
echo $requiredArgument . $optionalArgument;
}
Hàm này có thể làm hai việc:
Nếu nó được gọi chỉ với tham số bắt buộc: myFunction("Hi")
Nó sẽ in "Hi default"
Nhưng nếu nó được gọi với tham số tùy chọn: myFunction("Hi","me")
Nó sẽ in "Hi me";
Tôi hy vọng điều này sẽ giúp bất cứ ai đang tìm kiếm điều này trên đường.
Đây là một giải pháp sử dụng phương thức ma thuật __invoke
(Có sẵn từ php 5.3)
class Foo {
public function __invoke($method=null, $args=[]){
if($method){
return call_user_func_array([$this, $method], $args);
}
return false;
}
public function methodName($arg1, $arg2, $arg3){
}
}
Từ trong cùng một lớp:
$this('methodName', ['arg1', 'arg2', 'arg3']);
Từ một thể hiện của một đối tượng:
$obj = new Foo;
$obj('methodName', ['arg1', 'arg2', 'arg3'])
call_user_func_array
như đã nêu bởi câu trả lời được bình chọn hàng đầu trong năm 2009. Có thể có một điểm để gói thêm một phần __invoke
xung quanh nó - nhưng tôi không thấy nó.