2012-06-02 18 views
12

Nói rằng tôi có một mảng như sau:Bất kỳ cách nào để kiểm tra các chức năng ẩn danh?

array(
    [0] => function() { return "hello"; } 
    [1] => function() { return "world"; } 
    [2] => "look" 
    [3] => function() { return "and";} 
    [4] => function() { return "listen";} 
) 

Có cách nào tôi có thể gọi 0, 1, 3 và 4 mà không có cách gọi 2?

+8

instanceof Closure && is_callable() – jolt

+0

Đây có phải là câu trả lời không? – elite5472

+0

Đã viết từ điện thoại, không muốn làm phần định dạng. SO không thân thiện với thiết bị di động. :( – jolt

Trả lời

16

chức năng Anonymous là trường hợp của lớp Closure. Vì vậy, kiểm tra và is_callable thực hiện công việc.

foreach ($array as $func) { 
    if (is_callable($func) && $func instanceof Closure) { 
     $func(); 
    } 
} 

Thực ra, việc kiểm tra lớp học là đủ vì bạn không thể thực hiện thủ công các đối tượng ngoại trừ bằng cách tạo chức năng ẩn danh.

+0

Công trình này tuyệt vời. – elite5472

+0

@ elite5472 bạn đã thử nghiệm nó chưa? nó sẽ gây ra một lỗi nghiêm trọng nếu '" look "' được định nghĩa là một hàm vì nó sẽ dẫn đến kiểm tra '" look "instanceof Closure' gây ra lỗi nghiêm trọng. Lols, nevermind, đó chỉ là nếu bạn kiểm tra một chuỗi trực tiếp thay vì một biến chứa một chuỗi ...: D – Esailija

+0

Esailija, không, nó dẫn đến thử nghiệm '$ func instanceof Closure' hợp lệ:' $ func = 'look' ; var_dump ($ func instanceof Closure); '=>' bool (false) ' –

1

Bạn có thể sử dụng reflection, số này có an undocument function to check for closures; thử này (chưa được kiểm tra):

foreach ($array as $val) { 
    $re = newReflectionFunction($val); 
    if ($re->isClosure()) { 
     $val(); 
     // do whatever you want 
    } 
} 

... hoặc kiểm tra xem nó không phải là một chuỗi/số:

foreach ($array as $val) { 
    if (!is_string($val) && !is_numeric($val)) { 
     $val(); 
     // do whatever you want 
    } 
} 

... hoặc kiểm tra xem nó là một đối tượng:

foreach ($array as $val) { 
    if (gettype($val) == 'object') { 
     $val(); 
     // do whatever you want 
    } 
} 
+0

Điều này không phải là rất hữu ích. Nếu nó không phải là một chuỗi? – elite5472

+0

Trong trường hợp của bạn, vì vậy tôi đã giả sử nó là một hàm ẩn danh hoặc một chuỗi. – Jeroen

+1

elite5472, đó không phải là những gì bạn đã hỏi. Từ câu hỏi của bạn, một câu trả lời hữu ích sẽ là 'if ($ val! == 'look') ...' –

0

gettype về phương pháp anon trở về "đối tượng" và is_callable() trả về true về chức năng, sau đó:

foreach ($array as $val) { 
    if (is_callable($val) && gettype($val)=="object") { 
     $val(); 
    } 
} 

và đây là mã kiểm tra của tôi:

<?php 

function look(){ 
    return "looking"; 
} 

$data=array(
    0 => function() { return "hello"; }, 
    1 => function() { return "world"; }, 
    2 => "look", 
    3 => function() { return "and";}, 
    4 => function() { return "listen";} 
); 
echo "<pre>"; 

foreach ($data as $val) { 
    if (is_callable($val) && gettype($val)=="object") { 
     echo $val(); 
    } 
} 

?> 
+0

Nếu 'look()' là một hàm xác định thì sao? –

+0

Tôi đã cập nhật câu trả lời của mình. –

+0

Đây không phải là chính xác, bởi vì [__invoke] (http://www.php.net/manual/en/language.oop5.magic.php#object.invoke)() tồn tại và vì vậy bất kỳ đối tượng nào do người dùng xác định có thể được thực hiện có thể gọi được. – goat

1

Tôi nghĩ đây là những gì bạn muốn. $result sẽ là một mảng giá trị trả về của mỗi cuộc gọi hàm (ngoại trừ nếu nó không phải là một hàm ẩn danh, trong trường hợp đó nó sẽ là giá trị ban đầu từ $array).

$result = array_map(
        function($e) { 
         return ($e instanceof Closure && is_callable($e)) ? 
         $e() : $e; 
        }, $array); 
Các vấn đề liên quan