php is_ functions () để xác định xem một biến có phải là một hàm hay không


88

Tôi rất thích thú khi đọc về các hàm ẩn danh trong php, cho phép bạn khai báo một biến là hàm dễ dàng hơn so với việc bạn có thể làm với create_ functions . Giờ em đang thắc mắc không biết hàm bị truyền một biến thì làm cách nào để kiểm tra xác định đó có phải là hàm không? Chưa có hàm is_ functions () và khi tôi thực hiện var_dump cho một biến là một hàm ::

$func = function(){
    echo 'asdf';
};
var_dump($func);

Tôi hiểu điều này:

object(Closure)#8 (0) { } 

Bất kỳ suy nghĩ về cách kiểm tra xem đây có phải là một chức năng không?

Câu trả lời:


139

Sử dụng is_callableđể xác định xem một biến đã cho có phải là một hàm hay không. Ví dụ:

$func = function()
{  
    echo 'asdf';  
};

if( is_callable( $func ) )
{
    // Will be true.
}

10
is_callable () sẽ hoạt động tốt cho dù bạn đang truyền một hàm ẩn danh, một tên hàm dưới dạng một chuỗi hoặc một mảng gọi lại PHP hợp lệ. Nếu bạn đặc biệt chỉ muốn kiểm tra các hàm ẩn danh, thì bạn sẽ muốn một cái gì đó giống như những gì Gumbo đã nói: hãy đảm bảo rằng tham số là một đối tượng và đảm bảo nó là một instanceof Closure.
Lane

2
Điều gì sẽ xảy ra nếu tôi muốn kiểm tra ướt hơn đó là một callack hay một chuỗi và làm những việc khác cho chúng. Tôi không muốn một giá trị chuỗi vô tình bị lấy làm một lệnh gọi lại.
Gherman,

2
@German Chỉ cần kiểm tra đầu tiên nếu is_string ($ func) sau đó là séc thứ hai với is_callable ($ func)
Heroselohim

4
Đoạn mã trên đã khiến tôi gặp rắc rối. Tôi dự định một chuỗi có nhãn "Ngày" và sau đó nó được xử lý như một chuỗi đóng và được thực thi. Cách đúng là if (($ variable instanceof Closure) && is_callable ($ variable)) {...}
Basil Musa

1
Tại sao trường hợp của bao đóng AND có thể gọi được. Khi nào thì không gọi được đóng cửa? Sẽ không ngạc nhiên nếu có lúc, nhưng tôi tò mò tại sao chúng ta cần cả hai séc.
Joel M

34

Bạn có thể sử dụng function_existsđể kiểm tra có một chức năng với tên đã cho. Và để kết hợp điều đó với các chức năng ẩn danh, hãy thử điều này:

function is_function($f) {
    return (is_string($f) && function_exists($f)) || (is_object($f) && ($f instanceof Closure));
}

Cảm ơn vì điều đó! Ứng dụng của tôi cho phép người dùng chỉ định hàm băm của riêng họ hoặc cung cấp luân phiên một đối số cho hàm băm (). Nhưng một số thuật toán băm hợp lệ cũng là nội trang PHP và do đó có thể gọi được (ví dụ: 'md5', 'sha1'). is_object()instanceof Closurelà một cách mạnh mẽ hơn nhiều để kiểm tra điều này!
njbair 22/12/12

Loại bỏ các lệnh gọi is_string và function_exists và đây là hàm bạn muốn sử dụng để phát hiện các hàm lambda. Cảm ơn bạn!
jack

28

Nếu bạn chỉ muốn kiểm tra xem một biến có phải là một hàm ẩn danh và không phải là một chuỗi hoặc mảng có thể gọi hay không, hãy sử dụng instanceof.

$func = function()
{  
    echo 'asdf';  
};

if($func instanceof Closure)
{
    // Will be true.
}

Các hàm ẩn danh (thuộc loại đã được thêm vào trong PHP 5.3) luôn là các thể hiện của Closurelớp và mọi thể hiện của Closurelớp là một hàm ẩn danh.

Có một loại thứ khác trong PHP có thể được coi là một hàm, và đó là các đối tượng thực thi __invokephương thức ma thuật. Nếu bạn muốn bao gồm những thứ đó (trong khi vẫn loại trừ chuỗi và mảng), hãy sử dụng method_exists($func, '__invoke'). Đây vẫn sẽ bao gồm việc đóng cửa, kể từ khi đóng cửa thực hiện __invokecho phù hợp.


8
Điều này đặc biệt hữu ích, vì is_callable()sẽ cố gắng tìm một phương thức để gọi dựa trên một chuỗi hoặc mảng được truyền vào, điều này có thể tự động tải các lớp và có thể không phải là hành vi bạn mong đợi / yêu cầu.
spikyjt

2
function is_function($f) {
    return is_callable($f) && !is_string($f);
}

Trong tương lai, PHP có thể thay đổi gettype () từ Object thành Callable, như các ngôn ngữ khác đã làm. Vì vậy, câu trả lời này có lẽ là cách tốt nhất để đi. Nhưng điều này có thể được tối ưu hóa dưới dạng: return! Is_string ($ f) &&! Is_array ($ f) && is_callable ($ f).
Alexandre T.

0

Trong php các hàm gọi hợp lệ có thể là hàm, tên của hàm (chuỗi) và mảng có dạng ['className', 'staticMethod']hoặc [$object, 'method'], do đó, để phát hiện các hàm chỉ cần loại trừ chuỗi và mảng:

function isFunction($callable) {
    return $callable && !is_string($callable) && !is_array($callable) && is_callable($callable);
}
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.