###環境
Windows10 / Apache 2.4系 / MySQL 5.5系 / CakePHP 2.7.5
###前提・実現したいこと
CakePHPで特定のURLでのアクセスをトリガーとした、非同期でのバッチ処理を実装しています。
処理の流れは以下の通りです。
{$method} は実行する function 名
2. BatchesController 内の function action 内で、
"Console\cake batch {$method}" を非同期で実行
具体的には popen("start Console\cake batch {$method}", "r") という形で、
外部コマンドを利用して start で非同期を実施します。
3. BatchShell 内に定義した function {$method} に処理を記載
###発生している問題・エラーメッセージ
BatchShell 内の function {$method} 内で DB へのアクセスが発生するプログラムがあるのですが、
どうやら、DB の設定情報が取得できないようで、DB へのアクセスができない状態が発生しています。
以下のエラーメッセージを確認しました。
Database connection "Mysql" is missing, or could not be created.
コマンドプロンプトを立ち上げて、
Console\cake batch {$method}
と直接実行すれば正常に動作するので、
popen を経由することで発生しているような気がします。
exec、system 等、他の外部コマンドでも上記のエラーメッセージが表示されたので、
外部コマンド経由での実行が原因かもしれない、というところまでは分かっています。
###試したこと
BatchShell 内の function {$method} 内で $this->log("hoge");
とすると、
ログには出力されるので、function {$method} までは処理が到達しています。
ただ、以下のような DB へのアクセスが発生するようなプログラムを書くと上記のエラーメッセージが表示されます。
$this->{Model}->{function}; (実際に存在する関数)
DB の接続情報はどうなっているのかと思い、
以下も試してみましたが、同様に上記のエラーメッセージが表示されます。
・$this->{Model}->getDataSource();
ソースを追いかけていくと、Mysql.php 内の以下の function 内に原因がありました。
public function enabled() { return in_array('mysql', PDO::getAvailableDrivers()); }
コマンドプロンプトからの直接実行では、
PDO::getAvailableDrivers() の中身が以下になるのに対して、
Array ( [0] => mysql [1] => odbc )
popen 経由で実行すると PDO::getAvailableDrivers() の中身は空になっていました。
なぜ popen 経由では PDO::getAvailableDrivers() が空になるのかが分かれば解決しそうなのですが、
ネットで色々情報を探しても解決策が見つからず八方ふさがり状態です。
お知恵を拝借していただければありがたいです。
追加で、以下の2つファイルを用意して検証しました。
・check_pdo.php
<?php echo '<pre>'; var_dump('ACTION!'); // この文字列が表示されれば check_pdo.php 自体は実行されている var_dump(PDO::getAvailableDrivers()); echo '</pre>'; ?>
・check_pdo_via_popen.php : chekc_pdo.php を popen で呼び出すファイル
<?php $cmd = 'php {ファイルまでのパス}/check_pdo.php'; $fp = popen($cmd, 'r'); print '<pre>'; while ($read = fread($fp, 2096)) { echo $read; } print '</pre>'; pclose($fp); ?>
コマンドプロンプトから check_pdo.php を php コマンドで直接実行
実行コマンド
C:\Windows\SysWOW64> php {ファイルまでのパス}/check_pdo.php
※ php のパスは通してあります。
結果
<pre>string(7) "ACTION!" array(2) { [0]=> string(5) "mysql" [1]=> string(4) "odbc" } </pre>
Web ブラウザから直接 check_pdo.php にアクセス(CakePHP は経由せず)
結果
string(7) "ACTION!" array(2) { [0]=> string(5) "mysql" [1]=> string(4) "odbc" }
コマンドプロンプトから check_pdo_via_popen.php を php コマンドで直接実行
実行コマンド
C:\Windows\SysWOW64> php {ファイルまでのパス}/check_pdo_via_popen.php
※ php のパスは通してあります。
結果
<pre><pre>string(7) "ACTION!" array(2) { [0]=> string(5) "mysql" [1]=> string(4) "odbc" } </pre></pre>
Web ブラウザから直接 check_pdo_via_popen.php にアクセス(CakePHP は経由せず)
結果
string(7) "ACTION!" array(0) { }
コマンドプロンプトからであれば popen を利用しても表示されたので、
原因は popen ではないようです。
最初の質問と共通するのは Webブラウザからアクセスだと空になる ということですので、
Apache ユーザで実行すると特定の条件下で発生する?辺りなのかと踏んでいます。
引き続き、よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー