MySQLを使っていてPHP5からPHP7へのバージョンアップを伴うWEBページ移行を行う際に、Tailコマンドでログ監視をしたら想定よりも作業が捗った話
実施した環境
現行:PHP5系
移行先:PHP7系
データベース:MySQL5.X
WEB:Apache2.4.X
前置き
私はゲームクリエイターであって、WEB系エンジニアではないので、ここに記載されている情報は付け焼刃的に調べた内容なので正しくない可能性があり、誤っている内容が含まれている可能性があります。変な内容があれば指摘して頂けると嬉しいです。
ストーリー(スキップ可能)
PHP5系はセキュリティ面において深刻な問題がいくつかあるらしく、PHP7はPHP5より2倍くらいサイト表示速度が速くなるので良い事づくし。
PHP7.2は2020年12月にはサポートが切れてしまうらしいので、現時点(2020年9月)ではPHP7.3以降が良いと思われる。
データベースと接続する為のmysql関数がphp5.5では非推奨となり、php7.0以降では使用できなくなった。その為、php7系にWEBページをそのまま移行すると、以下のようなエラーが表示される。
「Fatal error: Uncaught Error: Call to undefined function mysql_XXXXXX」
代わりの関数を使用するようになる為、ソースコードを若干修正する必要がある。grepやテキスト内検索で一つ一つ該当箇所を置き換えて行っても良いと考えたが、過去に実践したノウハウも経験値も無い為、PHPエラーとして検知された箇所を都度修正するやり方で進めてみる事にした。
使用できなくなったmysql関数はmysqli関数に代用することができるらしい。
基本的には関数名に「 i 」を付けるだけで変換できるが、一部の関数は引数の並び替えが必要になる。
■DBがMySQLの場合
PHP7でのデータベース接続の際、mysqli関数でMySQLサーバに接続する。
mysqli_connect('ホスト名', 'ユーザー名', 'パスワード', 'データベース名');
ホスト名:データベースサーバのホスト名またはIPアドレスを記述する。この引数が無い場合、または明示的に'localhost'と記述した場合はローカルホストとみなされる。
ユーザー名:MySQLのユーザー名
パスワード:MySQLのパスワード
データベース名:データベースの名前を指定する。mysql関数の時は別のコマンドで指定していたが、mysqli関数では同時にデータベース名を設定できるようになった。
mysqli関数の記述はオブジェクト指向の記述にする事を推奨している。
やりたいこと
・WEBページを表示したときに、PHPコードに問題があればエラーをログに吐き出す。
・吐き出されたログはリアルタイムで確認したい。エラーの箇所も何行目かを知りたい。
・MySQLを使うソースコードでPHP5からPHP7に移行を効率的に行いたい。
エラーログを出力する為の事前準備
php.iniファイルに次の1行を追加する
error_log = [出力先フルパス]/[出力先ファイル名]
先ほどのパスにエラーログを出力するファイルを作成する
今回はファイル名を[debug.log]に設定した。
※debug.logが存在しない状態だとログは追記されなかった。
※WinSCPで作成したファイルをアップロードし、permissionは0705にした。
3)TerminalからLinuxにSSHでログインし、tailコマンドでログファイルの末尾部分をリアルタイムでTerminal画面に出力する
tail -f debug.log
sshでログインした後、tailコマンドでログのリアルタイム監視ができる
移行したPHPページを表示したりボタンやフォーム入力などのテストの際、
エラーがあった場合の処理をerror_log()関数で吐き出すようにし、リアルタイムにログが出るようになる為、デバッグ作業が少し楽になる。
php.iniの他の設定は変更なし
■ログ出力レベルを指定する
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
・出力内容が気に入らない時は設定を変更する。今回は変更なし
■ログをファイルに出力する
log_errors = On
・Onにしていないとログは蓄積されないと思われる。今回は変更なし
mysqliでのデータベース接続
db_connect.php
<?php
//インスタンス化
$mysqli = new mysqli('127.0.0.1' , 'username', 'password', 'databasename');
//エラーチェック
if($mysqli->connect_error){
//エラーの内容を変数に入れる
$sql_err = $mysqli->connect_error;
// 日付を設定する
$date = date('Ymd', time() );
// 時刻を設定する
$time = date('Y-m-d H:i:s',time() );
//エラー出力
error_log('['. $time .']' .$sql_error ."\r\n", 3, '[ファイル出力パス]/log_' .$date .".log");
//デフォルトのファイルに蓄積するときは0を指定し、ファイルの指定もしない
//error_log('['. $time .']' .$sql_error,0);
//画面に表示するメッセージ
echo "データベースの接続に失敗しました。\n";
//エラーの詳細内容も同じ画面に表示する
die($sql_error);
exit;
}
?>
PHPのエラーが日付毎に吐き出されるようになった。
後はTerminalソフト等からSSH接続し、ファイル出力パスにcdでディレクトリ移動を行い、生成されたログファイルをtailコマンドを監視モード(-f)で起動するとリアルタイムでログが蓄積されていくのが確認できる。
例:コマンド 生成されたログが2020/9/1の場合
「tail -f log_20200901.log」
利用方法
WEBサイトのPHPエラーをWEB画面操作しながら監視していくことができた。しかし、デフォルトのエラー出力はphp.iniに設定したdebug.logに蓄積されるので明示的にerror_logコマンドでパスを指定しないとログの蓄積は日別にならない。
明示的に出力しなかったエラーはタイムスタンプ付きでphp.iniで指定したファイルに記録されたので、どこかでphpエラーを吐き出す設定が元々入っている?(レンタルサーバ側の設定かどうかは未確認)
とりあえずログは蓄積できるようになったのでPHP5からPHP7への移行はdebug.logにログを吐き出させながら、Terminalソフトでtailコマンドを実行し、ログファイルをTerminalで開きつつ、WEBページを操作しながらログを確認して修正作業を行うという流れで、今のところは効率的に作業ができている。
error_log出力先の変更について
・php.iniのerror_logに指定したファイルにログを蓄積するパターン
error_log($sql_error,0);
・指定したファイルにログを出力したいパターン
error_log($sql_error,3,[FullPathの指定ファイル名]);
※改行コードが入らないので見やすくするには."\r\n"で改行を付与する必要がある
php.iniを設定変更する方法
レンタルサーバの管理パネル->PHP->php.ini設定->php.ini直接編集で
error_logのパスを追記する事ができる。
※SSH接続しても権限が無い場合、管理パネル等からphp.iniを編集する。
権限がある場合はetc/php配下等にあるphp.iniを修正する。
PHP7変換メモ
・mysqli_fetch_arrayはmysqli_fetch_assocで、パラメータを無くすと使えるようになった。
mysql_fetch_array($rst, MYSQL_ASSOC) → mysqli_fetch_assoc($rst)
・mysql_fetch_array($rst,NULL) → mysqli_fetch_array($rst,MYSQLI_BOTH)
・mysqli_queryは、mysqliクラスのオブジェクトを第一引数にし、第二引数にSQL文を指定する。mysqli_query($mysqli,$sqlstr) ;
・mysql_num_rows → mysqli_num_rows 引数変更なし
・mysql_close → mysqli_close 引数変更なし
調べても同じような記述を紹介しているサイトは他にたくさんあった。
mysqli_fetch_arrayについてはfetch_assocにすると良いという記事は少なかった気がする。こんな感じか?と直していったら動いたので正しいかは不明。
DBがPostgreSQLになる場合
pg_connect関数で接続するらしく、mysql_の部分がpg_に変わるくらいで大幅な変更はない様子。でも未検証。今後調査が必要になる場合は追記します。
この記事が気に入ったらサポートをしてみませんか?