ホームページ バックエンド開発 PHPチュートリアル register_shutdown_function 関数の詳細な紹介

register_shutdown_function 関数の詳細な紹介

Dec 20, 2017 pm 02:51 PM
function shutdown

在PHP核心技术与最佳实践中,提及了一个函数register_shutdown_function,我发现这个函数非常的有意思,今天就来给大家详细解析一下这个函数

1. 函数说明

定义:该函数是来注册一个会在PHP中止时执行的函数

参数说明:

void register_shutdown_function ( callable $callback [, mixed $parameter [, mixed $... ]] )
ログイン後にコピー


注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。

callback:待注册的中止回调

parameter:可以通过传入额外的参数来将参数传给中止函数

2. PHP中止的情况

PHP中止的情况有三种:

执行完成

exit/die导致的中止

发生致命错误中止

a. 第一种情况,执行完成

<?php
function test()
{
 echo &#39;这个是中止方法test的输出&#39;;
}
register_shutdown_function(&#39;test&#39;);
echo &#39;before&#39; . PHP_EOL;
ログイン後にコピー


运行:

before
ログイン後にコピー
ログイン後にコピー

这个是中止方法test的输出


注意:输出的顺序,等执行完成了之后才会去执行register_shutdown_function的中止方法test

b. 第二种情况,exit/die导致的中止

<?php
function test()
{
 echo &#39;这个是中止方法test的输出&#39;;
}
  
register_shutdown_function(&#39;test&#39;);
  
echo &#39;before&#39; . PHP_EOL;
exit();
echo &#39;after&#39; . PHP_EOL;
ログイン後にコピー


运行:

before
ログイン後にコピー
ログイン後にコピー

这个是中止方法test的输出


后面的after并没有输出,即exit或者是die方法导致提前中止。

c. 第三种情况,发送致命错误中止

<?php
function test()
{
 echo &#39;这个是中止方法test的输出&#39;;
}
  
register_shutdown_function(&#39;test&#39;);
  
echo &#39;before&#39; . PHP_EOL;
  
// 这里会发生致命错误
$a = new a();
  
echo &#39;after&#39; . PHP_EOL;
ログイン後にコピー


运行:

before
Fatal error: Uncaught Error: Class &#39;a&#39; not found in D:\laragon\www\php_book\test.php on line 1
Error: Class &#39;a&#39; not found in D:\laragon\www\php_book\test.php on line 12
Call Stack:
 0.0020  360760 1. {main}() D:\laragon\www\php_book\test.php:0
ログイン後にコピー

这个是中止方法test的输出


后面的after也是没有输出,致命错误导致提前中止了。

3. 参数

第一个参数支持以数组的形式来调用类中的方法,第二个以及后面的参数都是可以当做额外的参数传给中止方法。

<?php
  
class Shutdown
{
 public function stop()
 {
  echo "这个是stop方法的输出";
 }
}
  
// 当PHP终止的时候(执行完成或者是遇到致命错误中止的时候)会调用new Shutdown的stop方法
register_shutdown_function([new Shutdown(), &#39;stop&#39;]);
  
// 将因为致命错误而中止
$a = new a();
  
// 这一句并没有执行,也没有输出
echo &#39;必须终止&#39;;
ログイン後にコピー


也可以在类中执行:

<?php
  
class TestDemo {
 public function construct()
 {
  register_shutdown_function([$this, "f"], "hello");
 }
  
 public function f($str)
 {
  echo "class TestDemo->f():" . $str;
 }
}
  
$demo = new TestDemo();
echo &#39;before&#39; . PHP_EOL;
  
/**
运行:
before
class TestDemo->f():hello
 */
ログイン後にコピー


4. 同时调用多个

可以多次调用 register_shutdown_function,这些被注册的回调会按照他们注册时的顺序被依次调用。

不过注意的是,如果在第一个注册的中止方法里面调用exit方法或者是die方法的话,那么其他注册的中止回调也不会被调用。
代码:

<?php
/**
 * 可以多次调用 register_shutdown_function,这些被注册的回调会按照他们注册时的顺序被依次调用。
 * 注意:如果你在f方法(第一个注册的方法)里面调用exit方法或者是die方法的话,那么其他注册的中止回调也不会被调用
 */
  
/**
 * @param $str
 */
function f($str) {
 echo $str . PHP_EOL;
  
 // 如果下面调用exit方法或者是die方法的话,其他注册的中止回调不会被调用
 // exit();
}
  
// 注册第一个中止回调f方法
register_shutdown_function("f", "hello");
  
class TestDemo {
 public function construct()
 {
  register_shutdown_function([$this, "f"], "hello");
 }
  
 public function f($str)
 {
  echo "class TestDemo->f():" . $str;
 }
}
  
$demo = new TestDemo();
echo &#39;before&#39; . PHP_EOL;
  
/**
运行:
before
hello
class TestDemo->f():hello
  
注意:如果f方法里面调用了exit或者是die的话,那么最后的class TestDemo->f():hello不会输出
 */
ログイン後にコピー


5. 用处

该函数的作用:

析构函数:在PHP4的时候,由于类不支持析构函数,所以这个函数经常用来模拟实现析构函数

致命错误的处理:使用该函数可以用来捕获致命错误并且在发生致命错误后恢复流程处理

代码如下:

<?php
/**
 * register_shutdown_function,注册一个会在php中止时执行的函数,中止的情况包括发生致命错误、die之后、exit之后、执行完成之后都会调用register_shutdown_function里面的函数
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/7/15
 * Time: 17:41
 */
  
class Shutdown
{
 public function stop()
 {
  echo &#39;Begin.&#39; . PHP_EOL;
  // 如果有发生错误(所有的错误,包括致命和非致命)的话,获取最后发生的错误
  if (error_get_last()) {
   print_r(error_get_last());
  }
  
  // ToDo:发生致命错误后恢复流程处理
  
  // 中止后面的所有处理
  die(&#39;Stop.&#39;);
 }
}
  
// 当PHP终止的时候(执行完成或者是遇到致命错误中止的时候)会调用new Shutdown的stop方法
register_shutdown_function([new Shutdown(), &#39;stop&#39;]);
  
// 将因为致命错误而中止
$a = new a();
  
// 这一句并没有执行,也没有输出
echo &#39;必须终止&#39;;
ログイン後にコピー


运行:

Fatal error: Uncaught Error: Class &#39;a&#39; not found in D:\laragon\www\php_book\1_23_register_shutdown.php on line 31
  
Error: Class &#39;a&#39; not found in D:\laragon\www\php_book\1_23_register_shutdown.php on line 31
  
Call Stack:
 0.0060  362712 1. {main}() D:\laragon\www\php_book\1_23_register_shutdown.php:0
  
Begin.
Array
(
 [type] => 1
 [message] => Uncaught Error: Class &#39;a&#39; not found in D:\laragon\www\php_book\1_23_register_shutdown.php:31
Stack trace:
#0 {main}
 thrown
 [file] => D:\laragon\www\php_book\1_23_register_shutdown.php
 [line] => 31
)
Stop.
ログイン後にコピー


注意:PHP7中新增了Throwable异常类,这个类可以捕获致命错误,即可以使用try...catch(Throwable $e)来捕获致命错误,代码如下:

<?php
  
try {
 // 将因为致命错误而中止
 $a = new a();
  
 // 这一句并没有执行,也没有输出
 echo &#39;end&#39;;
} catch (Throwable $e) {
 print_r($e);
 echo $e->getMessage();
}
ログイン後にコピー


运行:

Error Object
(
 [message:protected] => Class &#39;a&#39; not found
 [string:Error:private] =>
 [code:protected] => 0
 [file:protected] => C:\laragon\www\php_book\throwable.php
 [line:protected] => 5
 [trace:Error:private] => Array
  (
  )
  
 [previous:Error:private] =>
 [xdebug_message] =>
Error: Class &#39;a&#39; not found in C:\laragon\www\php_book\throwable.php on line 5
  
Call Stack:
 0.0000  349856 1. {main}() C:\laragon\www\php_book\throwable.php:0
  
)
Class &#39;a&#39; not found
ログイン後にコピー


这样的话,PHP7中使用Throwable来捕获的话比使用register_shutdown_function这个函数来得更方便,也更推荐Throwable。

注意:Error类也是可以捕获到致命错误,不过Error只能捕获致命错误,不能捕获异常Exception,而Throwable是可以捕获到错误和异常的,所以更推荐。

6.巧用register_shutdown_function判断php程序是否执行完

还有一种应用场景就是:要做一个消费队列,因为某条有问题的数据导致致命错误,如果这条数据不处理掉,那么整个队列都会导致瘫痪的状态,这样可以用以下方法来解决。即:如果捕获到有问题的数据导致错误,则在回调函数中将这条数据处理掉就可以了。

php范例参考与解析:

<?php
 
register_shutdown_function(&#39;myFun&#39;); //放到最上面,不然如果下面有致命错误,就不会调用myFun了。
$execDone = false; //程序是否成功执行完(默认为false)
 
/**
********************* 业务逻辑区*************************
*/
$tas = 3;
if($tas == 3)
{
new daixiaorui();
}
 
/**
********************* 业务逻辑结束*************************
*/
$execDone = true; //由于程序由上至下执行,因此当执行到此后,则证明逻辑没有出现致命的错误。
 
function myFun()
{
global $execDone;
if($execDone === false)
{
file_put_contents("E:/myMsg.txt", date("Y-m-d H:i:s")."---error: 程序执行出错。\r\n", FILE_APPEND);
/******** 以下可以做一些处理 ********/
}
}
ログイン後にコピー

总结

register_shutdown_function这个函数主要是用在处理致命错误的后续处理上(PHP7更推荐使用Throwable来处理致命错误),不过缺点也很明显,只能处理致命错误Fatal error,其他的错误包括最高错误Parse error也是没办法处理的。


相信看了这些案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

相关阅读:

实例讲解Ajax异步请求技术

AJAX的常用语法是什么

AJAX原理与CORS跨域的方法


以上がregister_shutdown_function 関数の詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Linux shutdown コマンドはすぐにシャットダウンできますか? Linux shutdown コマンドはすぐにシャットダウンできますか? Jan 28, 2023 pm 05:26 PM

Linux のシャットダウン コマンド shutdown を使用すると、root ユーザーは「shutdown -h now」コマンドを実行するだけで、コンピュータをすぐにシャットダウンできます。 shutdown コマンドを使用すると、シャットダウン プロセスを実行し、シャットダウンする前にユーザーが実行しているすべてのプログラムにメッセージを送信できます。shutdown コマンドを使用するには、システム管理者の root ユーザーが必要です。

機能とはどういう意味ですか? 機能とはどういう意味ですか? Aug 04, 2023 am 10:33 AM

ファンクションとは、関数を意味します。これは、特定の関数を備えた再利用可能なコード ブロックです。プログラムの基本コンポーネントの 1 つです。入力パラメータを受け取り、特定の操作を実行し、結果を返すことができます。その目的は、再利用可能なコード ブロックをカプセル化することです。コードの再利用性と保守性を向上させるコード。

Windows 10/11で自動シャットダウンを設定する3つの方法 Windows 10/11で自動シャットダウンを設定する3つの方法 May 01, 2023 pm 10:40 PM

忙しい世界では、定期的またはタイムリーにトリガーしたいことを自動化したいと考えています。自動化はタスクの制御に役立ち、タスクを実行する労力を軽減します。これらのタスクの 1 つは、コンピュータをシャットダウンすることである場合があります。コンピュータを定期的にシャットダウンすることも、特定の時間または曜日にシャットダウンすることも、または一度にシャットダウンすることもできます。システムが自動的にシャットダウンするようにタイマーを設定する方法を見てみましょう。方法 1: [ファイル名を指定して実行] ダイアログ ボックスを使用します。 ステップ 1: Win + R キーを押し、shutdown-s-t600 と入力して、[OK] をクリックします。注: 上記のコマンドでは、600 は時間を秒単位で表します。必要に応じて変更できます。分や時間ではなく、常に秒単位である必要があります

Linux でスケジュールされたシャットダウン コマンドを設定する方法 Linux でスケジュールされたシャットダウン コマンドを設定する方法 Feb 18, 2024 pm 11:55 PM

Linux のスケジュールされたシャットダウン コマンドとは何ですか? Linux システムを使用している場合、多くの場合、大量のファイルをダウンロードした後に自動的にシャットダウンする、またはサーバーが使用されなくなったときに自動的にシャットダウンするなど、シャットダウンをスケジュールする必要があります。 Linux システムでは、「shutdown」コマンドを使用してスケジュールされたシャットダウンを実装できます。 「shutdown」コマンドを使用すると、ユーザーはシステムをシャットダウンまたは再起動し、遅延時間を設定できます。コマンドにパラメータを追加することで、スケジュールシャットダウン機能を実装できます。コマンドの基本的な形式は次のとおりです。

MySQL が予期せずシャットダウンしました - MySQL エラーを解決する方法: MySQL が予期せずシャットダウンしました MySQL が予期せずシャットダウンしました - MySQL エラーを解決する方法: MySQL が予期せずシャットダウンしました Oct 05, 2023 pm 02:42 PM

MySQL は、さまざまな Web サイトやアプリケーションで広く使用されている、一般的に使用されているリレーショナル データベース管理システムです。ただし、MySQL の使用中にさまざまな問題が発生する可能性があります。その 1 つは、MySQL が予期せず終了することです。この記事では、MySQL のエラー問題を解決する方法について説明し、いくつかの具体的なコード例を示します。 MySQL が予期せずシャットダウンした場合は、まず MySQL エラー ログを確認してシャットダウンの理由を理解する必要があります。通常、MySQL エラー ログは MySQL インストール ディレクトリにあります。

Python の「enumerate()」関数の目的は何ですか? Python の「enumerate()」関数の目的は何ですか? Sep 01, 2023 am 11:29 AM

この記事では、Python の enumerate() 関数と「enumerate()」関数の目的について学びます。 enumerate() 関数とは何ですか? Python の enumerate() 関数は、データ コレクションをパラメータとして受け取り、列挙オブジェクトを返します。列挙オブジェクトはキーと値のペアとして返されます。キーは各項目に対応するインデックス、値は項目です。構文 enumerate(iterable,start) パラメータ iterable - 渡されたデータ コレクションは、iterablestart と呼ばれる列挙オブジェクトとして返すことができます。 - 名前が示すように、列挙オブジェクトの開始インデックスは start によって定義されます。無視したら

MySQL.procテーブルの役割と機能の詳しい説明 MySQL.procテーブルの役割と機能の詳しい説明 Mar 16, 2024 am 09:03 AM

MySQL.proc テーブルの役割と機能の詳細な説明。MySQL は人気のあるリレーショナル データベース管理システムです。開発者が MySQL を使用する場合、多くの場合、ストアド プロシージャ (StoredProcedure) の作成と管理が必要になります。 MySQL.proc テーブルは非常に重要なシステム テーブルであり、ストアド プロシージャの名前、定義、パラメータなど、データベース内のすべてのストアド プロシージャに関連する情報が保存されます。この記事では、MySQL.proc テーブルの役割と機能について詳しく説明します。

shutdown すぐにシャットダウンするコマンドは何ですか? shutdown すぐにシャットダウンするコマンドは何ですか? Feb 27, 2023 am 11:23 AM

すぐにシャットダウンするシャットダウン コマンドは「shutdown -h now」です。シャットダウン コマンドを使用すると、シャットダウン プロセスを実行し、シャットダウンする前にユーザーが実行しているすべてのプログラムにメッセージを送信できます。シャットダウンは、コンピュータを再起動するためにも使用できます。 。

See all articles