Làm cách nào để thực thi ngay một hàm ẩn danh trong PHP?


96

Trong JavaScript, bạn có thể xác định các hàm ẩn danh được thực thi ngay lập tức:

(function () { /* do something */ })()

Bạn có thể làm điều gì đó tương tự trong PHP không?


2
Tôi không có php 5.3 trên tay để thử, nhưng làm thế nào để call_user_func(function(){/* stuff */})làm?
Jasper

Câu trả lời:


120

Đối với PHP7: xem câu trả lời của Yasuo Ohgaki :(function() {echo 'Hi';})();

Đối với các phiên bản trước: cách duy nhất để thực thi chúng ngay lập tức mà tôi có thể nghĩ đến là

call_user_func(function() { echo 'executed'; });

12
Trừ khi (hoặc, cho đến khi) chuỗi cuộc gọi hàm được giới thiệu, đây cũng sẽ là gợi ý của tôi.
chào đón

2
@Gordon: php 5.4 vẫn không có gì?
năng động

@ yes123 nope. vẫn phải sử dụngcall_user_func
Gordon

2
@BennettMcElwee hãy nói theo cách này: ngay cả khi điều này hoạt động hơi chậm hơn so với phương pháp xác định-gán-cuộc gọi, khả năng điều này gây ra một nút cổ chai đáng kể trong ứng dụng của bạn là rất thấp. khi nghi ngờ cấu hình ứng dụng của bạn trong điều kiện thế giới thực.
Gordon

Cảm ơn @Gordon, đó là những gì tôi nghĩ. Tôi có ấn tượng rằng salathe và yes123 không hài lòng với phương pháp này, và tôi tự hỏi tại sao. Có vẻ như hoàn toàn ổn đối với tôi.
Bennett McElwee

28

Trong PHP 7là làm tương tự trong javascript

$gen = (function() {
    yield 1;
    yield 2;

    return 3;
})();

foreach ($gen as $val) {
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;

Đầu ra là:

1
2
3

15

Tất nhiên bạn có thể sử dụng call_user_func, nhưng vẫn có một giải pháp thay thế khá đơn giản khác:

<?php
// we simply need to write a simple function called run:
function run($f){
    $f();
}

// and then we can use it like this:
run(function(){
    echo "do something";
});

?>

1
Tôi muốn một hàm thực thi ngay lập tức, vì hàm mà tôi đang xác định là một hàm mà SHOULDN KHÔNG được gọi nhiều lần trong quá trình thực thi bình thường. Vấn đề với việc xác định một hàm được đặt tên, run (), giống như bạn gặp phải, là bất kỳ ai khác nhìn thấy mã có thể nghĩ rằng họ cũng có thể gọi run () trong một số phần khác của mã. Hàm thực thi ngay lập tức làm rõ rằng mã này không nên chạy hai lần.
Daniel Howard

3
Họ không thể gọi runhàm của bạn trong một số phần khác của mã vì không có xử lý nào đối với hàm của bạn tồn tại sau dòng ngay lập tức thực thi nó.
Pacerier

3
@DanielHoward Điểm của run()là thực thi ngay lập tức hàm không tên được chuyển cho nó. Giống như call_user_func(), chỉ không có tham số nào được truyền.
Cypher

1
@JordanLev, Nó có cách triển khai đơn giản hơn (chỉ một dòng $f();:) và có thể nhanh hơn nếu công cụ bạn sử dụng không tối ưu hóa cho trường hợp đặc biệt call_user_funcchỉ có một đối số hàm. Điều này là do call_user_funchỗ trợ truyền nhiều tham số và đối số đầu tiên của nó hỗ trợ một chuỗi như một đối số hoặc một hàm. Điều đó nói rằng, nếu call_user_funccó thể đọc được nhiều, tôi sẽ không sử dụng runtrừ khi mã nằm ở đâu đó ở dưới cùng của pyramind .
Pacerier

1
@JordanLev, "triển khai đơn giản hơn" đề cập đến sự so sánh giữa mã bên trong các hàm runcall_user_func. call_user_funccó một bất lợi cố hữu khi so sánh với runbởi vì runchỉ làm một việc, trong khi call_user_funchỗ trợ các tính năng bổ sung ngoài việc làm những gì run. Bạn có thể thử kiểm tra vòng lặp nhanh ( ví dụ ) để xem động cơ của bạn chạy nhanh hơn.
Pacerier

11

Đây là cách đơn giản nhất cho PHP 7.0 trở lên.

php -r '(function() {echo 'Hi';})();'

Nó có nghĩa là tạo bao đóng, sau đó gọi nó dưới dạng hàm bằng cách theo sau "()". Hoạt động giống như JS nhờ thứ tự đánh giá biến đồng nhất.

https://3v4l.org/06EL3


2
Câu trả lời hay, nhưng tại sao bạn lại định dạng nó thành một thao tác dòng lệnh?
Kodos Johnson

6
(new ReflectionFunction(function() {
 // body function
}))->invoke();

6
bạn có thể cung cấp thêm chi tiết? có thể thêm một lời giải thích?
MoralCode

2

Lưu ý, câu trả lời được chấp nhận là tốt nhưng phải mất 1,41 lần (chậm hơn 41%) so với việc khai báo một hàm và gọi nó trong hai dòng.

[Tôi biết đó không hẳn là một câu trả lời mới nhưng tôi cảm thấy việc thêm câu trả lời này vào đâu đó cho khách truy cập là rất có giá trị.]

Chi tiết:

<?php
# Tags: benchmark, call_user_func, anonymous function 
require_once("Benchmark.php");
bench(array(
        'test1_anonfunc_call' => function(){
                $f = function(){
                        $x = 123;
                };
                $f();
        },
        'test2_anonfunc_call_user_func' => function(){
                call_user_func(
                        function(){
                                $x = 123;
                        }
                );
        }
), 10000);
?>

Các kết quả:

$ php test8.php
test1_anonfunc_call took 0.0081379413604736s (1228812.0001172/s)
test2_anonfunc_call_user_func took 0.011472940444946s (871616.13432805/s)

0

Tôi đã thử theo cách này, nhưng nó dài dòng hơn câu trả lời hàng đầu bằng cách sử dụng bất kỳ toán tử (hoặc hàm) nào cho phép bạn xác định hàm trước:

    $value = $hack == ($hack = function(){
            // just a hack way of executing an anonymous function
            return array(0, 1, 2, 3);                
    }) ? $hack() : $hack();

2
Vậy tại sao không đơn giản $hack = function(){...}; $hack()?

0

Đây không phải là một câu trả lời trực tiếp mà là một cách giải quyết. Sử dụng PHP> = 7. Định nghĩa một lớp ẩn danh với một phương thức được đặt tên và xây dựng lớp và gọi phương thức đó ngay lập tức.

$var = (new class() { // Anonymous class
    function cool() { // Named method
        return 'neato';
    }
})->cool(); // Instantiate the anonymous class and call the named method
echo $var; // Echos neato to console.

-2

Không được thực hiện ngay lập tức, nhưng gần;)

<?php

$var = (function(){ echo 'do something'; });
$var();

?>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.