การโทรกลับเขียนด้วย PHP เป็นอย่างไร?
การโทรกลับเขียนด้วย PHP เป็นอย่างไร?
คำตอบ:
คู่มือใช้คำว่า "callback" และ "callable" สลับกันได้อย่างไรก็ตาม "callback" ตามธรรมเนียมอ้างถึงสตริงหรือค่าอาร์เรย์ที่ทำหน้าที่เหมือนตัวชี้ฟังก์ชั่นการอ้างอิงฟังก์ชั่นหรือวิธีการเรียนสำหรับการร้องขอในอนาคต สิ่งนี้ได้อนุญาตให้องค์ประกอบบางส่วนของการเขียนโปรแกรมการทำงานตั้งแต่ PHP 4 รสชาติคือ:
$cb1 = 'someGlobalFunction';
$cb2 = ['ClassName', 'someStaticMethod'];
$cb3 = [$object, 'somePublicMethod'];
// this syntax is callable since PHP 5.2.3 but a string containing it
// cannot be called directly
$cb2 = 'ClassName::someStaticMethod';
$cb2(); // fatal error
// legacy syntax for PHP 4
$cb3 = array(&$object, 'somePublicMethod');
นี่เป็นวิธีที่ปลอดภัยในการใช้ค่าที่เรียกใช้ได้โดยทั่วไป:
if (is_callable($cb2)) {
// Autoloading will be invoked to load the class "ClassName" if it's not
// yet defined, and PHP will check that the class has a method
// "someStaticMethod". Note that is_callable() will NOT verify that the
// method can safely be executed in static context.
$returnValue = call_user_func($cb2, $arg1, $arg2);
}
รุ่นที่ทันสมัย PHP $cb()
อนุญาตให้สามรูปแบบดังกล่าวข้างต้นเป็นครั้งแรกที่จะเรียกโดยตรงเป็น call_user_func
และcall_user_func_array
สนับสนุนทั้งหมดข้างต้น
ดู: http://php.net/manual/th/language.types.callable.php
Notes / เตือน:
['Vendor\Package\Foo', 'method']
call_user_func
ไม่รองรับการส่งข้อมูลที่ไม่ใช่วัตถุโดยการอ้างอิงดังนั้นคุณสามารถใช้call_user_func_array
หรือในเวอร์ชัน PHP ในภายหลังให้บันทึกการเรียกกลับไปยัง var และใช้ไวยากรณ์โดยตรง: $cb()
;__invoke()
วิธีการ (รวมถึงฟังก์ชั่นที่ไม่ระบุชื่อ) อยู่ภายใต้หมวดหมู่ "callable" และสามารถใช้วิธีเดียวกันได้ แต่โดยส่วนตัวแล้วฉันไม่ได้เชื่อมโยงสิ่งเหล่านี้กับคำว่า "callback" แบบดั้งเดิมcreate_function()
สร้างฟังก์ชันสากลและส่งกลับชื่อ มันเป็นเสื้อคลุมeval()
และฟังก์ชั่นที่ไม่ระบุชื่อควรใช้แทน'someGlobalFunction'
แน่นอนเป็นหน้าที่ที่กำหนดไว้
ด้วย PHP 5.3 คุณสามารถทำสิ่งนี้ได้:
function doIt($callback) { $callback(); }
doIt(function() {
// this will be done
});
ในที่สุดก็เป็นวิธีที่ดีที่จะทำ นอกจากนี้ยังยอดเยี่ยมสำหรับ PHP เพราะการโทรกลับนั้นยอดเยี่ยม
การดำเนินการติดต่อกลับจะทำเช่นนั้น
// This function uses a callback function.
function doIt($callback)
{
$data = "this is my data";
$callback($data);
}
// This is a sample callback function for doIt().
function myCallback($data)
{
print 'Data is: ' . $data . "\n";
}
// Call doIt() and pass our sample callback function's name.
doIt('myCallback');
แสดง: ข้อมูลคือ: นี่คือข้อมูลของฉัน
call_user_func()
เมื่อมีไวยากรณ์ซึ่งทำให้พวกเขาสามารถเรียกใช้ฟังก์ชันและทำการโทรกลับได้ ฉันเห็นด้วยกับคุณ!
เคล็ดลับที่ดีอย่างหนึ่งที่ฉันได้พบเมื่อเร็ว ๆ นี้คือการใช้ PHP create_function()
เพื่อสร้างฟังก์ชั่นนิรนาม / แลมบ์ดาสำหรับการใช้งานครั้งเดียว มันมีประโยชน์สำหรับการทำงาน PHP ชอบarray_map()
, preg_replace_callback()
หรือusort()
ที่เรียกกลับใช้สำหรับการประมวลผลที่กำหนดเอง ดูเหมือนว่าจะeval()
อยู่ภายใต้การคุ้มครอง แต่ก็ยังเป็นวิธีการใช้งาน PHP ที่ดี
create_function()
หรือไม่?
ดี ... ด้วย 5.3 บนขอบฟ้าทุกอย่างจะดีขึ้นเพราะด้วย 5.3 เราจะได้ปิดและด้วยฟังก์ชั่นนิรนาม
คุณจะต้องยืนยันว่าการโทรของคุณนั้นถูกต้องหรือไม่ ตัวอย่างเช่นในกรณีของฟังก์ชั่นที่เฉพาะเจาะจงคุณจะต้องตรวจสอบและดูว่าฟังก์ชั่นที่มีอยู่:
function doIt($callback) {
if(function_exists($callback)) {
$callback();
} else {
// some error handling
}
}
is_callable( $callback )
create_function
ไม่ได้ผลสำหรับฉันในชั้นเรียน call_user_func
ผมต้องใช้
<?php
class Dispatcher {
//Added explicit callback declaration.
var $callback;
public function Dispatcher( $callback ){
$this->callback = $callback;
}
public function asynchronous_method(){
//do asynch stuff, like fwrite...then, fire callback.
if ( isset( $this->callback ) ) {
if (function_exists( $this->callback )) call_user_func( $this->callback, "File done!" );
}
}
}
จากนั้นใช้:
<?php
include_once('Dispatcher.php');
$d = new Dispatcher( 'do_callback' );
$d->asynchronous_method();
function do_callback( $data ){
print 'Data is: ' . $data . "\n";
}
?>
[แก้ไข] เพิ่มวงเล็บที่ขาดหายไป นอกจากนี้ยังเพิ่มการประกาศโทรกลับฉันชอบมันมาก
ฉันประจบประแจงทุกครั้งที่ฉันใช้ create_function()
ใน PHP
พารามิเตอร์เป็นสตริงที่คั่นด้วยโคม่าตัวฟังก์ชันทั้งหมดในสตริง ... เอ๊ะ ... ฉันคิดว่าพวกเขาไม่สามารถทำให้มันน่าเกลียดได้แม้ว่าพวกเขาจะพยายาม
น่าเสียดายที่มันเป็นทางเลือกเดียวเมื่อสร้างฟังก์ชั่นที่ตั้งชื่อไว้ไม่คุ้มค่ากับปัญหา
create_function()
เลิกใช้แล้วและไม่ควรใช้
สำหรับผู้ที่ไม่สนใจเกี่ยวกับความเข้ากันได้กับ PHP < 5.4
ฉันขอแนะนำให้ใช้การบอกกล่าวแบบเพื่อทำให้การใช้งานมีความสะอาดยิ่งขึ้น
function call_with_hello_and_append_world( callable $callback )
{
// No need to check $closure because of the type hint
return $callback( "hello" )."world";
}
function append_space( $string )
{
return $string." ";
}
$output1 = call_with_hello_and_append_world( function( $string ) { return $string." "; } );
var_dump( $output1 ); // string(11) "hello world"
$output2 = call_with_hello_and_append_world( "append_space" );
var_dump( $output2 ); // string(11) "hello world"
$old_lambda = create_function( '$string', 'return $string." ";' );
$output3 = call_with_hello_and_append_world( $old_lambda );
var_dump( $output3 ); // string(11) "hello world"
create_function()
เลิกใช้แล้วตั้งแต่ PHP 7.2.0 การใช้ฟังก์ชั่นนี้เป็นสิ่งที่ท้อแท้อย่างมาก