2012-02-24 76 views
5

Có thể ghi đè lên ngăn xếp đã được đặt là register_shutdown_function không? Một cái gì đó như:register_shutdown_function ghi đè

function f1(){ 
    echo "f1"; 
} 
function f2(){ 
    echo "f2"; 
} 
register_shutdown_function("f1"); 
echo "actions here"; 
register_shutdown_function("f2"); 
call_to_undefined_function(); // to "produce" the error 

Trong trường hợp này tôi muốn tập lệnh chỉ gọi f2(). Điều này có thể không?

Trả lời

2

từ php doc page trên register_shutdown_function():

Nhiều cuộc gọi đến register_shutdown_function() có thể được thực hiện, và mỗi sẽ được gọi theo thứ tự giống như họ đã được đăng ký. Nếu bạn gọi thoát() trong một chức năng tắt máy đã đăng ký, quá trình xử lý sẽ dừng hoàn toàn và không có chức năng tắt đăng ký nào khác được gọi.

điều này có nghĩa là nếu bạn chỉ muốn gọi hàm f2 bạn có thể chuyển nó vào cuộc gọi exit() trong trình xử lý ngoại lệ. Nhiều cuộc gọi đến register_shutdown_function() sẽ gọi tất cả các chức năng theo thứ tự, không chỉ là lần đăng ký cuối cùng. Vì dường như không có bất kỳ loại nào của unregister_shutdown_function(), đây là những gì tôi đề xuất.

0

Tôi có vấn đề này quá, và tôi giải quyết này như:

function f1(){ 
if (defined('CALL1') && CALL1===false) return false; 
echo "f1"; 
} 
function f2(){ 
    echo "f2"; 
} 
register_shutdown_function("f1"); 
echo "actions here"; 
define('CALL1', false); 
register_shutdown_function("f2"); 
call_to_undefined_function(); 
3

Bạn không thể làm điều đó thẳng, nhưng luôn có một cách giải quyết:

$first = register_cancellable_shutdown_function(function() { 
    echo "This function is never called\n"; 
}); 

$second = register_cancellable_shutdown_function(function() { 
    echo "This function is going to be called\n"; 
}); 

cancel_shutdown_function($first); 

Output:

$ php test.php 
This function is going to be called 

The code:

function register_cancellable_shutdown_function($callback) 
{ 
     return new cancellable_shutdown_function_envelope($callback); 
} 

function cancel_shutdown_function($envelope) 
{ 
    $envelope->cancel(); 
} 

final class cancellable_shutdown_function_envelope 
{ 
     private $callback; 

     public function __construct($callback) 
     { 
       $this->callback = $callback; 
       register_shutdown_function(function() { 
         $this->callback && call_user_func($this->callback); 
       }); 
     } 

     public function cancel() 
     { 
       $this->callback = false; 
     } 
} 
1

tùy chọn khác là sử dụng các chức năng sau:

function register_named_shutdown_function($name, $callback) 
{ 
     static $callbacks = []; 
     $callbacks[$name] = $callback; 

     static $registered; 
     $registered || $registered = register_shutdown_function(function() use (&$callbacks) { 
       array_map(function ($callback) { 
         call_user_func($callback); 
       }, $callbacks); 
     }) || true; 
} 

sử dụng mẫu:

register_named_shutdown_function("first", function() { 
     echo "Never executed\n"; 
}); 

register_named_shutdown_function("second", function() { 
     echo "Secondly executed\n"; 
}); 

register_named_shutdown_function("first", function() { 
     echo "Firstly executed\n"; 
}); 

Đầu ra:

Firstly executed 
Secondly executed