ฉันมีฟังก์ชัน PHP ที่รับอาร์กิวเมนต์จำนวนตัวแปร (โดยใช้func_num_args()
และfunc_get_args()
) แต่จำนวนอาร์กิวเมนต์ที่ฉันต้องการส่งผ่านฟังก์ชันนั้นขึ้นอยู่กับความยาวของอาร์เรย์ มีวิธีการเรียกใช้ฟังก์ชัน PHP ด้วยอาร์กิวเมนต์กี่ตัวแปรหรือไม่?
ฉันมีฟังก์ชัน PHP ที่รับอาร์กิวเมนต์จำนวนตัวแปร (โดยใช้func_num_args()
และfunc_get_args()
) แต่จำนวนอาร์กิวเมนต์ที่ฉันต้องการส่งผ่านฟังก์ชันนั้นขึ้นอยู่กับความยาวของอาร์เรย์ มีวิธีการเรียกใช้ฟังก์ชัน PHP ด้วยอาร์กิวเมนต์กี่ตัวแปรหรือไม่?
คำตอบ:
หากคุณมีอาร์กิวเมนต์ในอาร์เรย์คุณอาจสนใจcall_user_func_array
ฟังก์ชัน
ถ้าจำนวนของการขัดแย้งที่คุณต้องการที่จะผ่านขึ้นอยู่กับความยาวของอาร์เรย์ก็อาจหมายความว่าคุณสามารถแพ็คพวกเขาเป็นอาร์เรย์ตัวเอง - call_user_func_array
และการใช้งานที่หนึ่งสำหรับพารามิเตอร์ที่สองของ
องค์ประกอบของอาร์เรย์ที่คุณส่งผ่านจะได้รับจากฟังก์ชันของคุณเป็นพารามิเตอร์ที่แตกต่างกัน
ตัวอย่างเช่นหากคุณมีฟังก์ชันนี้:
function test() {
var_dump(func_num_args());
var_dump(func_get_args());
}
คุณสามารถบรรจุพารามิเตอร์ของคุณลงในอาร์เรย์ได้ดังนี้:
$params = array(
10,
'glop',
'test',
);
จากนั้นเรียกใช้ฟังก์ชัน:
call_user_func_array('test', $params);
รหัสนี้จะส่งออก:
int 3
array
0 => int 10
1 => string 'glop' (length=4)
2 => string 'test' (length=4)
กล่าวคือ 3 พารามิเตอร์; เหมือนกับ iof ฟังก์ชันถูกเรียกด้วยวิธีนี้:
test(10, 'glop', 'test');
ตอนนี้สามารถทำได้ด้วย PHP 5.6.xโดยใช้ตัวดำเนินการ ... (หรือที่เรียกว่าตัวดำเนินการ Splat ในบางภาษา):
ตัวอย่าง:
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' ) );
ในPhp 5.6ใหม่คุณสามารถใช้... operator
แทนการใช้func_get_args()
.
ดังนั้นเมื่อใช้สิ่งนี้คุณจะได้รับพารามิเตอร์ทั้งหมดที่คุณส่งผ่าน:
function manyVars(...$params) {
var_dump($params);
}
ตั้งแต่PHP 5.6สามารถระบุรายการอาร์กิวเมนต์ตัวแปรกับตัว...
ดำเนินการได้
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)
#> }
ดังที่คุณเห็นตัว...
ดำเนินการรวบรวมรายการตัวแปรของอาร์กิวเมนต์ในอาร์เรย์
หากคุณต้องการส่งผ่านอาร์กิวเมนต์ของตัวแปรไปยังฟังก์ชันอื่นสิ่ง...
นี้ยังสามารถช่วยคุณได้
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);
}
ตั้งแต่PHP 7รายการตัวแปรของอาร์กิวเมนต์สามารถบังคับให้เป็นประเภทเดียวกันทั้งหมดได้เช่นกัน
function do_something($first, int ...$all_the_others) { /**/ }
สำหรับผู้ที่กำลังมองหาวิธีดำเนินการดังต่อไปนี้$object->method
:
call_user_func_array(array($object, 'method_name'), $array);
ฉันประสบความสำเร็จกับสิ่งนี้ในฟังก์ชันการสร้างที่เรียกตัวแปร method_name พร้อมพารามิเตอร์ตัวแปร
$object->method_name(...$array);
$object->method_name(&...$args);
คุณสามารถเรียกมัน
function test(){
print_r(func_get_args());
}
test("blah");
test("blah","blah");
เอาท์พุท:
อาร์เรย์ ([0] => blah) อาร์เรย์ ([0] => blah [1] => blah)
ฉันแปลกใจที่ไม่มีใครพูดถึงแค่การส่งผ่านและแยกอาร์เรย์ เช่น:
function add($arr){
extract($arr, EXTR_REFS);
return $one+$two;
}
$one = 1;
$two = 2;
echo add(compact('one', 'two')); // 3
ของหลักสูตรนี้ไม่ได้ให้ตรวจสอบการโต้แย้ง สำหรับสิ่งนั้นทุกคนสามารถใช้ฟังก์ชันคาดหวังของฉัน: https://gist.github.com/iautomation/8063fc78e9508ed427d5
อย่างไรก็ตามคำถามเก่า ๆ ฉันรู้ว่าไม่มีคำตอบใดที่จะตอบคำถามได้ดีจริงๆ
ฉันเพิ่งเล่นกับ php และโซลูชันมีลักษณะดังนี้:
function myFunction($requiredArgument, $optionalArgument = "default"){
echo $requiredArgument . $optionalArgument;
}
ฟังก์ชั่นนี้สามารถทำได้สองอย่าง:
หากเรียกด้วยพารามิเตอร์ที่ต้องการเท่านั้น: myFunction("Hi")
มันจะพิมพ์ "Hi default"
แต่ถ้ามันถูกเรียกด้วยพารามิเตอร์ทางเลือก: myFunction("Hi","me")
มันจะพิมพ์ "สวัสดีฉัน";
ฉันหวังว่านี่จะช่วยทุกคนที่กำลังมองหาสิ่งนี้อยู่ระหว่างทาง
นี่คือวิธีแก้ปัญหาโดยใช้วิธีมายากล __invoke
(ใช้ได้ตั้งแต่ 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){
}
}
จากภายในคลาสเดียวกัน:
$this('methodName', ['arg1', 'arg2', 'arg3']);
จากตัวอย่างของวัตถุ:
$obj = new Foo;
$obj('methodName', ['arg1', 'arg2', 'arg3'])
call_user_func_array
ตามที่ระบุไว้โดยคำตอบที่ได้รับการโหวตสูงสุดในปี 2009 บางทีอาจมีจุดที่ต้องห่อส่วนพิเศษไว้__invoke
รอบ ๆ - แต่ฉันไม่เห็นมัน