スキップしてメイン コンテンツに移動

投稿

ラベル(register_shutdown_function)が付いた投稿を表示しています

PHPのregister_shutdown_functionで登録した関数内でmemory_limitを増加させる

PHPで、特にメモリ不足のエラーが発生してプログラムが強制終了したときに、register_shutdown_functionに終了時に実行したい関数を登録することで、プログラム終了時にその登録した関数を実行することができます。 が、その登録した関数内の処理でメモリ不足になり、実行したかった処理が実行されないという問題に遭遇しました。 色々テストしたところ、register_shutdown_functionに登録した関数内でPHPのmemory_limitを増加させれば対応できることがわかりました。 といわけで現在のmemory_limitに任意のメモリ値を足すメソッドを作成してみました。 下記のsetAddedMemoryLimitByMegaByteメソッドは、引数にmemory_limitの増分を渡すことで、memory_limitの設定値を増加させることができます。 注意点として、作成したプログラム内のmemory_limitの許容フォーマットは こちら に書かれている情報に基づいて決めました。 今のプログラムは、256、128K、1024M、3Gなどは正しく処理可能です。 メモリサイズの設定値なので、そこまで変な値が設定される可能性は少ないですが、もし今のプログラムで処理できない場合は、convertMemoryLitAsByteValue内のmemory_limitをパースしている正規表現部分を修正することで対応できます。 class PHPUtils { public static function setAddedMemoryLimitByMegaByte($addition) { $current = ini_get('memory_limit'); if($current == -1) { return; } try { ini_set('memory_limit', self::calcAddedMemoryAsMegaByte($current, $addition))

register_shutdown_functionを使ってPHPのFatal Error発生後の処理を制御

PHP 7以降では、PHPのエラーは基本的にErrorクラスとして扱われ、try-catchブロックで捕まえることができるようになりました。(Catchable Fatal Error) ちなみにPHP 7では下記の2つのクラスがThrowableクラスを継承しており、両方捕まえるときは、try-catchブロックでThrowableをcatchするように書けばOKです。 Exception Error ただし、一部のFatal Error(例: Memory Exhausted Error)はtry-catchブロックで捕まえることができません。 Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 9792 bytes) in .... この場合は、register_shutdown_functionを使って、PHPのプログラムが終了したときにエラー処理をするしかなさそうです。 register_shutdown_functionとerror_get_lastを使ってエラー処理をする関数のコード例を示します。 <?php // PHPのError定数 => 文字列表現の連想配列 const ERROR_CODE_TO_STRING = [ E_ERROR => 'E_ERROR', E_WARNING => 'E_WARNING', E_PARSE => 'E_PARSE', E_NOTICE => 'E_NOTICE', E_CORE_ERROR => 'E_CORE_ERROR', E_CORE_WARNING => 'E_CORE_WARNING', E_COMPILE_WARNING => 'E_COMPILE_WARNING', E_USER_ERROR => 'E_USER_ERROR', E_USER_WARNING => '