PHPのスニペットいろいろ
篠原 隆司
PHPでたまに必要になるよく使うコードを置いてます。
主に自分用です。
どこでも誰でも使えるものもあれば私(の環境)しか使えないものもあります。
三項演算子とかワンライナーで書けそうなところも、可読性と再利用性を優先してます。
スニペットとは「分かっている人が楽をするためのツール」です。
分からない人がコピペするためのものではありません。
コードの意味を理解してご利用ください。
基本の設定
// タイムゾーンを「東京」にする date_default_timezone_set('Asia/Tokyo'); // ja にして utf-8 にする mb_language('ja'); mb_regex_encoding('utf-8'); mb_internal_encoding('utf-8'); // X-Powered-Byを非表示 ini_set('expose_php', 0);
php
ini_set / ini_get
メモリ制限
// メモリ制限を 128M に変更 ini_set('memory_limit', '128M'); // 現在のメモリ制限値を取得 echo ini_get('memory_limit');
php
取得関係
サーバ名を取得
$server_name = ''; if (isset($_SERVER['SERVER_NAME'])) { $server_name = $_SERVER['SERVER_NAME']; }
php
SSLの状態
$is_ssl = false; if (isset($_SERVER['SERVER_PORT'])) { $is_ssl = $_SERVER['SERVER_PORT'] === '443'; }
php
ユーザーエージェント
$user_agent = 'unset'; if (isset($_SERVER['HTTP_USER_AGENT'])) { $user_agent = $_SERVER['HTTP_USER_AGENT']; }
php
リモートアドレス
$remote_addr = '0.0.0.0'; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $remote_addr = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { if (isset($_SERVER['REMOTE_ADDR'])) { $remote_addr = $_SERVER['REMOTE_ADDR']; } }
php
計測関係
マイクロ秒単位で掛かった時間を計測
高速化対応をするときには体感じゃなく、実際に計測しましょう。
// 開始時間 $start_microtime = microtime(true); // 時間の掛かるなにか sleep(1); // 経過時間 $elapsed_time = microtime(true) - $start_microtime; // 表示 echo number_format($elapsed_time, 5);
php
メール関係
メールサーバを指定
mail() 関数とかでメールを送信するとき何も気にしないと、PHPが動いているマシンを使って送信しようとします。
開発用マシンとかだとメールサーバを用意してないから送信エラーになること、ありますね。
次のようにメールサーバとポートを指定して外部マシン経由で送信できるようになります。
ini_set('SMTP', 'メールサーバのIPアドレスまたはホスト名'); ini_set('smtp_port', 587);
php
変換
あらゆる変数を文字列に変換
ちょっと変数の中身を見たいなってときに、print_r とか var_dump とか ログに書き出したりすると思うんですが、そういうとき、どんな型の変数でも受け入れるように拡張したのを用意しておくと便利です。
/** * 変数を文字列に変換 * * @param mixed $variable */ function toString($variable) { if (is_null($variable)) { return '[NULL]'; } if (is_bool($variable)) { return ($variable ? '[TRUE]' : '[FALSE]'); } if (is_string($variable)) { return $variable; } if (is_float($variable)) { return '(float) ' . $variable; } if (is_int($variable)) { return '(int) ' . $variable; } return print_r($variable, true); } // 使用例 error_log(toString(null)); error_log(toString(true)); error_log(toString(false)); error_log(toString(123)); error_log(toString('123')); error_log(toString(123.45)); error_log(toString('123.45')); error_log(toString('こんにちわ')); error_log(toString(array('A', 'B', 'C')));
php
エラー関係
エラー表示
すべてのエラーを出力対象にし、画面に表示します。
ちなみにこれだけではFatalなエラーは取れません。
フレームワークを使っている場合はフレームワークの初期化処理で設定されていることもあります。設定したのに効かないときはそのあたりをみましょう。
ini_set('display_errors', 1); error_reporting(- 1);
php
エラーをログファイルに残す
エラーが発生すると多くの場合、httpdのエラーログ(/var/log/httpd/error_log)とかに書かれるんじゃないでしょうか。
次のようにしてログファイルの位置を設定できます。
ただこれだけだとローテーションとかもないので工夫が必要です。が、そのあたりは本項の範疇外なのでヒント程度にしときます。
あと、そもそもの話として、そもそも error_log に出てくるようなログはその原因から取り除くべきです。ので、そもそもローテーションなんていらんのです。
// error_log への記録を有効にする ini_set('log_errors', 1); // error_log したときの保存場所 // 保存場所のディレクトリは自前で準備 ini_set('error_log', __DIR__ . '/error.log'); // ログファイルを年月で分けてみるとか ini_set('error_log', __DIR__ . '/error-' . date('Y-m-d') . '.log'); // エラーファイルへの書き込み error_log('エラーだよ');
php
エラーを例外にして try / catch
PHPは、try / catch が使えるのですが素直に何も考えないと書くと「思ってるのと違う」ってなると思います。
「わざとエラーを出して、catchに来るはずなのになんで来ないのー」なんてことも。
ということで、PHPのエラーを「例外」(Exception)に変換するのがこちらです。
// エラーハンドラー、Fatalなエラーを Exception に変換する set_error_handler(function ($errno, $errstr, $errfile, $errline) { if (class_exists('\Exception')) { throw new \Exception($errfile . '[' . $errline . '] ErrorNo : ' . $errno . ' / ' . $errstr); } }); // sample try { $a = 10 / 0; // ゼロ割 // $a = $b; // 未定義の変数($b)の使用 // throw new Exception('エラー'); // 例外を投げる } catch (Exception $e) { error_log(print_r($e, true), 0); }
php
シャットダウンエラーの画面表示
PHPのエラーにはいくつか種類があります。
プログラムが動作しないレベルのエラーは「シャットダウンエラー」で行います。
例えば、パースエラー、関数とかIF文とかで閉じ括弧を忘れたとか。
例えば、Fatalエラー、同名の関数を二重に定義したとか。
こういう類のエラーは、処理を継続することができませんので発覚した時点で「シャットダウン」します。
そのため通常のエラーフローに行きませんので、ログを見ても何もでてきません。
メモリ制限に引っかかったときは、register_shutdown_function まで来ないので memory_limit も用意しています。エラーが出るはずなのに出ないときは memory_limit を増やして試してみます。
// ini_set('memory_limit', '128M'); register_shutdown_function(function () { if (is_callable('error_get_last')) { $e = error_get_last(); if (! is_null($e)) { $s = print_r($e, true); // error_log($s, 0); $s = htmlspecialchars($s, ENT_QUOTES); echo '<pre>' . $s . '</pre>'; exit(); } } });
php
変数の中身を画面に表示
変数は文字列でも配列でもオブジェクトでもOKです。
変数の中を見れたらよいので、echo の後その場でexit で良いと思います。
$data = '表示させたい変数'; echo '<pre style="border:solid 1px #aaa;background-color:#000;padding:1em;margin:1em 0;text-align:left;font-size:12px;line-height:1.2;">' . htmlspecialchars(print_r($data, true), ENT_QUOTES) . '</pre>'; // exit;
php