PHP+MySQLでデータベースを運用していると「月単位で集計したCSVデータが欲しい」といった要望が定期的に挙がってくることになります。
そんな時、要望に応じてその都度データを抽出する作業を実施していれば、当然、「PHPをコマンドラインで実行させ、定期的にMySQLに接続して自動でデータを取得したい」と思うようになるのではないでしょうか。
今回は、そんなシステムエンジニアとしての第一歩を歩き始めた方を対象に、PHPをコマンドラインで実行する時のメリットや注意点をまとめながら、バッチ化や自動実行への道順を探っていきたいと思います。
PHPをコマンドライン実行する環境
コマンドライン実行が可能な環境
PHPの動作環境は、大きく分けてWebサーバー経由で実行される「CGI版」、ApacheなどWebサーバーのモジュール経由で実行される「モジュール版」、コマンドライン上で実行される「CLI版」の3つに分類されます。
レンタルサーバーの場合、CGI版かモジュール版で構築されている場合が多く、そういったサーバーはPHPをコマンドラインで実行させることは想定されていません。
コマンドラインでPHPを実行する方法を学ぶにあたり、どのような環境でPHPをコマンドラインで実行できるのかを見極めていくことが重要となりますので、まずは、さまざまな環境でPHPをコマンドライン実行できるのかどうかを見ていきましょう。
ローカル環境
自分でPHPをインストールし、自分でWebサーバーを構築したローカル環境であれば、当然、コマンドラインでPHPを実行可能です。
ただし、PHPを実行するためには、PATHを通しておく必要があります。
インストールしたPHPにパスを通すには以下のようなコマンドを実行しておく必要があります。
1 |
$ export PATH=(PHPがインストールされているパス):$PATH |
例えば「/usr/local/opt/php@7.2/bin」ディレクトリに「PHP7.2」がインストールされている場合は、以下のコマンドを実行してパスを通します。
1 |
$ export PATH=/usr/local/opt/php@7.2/bin:$PATH |
このコマンドを実行することで、パスが通りますので、「php -v」などのコマンドを入力してPHPが実行できることを確認しておいてください。
レンタルサーバーでの可否
先程、レンタルサーバーではCGI版かモジュール版のみで動作するのでコマンドラインでの実行は想定していない、と記載しましたが、これは正確な説明ではありません。
というのも、「SSH接続」することでコマンドラインによるPHPの実行を許可しているレンタルサーバーが存在するためです。
レンタルサーバーを利用する時は料金や容量で選択しがちですが、「SSH接続可能かどうか」もレンタルサーバー選定時の重要な要素となりますので、SSH接続可能なレンタルサーバをいくつか紹介したいと思います。
エックスサーバー
SSH接続可能なレンタルサーバーとして有名なのは「エックスサーバー」です。
無料版のXFreeではSSH接続できませんが、有料版のプランであれば全てのプランでSSH接続可能です。
公開鍵認証方式でSSH接続することになりますので、サーバー上で公開鍵の鍵ペアを生成して秘密鍵をダウンロードする必要があります。
SSH接続するためのコマンドは以下の通りです。
1 |
$ ssh -l サーバーID -i 秘密鍵ファイル名(今回はid_xserver_rsa) サーバーID.xsrv.jp -p 10022 |
さくらレンタルサーバー
もうひとつ、「さくらレンタルサーバー」も有名です。
ライトプランではSSH接続できませんが、スタンダードプラン以上であればSSH接続可能です。
自身のマシンで公開鍵の鍵ペアを生成し、サーバーに公開鍵を登録する必要があります。
サーバーに公開鍵を登録するコマンドは以下のとおりです。
1 2 3 |
$ scp ~/.ssh/id_rsa.pub ユーザー名@ドメイン:/home/sample/.ssh/authorized_keys $ ssh ユーザー名@ドメイン |
その他にも、ロリポップ、CORESERVER、mixhostなどのレンタルサーバーがありますが、基本的にSSH接続するための環境を、自分で設定する必要があります。
また、SSH接続できるとはいっても、root権限でコマンドが利用できるかどうかはレンタルサーバーによって異なりますので、なにかしらの制限はあるものとして利用したほうがよいでしょう。
SSH接続
先程からSSH接続すればレンタルサーバーでもコマンドラインでPHPを実行できる、と説明させていただきましたが、そもそも「SSH接続」とは何なのかを説明しておりませんでした。
SSHとは、Secure Shellと言う言葉から名付けられたリモート接続を行うためのプロトコルで、パスワードを含む全ての通信内容は暗号化され、通信経路上における盗聴やデータの改ざんを防ぐことができます。
また、認証に鍵データを利用することで、パスワード漏洩によるなりすましも防ぐことができ、安全なリモート接続が可能となります。
今回は詳細な説明を省きますが、コマンドラインでPHPを実行するだけでなく、サーバーを管理する上でも重要な技術ですので、別の機会に詳しい記事を書いてみたいと思います。
コマンドライン時の注意点
コマンドラインでPHPを実行するにあたり、いくつか注意すべき点があります。
基本的な内容ですが、気づかないとハマってしまうポイントですので簡単に紹介していきたいと思います。
実行権限
コマンドラインでPHPファイルを実行させる場合、以下のコマンドを使います。
1 |
$ php -f (PHPファイル名) |
このコマンドでPHPファイルに記述したプログラムを実行することができますが、以下のメッセージが出力される場合は、ファイルの実行権限が付与されていない可能性があります。
1 |
Could not open input file:(PHPファイル名) |
以下のコマンドでファイルの実行権限を付与しましょう。
1 2 |
$chmod 777 (PHPファイル名) //777ではフルアクセスとなるのでアクセス権限を考慮して設定しましょう |
改行
PHPをコマンドラインで実行する際、OSによって改行させる方法が異なっているため注意が必要です。
例えばWindows環境の改行コードは「\r\n(CRLF)」ですが、MacOS等の改行コードは「\n(LF)」となっているため、コマンドラインで実行した時、メッセージがうまく改行されていないことが多々発生します。
そこで、コマンドラインでの実行を想定したPHPには、OSに対応した改行コードを出力する「PHP_EOL」が使われています。
ただし、「PHP_EOL」は、Webブラウザ上で出力する場合には改行されませんので、コマンドラインで実行するPHPかWeb上で実行するPHPかを明確に分け、利用用途に応じて使い分ける必要があります。
終了タグ
PHPでは、開始タグの「<?php」と終了タグの「?>」で囲むことで、囲まれた箇所の記述がPHPスクリプトであることを明示することができるのですが、ファイル全体がPHPスクリプトで構成される場合、終了タグである「?>」を省略することが推奨されています。
これは、「<?php」と「?>」のタグで囲まれた外に余計な改行が入り込んでしまうことを防ぐ目的があります。
例えば以下のようなコードを記述した場合、コマンドライン上で、数行分の空白が出力されてしまいます。
1 2 3 4 5 6 |
<?php echo 'Hello'.PHP_EOL; ?> //(<?php〜?>の外に余計な改行がある) |
コマンドラインで実行する場合であれば、このような改行があってもコンソール上に無駄な改行が出力されるだけで特に影響はないかのように思われますが、Webサーバー上で実行すると、この空白行がブラウザに反映されてしまうため、htmlのレイアウト部分に大きな影響を与えてしまうことになります。
また、一見するとコンソール上の無駄な改行でしかない、と感じるかもしれませんが、「コマンドライン上に何らかの出力があった場合」を条件として、その内容をメールで送信するようなシステムを構築していた場合、空白のメールが送信されてしまう、といった影響を与えることにもなります。
ファイル全体がPHPスクリプトで構成される場合は終了タグを記述しないようにするとよいでしょう。
コマンドライン実行の意味
「PHP_EOL」を記述してもブラウザ上では改行されなかったり、コマンドライン上で大きな問題とはならない空白行がブラウザ上で大問題となってしまったりと、Web用に作ったPHPをそのままコマンドラインで実行するにはいくつか問題がありそうです。
そんな問題がある中でコマンドラインでPHPを実行する意味とは何でしょうか。
その点についてもう少し考えてみたいと思います。
複数のPHPバージョンの切り替えが容易
PHPをコマンドラインで実行する場合のメリットとしては「複数のPHPバージョンをインストールした時の管理が容易」という点が挙げられます。
PHPのちょっとした構文の仕様を確認したい場合や、バージョンでの違いを確認したい場合に、運用中のWebサーバーのPHPバージョンを変えて対応する、ということはありえません。
おそらく開発環境で対応することになるとは思いますが、そんな時、コマンドライン上でのバージョン切替の操作自体を自動化しておき、コマンドひとつでバージョンを切り替えることができれば、かなりの手間を省くことができるでしょう。
データベースに接続しやすい
また、データベースにアクセスしやすい、という点もコマンドラインでPHPを実行するメリットに挙げられます。
通常、コマンドプロンプトやターミナルからデータベースに接続する際、以下のようなコマンドを入力する必要があります。
1 2 3 |
$ mysql -h [ホスト名] -u ユーザー名 -p[パスワード入力] mysql > USE [データベース名]; mysql > SELECT * FROM [テーブル名]; |
データベース接続からSQL実行までの流れをPHPファイルでひとまとめにしてサーバーに配置し、そのPHPファイルを以下のように記述したbatファイルやcommandファイルで実行することでデータベースの抽出結果を取得することができるようになります。
1 |
ssh -t -i [鍵] -p [ポート] [ホスト名] -l [パスコード] -t "echo 'rm /tmp/initfile; source ~/.bashrc; cd [スクリプトのあるディレクトリ]; php -f [PHPファイル名]' > /tmp/initfile; bash --init-file /tmp/initfile" |
こういったことがPHPをコマンドラインで実行する意味と言えるでしょう。
JavaやVB.netの方が処理速度は速い
PHPをコマンドラインで実行するということは、「一連の処理を自動化させる」と言い換えることができます。
ですが、そういったことはJavaやVB.netなどのコンパイルしたプログラムの方が処理速度が早いため、PHPでなければいけない理由ではありません。
PHPをコマンドラインで実行する場合は、「サーバーにJavaをインストールしたくない」「VisualStudio購入のコストをかけたくない」など、それなりの理由を考えながら実施していく必要がありそうです。
PHPのコマンドライン実行
PHPをコマンドラインで実行できる環境や意味の説明はこのくらいにして、早速、コマンドラインでPHPを実行する方法を紹介していきたいと思います。
ここでは、Macのターミナルを使ってPHPを実行する場合に必要となるコマンドをいくつか紹介いたします。
インストールしたPHPにパスを通したら、ターミナルを起動しコマンド入力待ち状態にしておきましょう。
php -v:バージョン確認
まずはPHPのバージョンを調べるコマンドです。
以下のコマンドを実行することでパスが通っているPHPのバージョンを確認することができます。
1 |
$ php -v |
管理しているWebサーバーに応じてバージョンを切り替えている場合は、PHPを実行する前に必ず実行してPHPのバージョンを確認する癖をつけておくとよいでしょう。
echo:メッセージ出力
コンソール上にメッセージを表示させたい場合は「echo」を使います。
PHPスクリプトに記述する場合は以下のように記述します。
1 2 |
<?PHP echo '(メッセージ内容)'.$変数.PHP_EOL; |
シングルクォートかダブルクォートで出力したいメッセージを括り、変数と結合させたい場合は「.」でつなぎます。
最後の「PHP_EOL」は前述したとおり改行するための定数で、こちらもメッセージ内容と結合させたい場合は「.」でつなぎます。
touch():ファイル作成
PHPスクリプトでファイルを作成したい場合は「touch()」を使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?PHP // 作成するファイル名の指定 $file_name = 'file.txt'; // ファイルの存在確認 if( !file_exists($file_name) ){ // ファイル作成 touch( $file_name ); }else{ // すでにファイルが存在する為エラーとする echo 'Warning - ファイルが存在しています。 file name:['.$file_name.']'; exit; } // ファイルのパーティションの変更 chmod( $file_name, 0666 ); echo 'Info - ファイル作成完了。 file name:['.$file_name.']'; |
fwrite():ファイル書き込み
作成したファイルにデータを書き込みたい場合は「fwrite()」を使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?PHP // 書き込みするファイル名の指定 $file_name = 'file.txt'; // ファイルに書き込むデータ $data = 'abcdefg'; //ファイルを開く $fp = fopen('sample.txt', 'ab'); if ($fp){ if (flock($fp, LOCK_EX)){ if (fwrite($fp, $data) === FALSE){ echo 'ファイル書き込みに失敗しました'; }else{ echo $data.'をファイルに書き込みました'; } flock($fp, LOCK_UN); }else{ echo 'ファイルロック失敗'; } } $flag = fclose($fp); if ($flag){ echo 'クローズ'; }else{ echo 'クローズ失敗'; } |
これらを使えばデータベースの抽出結果をCSVファイルに書き出すといったことができるようになります。
どういったデータを抽出したいかを考えながら試してみていただければと思います。
PHPの自動実行
最後に、PHPを自動実行していく方法を紹介したいと思います。
PHPファイル+bat/command
Windowsの場合はbatファイル、Macの場合はcommandファイルで一連の処理を自動化することができます。
基本的には以下のような記述でbatファイルやcommandファイルを作成します。
1 2 3 |
CD [PHPファイルがあるディレクトリ] php -f [PHPファイル名] |
タスクスケジューラ
batファイルを定期的に自動実行させるには「タスクスケジューラ」を使います。
[スタート]メニューの[Windows管理ツール]-[タスクスケジューラ]で設定することができます。
今回は、batファイルを定期実行するには「タスクスケジューラ」を使う、という紹介のみとし、詳しい使い方は割愛させていただきます。
launchctl
commandファイルを定期的に自動実行させるには「launchctl」を使います。
こちらも今回は紹介のみとし、詳しい使い方については別の機会で紹介したいと思います。
まとめ
いかがでしたか。
PHPをコマンドラインで実行させる方法が分かりましたでしょうか。
コマンドライン実行の場合、コンパイルしたプログラム(JavaやVB.Net等)の方が処理速度は速いため、PHPをコマンドライン実行させる意味を考えながら状況に応じて使い分けることが重要ではないかと思います。
今回の記事ではコマンドライン実行の方法のみの説明となり、バッチ化や自動実行については道順を示すのみとなりましたが、今後、PHPをコマンドライン実行させたいと思った時にでも、こちらの記事を思い出していただければ幸いです。