Các cuộc gọi lại được viết bằng PHP như thế nào?
Các cuộc gọi lại được viết bằng PHP như thế nào?
Câu trả lời:
Hướng dẫn sử dụng các thuật ngữ "gọi lại" và "có thể gọi được" có thể hoán đổi cho nhau, tuy nhiên, "gọi lại" theo truyền thống đề cập đến một giá trị chuỗi hoặc mảng hoạt động như một con trỏ hàm , tham chiếu một phương thức hàm hoặc lớp để gọi trong tương lai. Điều này đã cho phép một số yếu tố của lập trình chức năng kể từ PHP 4. Các hương vị là:
$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');
Đây là một cách an toàn để sử dụng các giá trị có thể gọi được nói chung:
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);
}
Các phiên bản PHP hiện đại cho phép ba định dạng đầu tiên ở trên được gọi trực tiếp dưới dạng $cb()
. call_user_func
và call_user_func_array
hỗ trợ tất cả các bên trên.
Xem: http://php.net/manual/en/lingu.types.callable.php
Ghi chú / Hãy cẩn thận:
['Vendor\Package\Foo', 'method']
call_user_func
không hỗ trợ chuyển các đối tượng không theo tham chiếu, vì vậy bạn có thể sử dụng call_user_func_array
hoặc, trong các phiên bản PHP sau này, lưu cuộc gọi lại vào một var và sử dụng cú pháp trực tiếp : $cb()
;__invoke()
phương thức (bao gồm các hàm ẩn danh) thuộc danh mục "có thể gọi được" và có thể được sử dụng theo cùng một cách, nhưng cá nhân tôi không liên kết chúng với thuật ngữ "gọi lại" cũ.create_function()
tạo ra một chức năng toàn cầu và trả về tên của nó. eval()
Thay vào đó, nên sử dụng trình bao bọc cho và các hàm ẩn danh.'someGlobalFunction'
thực sự là một hàm xác định.
Với PHP 5.3, bây giờ bạn có thể làm điều này:
function doIt($callback) { $callback(); }
doIt(function() {
// this will be done
});
Cuối cùng là một cách tốt đẹp để làm điều đó. Một bổ sung tuyệt vời cho PHP, bởi vì các cuộc gọi lại là tuyệt vời.
Thực hiện một cuộc gọi lại được thực hiện như vậy
// 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');
Hiển thị: Dữ liệu là: đây là dữ liệu của tôi
call_user_func()
Khi họ có một cú pháp cho phép họ tự động gọi các hàm và thực hiện các cuộc gọi lại. Tôi đồng ý với bạn!
Một mẹo tiện lợi mà gần đây tôi đã tìm thấy là sử dụng PHP create_function()
để tạo một hàm ẩn danh / lambda để sử dụng một lần. Nó rất hữu ích cho các PHP functions như array_map()
, preg_replace_callback()
hoặc usort()
rằng callbacks sử dụng để chế biến tùy chỉnh. Nó trông khá giống như nó thực hiện eval()
dưới vỏ bọc, nhưng nó vẫn là một cách tốt để sử dụng PHP.
create_function()
?
tốt ... với 5.3 trên đường chân trời, tất cả sẽ tốt hơn, bởi vì với 5.3, chúng ta sẽ có được các bao đóng và với chúng là các hàm ẩn danh
Bạn sẽ muốn xác minh bất cứ điều gì cuộc gọi của bạn là hợp lệ. Ví dụ: trong trường hợp của một chức năng cụ thể, bạn sẽ muốn kiểm tra và xem liệu chức năng đó có tồn tại không:
function doIt($callback) {
if(function_exists($callback)) {
$callback();
} else {
// some error handling
}
}
is_callable( $callback )
create_function
đã không làm việc cho tôi trong một lớp học. Tôi đã phải sử dụng 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!" );
}
}
}
Sau đó, để sử dụng:
<?php
include_once('Dispatcher.php');
$d = new Dispatcher( 'do_callback' );
$d->asynchronous_method();
function do_callback( $data ){
print 'Data is: ' . $data . "\n";
}
?>
[Chỉnh sửa] Đã thêm dấu ngoặc đơn bị thiếu. Ngoài ra, thêm khai báo gọi lại, tôi thích nó theo cách đó.
Tôi co rúm mỗi khi tôi sử dụng create_function()
trong php.
Các tham số là một chuỗi tách biệt hôn mê, toàn bộ cơ thể chức năng trong một chuỗi ... Argh ... Tôi nghĩ rằng họ không thể làm cho nó xấu hơn ngay cả khi họ đã thử.
Thật không may, đó là lựa chọn duy nhất khi tạo một chức năng được đặt tên không đáng để gặp rắc rối.
create_function()
hiện không được dùng nữa và không nên sử dụng
Đối với những người không quan tâm đến việc phá vỡ tính tương thích với PHP < 5.4
, tôi khuyên bạn nên sử dụng gợi ý loại để thực hiện sạch hơn.
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()
đã được ĐỔI kể từ phiên bản PHP 7.2.0. Dựa vào chức năng này là rất nản lòng.