PHPからcronの設定
解決済
回答 3
投稿
- 評価
- クリップ 1
- VIEW 9,354
linuxなどを一切使わずPHPからのみの操作でクローンの設定をしたくて色々と試しましたが、そのやり方が分かりませんので、ご教授頂きたいです。
設定したいクローンの中身は、DBのflag(カラム名です)が、0、のモノを1分毎に削除する、という命令になります。
以下に当然のことながら動作はしませんが、一応私の考えた、設計の手順と、その手順を下に実際に書いたコードを記載いたします。
ご参考になれば幸いです。
以下が、設計の手順となります。
1, flag(カラム名です)が『0』のデータをDBから削除する、という命令を記述したPHPファイルの作成
2, cronの中身を書いたテキストファイルの作成
3, テキストファイルに書いたcronの中身を、system関数を用いて、設定する
以下が、上記の設計の手順を下に実際に書いたコードとなります。
(共通設定ファイルの記述は省略しています。)
●1, flag(カラム名です)が『0』のデータをDBから削除する、という命令を記述したPHPファイルの作成
・ファイル名・・・toroku_delete.php
・ファイルの中身↓
<?php
$toroku_delete = "DELETE FROM members WHERE flag=0";
mysql_query($toroku_delete);
?>
●2, cronの中身を書いたテキストファイルの作成
・ファイル名・・・cron_content.txt
・ファイルの中身↓
*/1 * * * * /toroku_delete.php
●3, テキストファイルに書いたcronの中身を、system関数を用いて、設定する
・ファイル名・・・cron.php
・ファイルの中身↓
<?php
$command = "crontab /cron_content.txt";
system($command);
?>
お手数ですが、何卒よろしくお願いいたします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
>とのアドバイスを頂きましたが、どうゆう意味なのか分かりませんでした。
おそらくcronにジョブ(1分毎にtoroku_delete.phpを実行する仕事)が登録されてないか、環境変数が読まれてないということか、そもそもcronを実行するプログラム(crond)が動作してないということをおっしゃっているのだと思います。
cronを実行するプログラム(crond)が動作しているか確認してみていただけますか。
下のコマンドをroot権限で実行してください。実行中と出力されていれば、動作しています。
# /etc/rc.d/init.d/crond status
crondが動作しているならば、cron.phpを実行した後に、以下のコマンドを実行すると、cronにジョブが登録されている事が確認できるのですが、登録されているか確認していただけますか。
$ crontab -l
登録されていたら、以下のコマンドで、phpがインストールされているパスを調べてみましょう。
$ which php
そして、以下のコマンドを実行して、cronからtoroku_delete.phpが起動できるか、確認してみましょう。
直接crontabを書き換えます。そして実行結果(エラーも含めて)をファイルに書き起こしてみます。
$ crontab -e
*/1 * * * * /usr/bin/php(※phpがインストールされているパス) /toroku_delete.php > /hoge.txt 2>&1
これで、実行されるのを待ちます。実行されたら、/hoge.txtになんらかの文字が出力されていますでしょうか。
>/usr/bin/php
>/usr/local/bin/php
>これらを付ける意味を全く分かっておりません。
これは、phpというプログラムのパスを指定しています。
なぜそんなことするかというと、cronで実行すると、環境変数が設定されないので、OSから見ると、phpというプログラムが見つけられない場合があるからです。(これは、ありがちなミスです)
ですので、絶対パスで指定する必要があります。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
system関数の箇所を以下に書き換えて、エラー出力または標準出力内容を出力できますでしょうか。
$output = $retval = null;
exec($command, $output, $retval);
if ($retval != "0") {
echo implode($output, "\n");
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
$command = "crontab /cron_content.txt";ですが、/ の直下にちゃんと ファイルはあるのでしょうか?
「フルパス」という言葉の意味はわかりますか?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.19%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2015/01/18 21:40
実は、linuxなどを一切使ってはならず、PHPからのみの操作で全て操作し作成する、という制約がありますので、コマンドで確認することが出来ません。
ですが、色々とご説明して頂けたおかげで、徐々に問題解決の兆しが見えてきたように思えます。
本当にありがとうございました。
それと、そもそも、クーロン設定の手順として、linuxなどを一切使わず、ゼロからPHPからのみの操作で作成する、といった場合、私が最初の質問で記載した以下の手順だけでは足りないのでしょうか?
--質問で記載した手順--
●1, flag(カラム名です)が『0』のデータをDBから削除する、という命令を記述したPHPファイルの作成
・ファイル名・・・toroku_delete.php
・ファイルの中身↓
<?php
$toroku_delete = "DELETE FROM members WHERE flag=0";
mysql_query($toroku_delete);
?>
●2, cronの中身を書いたテキストファイルの作成
・ファイル名・・・cron_content.txt
・ファイルの中身↓
*/1 * * * * /toroku_delete.php
●3, テキストファイルに書いたcronの中身を、system関数を用いて、設定する
・ファイル名・・・cron.php
・ファイルの中身↓
<?php
$command = "crontab /cron_content.txt";
system($command);
?>
--質問で記載した手順--
usop様のアドバイスをお聞きしていますと、私の考えた手順において、そもそもジョブ登録など、そういった所が抜けているのではないか、と思いました。
ここまでご丁寧にお答え頂いている上に大変恐縮ですが、もし、可能であれば、ご回答頂けますと幸いです。
何卒よろしくお願いいたします。
2015/01/19 07:41
なるほど。今更ながら質問の意味がわかりました。すみません。
できます。(普通実装しないと思いますが、課題かなんかでしょうか)
おそらくおっしゃっている質問の真意は、「phpでcronもどきを実装する」ということでしょう。
私が、真っ先に思いつく実装方法ですが、
cron.phpで、無限ループをつくり、その中で時間を計測して、指定した時間毎にtoroku_delete.phpをsystem関数などで実行すれば良いと思います。
2015/01/19 08:12
語句訂正です。
△「phpでcronもどきを実装する」
◯「phpのジョブスケジューラを実装する」
あと、実行するジョブが、実はtoroku_delete.phpだけでなく、他にも例えば3分毎に実行する別のジョブが多数いたりするのであれば、僕もphpでは使ったことないですが、phpで実装されているジョブスケジューラをネットで探してきた方がいいです。無限ループでsystem関数を使うような実装は、単純な仕様であれば良いですが、実装に気を使わなければならない箇所が結構な数あります。
2015/01/19 23:44
ご丁寧に回答して頂きありがとうございます。
私の理解不足でして、linuxを使ったらダメなのではなく、ターミナルなどを用いてlinuxを使ってはダメ、というだけで、むしろ、PHPファイル・テキストファイルを用いて、linuxコマンドを使う、ということでした。
ですので、以前ご提案頂いたlinuxを使った方法で、現状の確認することが出来ました。
まず、crondは動作していました。
crontab -l、では、
*/1 * * * * /toroku_delete.php
以上のジョブが登録されていました。
which php、では、
/usr/local/bin/php
以上がPHPのパスであることが判明しました。
そして、ここまでの情報で問題となっている箇所が、登録されているジョブだということが分かりました。
*/1 * * * * /toroku_delete.php
ではなく、
*/1 * * * * /usr/local/bin/php /toroku_delete.php
上記のようにしなくてはなりません。
この場合、ターミナルなどを使って、linuxを使う場合は、
$ crontab -e
*/1 * * * * /usr/local/bin/php /toroku_delete.php
上記のようにコマンドを入力すれば良いと思うのですが、PHPからlinuxコマンドを使う場合にどうやってやれば良いかが分かりません。
私は、以下の手順でジョブの編集を試みましたが失敗しました。
●1, cronの中身を書いたテキストファイルの作成
・ファイル名・・・cron_content.txt
・ファイルの中身↓
*/1 * * * * /usr/local/bin/php /toroku_delete.php
●2, テキストファイルに書いたcronの中身を、system関数を用いて、設定する
・ファイル名・・・cron.php
・ファイルの中身↓
<?php
system("crontab /cron_content.txt");
?>
何卒、ジョブを編集する有効な方法があれば、ご指南頂けますと幸いです。
ジョブスケジューラの実装に関しても、今後使うことがあると思いますので、知ることが出来て良かったです。
ありがとうございました。
2015/01/20 07:27
>*/1 * * * * /usr/local/bin/php /toroku_delete.php
>上記のようにコマンドを入力すれば良いと思うのですが、PHPからlinuxコマンドを使う場合にどうやってやれば良いかが分かりません。
すみませんが、もう一度、cron.phpのsystem関数の箇所を以下のソースで書き直して実行していただいてもよろしいでしょうか。
$output = $retval = null;
exec("$command 2>&1", $output, $retval);
if ($retval != "0") {
echo implode($output, "\n");
} else {
echo "成功"
}
前回のだとエラー内容が、$outputに入らなかったので、修正しました。(else文は念のため)
仕様がわからないので、おききしたいのですが、
cron.phpはどうやって起動するのでしょうか。
http://XXXX.com/cron.php
上記の様なURLをブラウザでアクセスして起動する方法でしょうか。
2015/01/20 07:45
X echo "成功"
○ echo "成功";
2015/01/20 12:48
ご返信ありがとうございます。
申し上げて頂いたソースに書き直して実行いたしましたところ、4パターンの結果が見られました
crontabの後ろが、1、2は絶対パスのパターンで、3、4はフルパスのパターンとなります。
1、$command = "crontab /cron_content.txt"; の場合
・結果↓
/cron_content.txt: No such file or directory
2、$command = "crontab /cron_content.txt
"; の場合(1との違いはファイルの最後を改行していることです。)
・結果↓
成功
3、$command = "crontab /home/co-27.3919.com/public_html/cron_content.txt"; の場合
・結果↓
"フルパス/cron_content.txt":1: premature EOF errors in crontab file, can't install.
4、$command = "crontab /home/co-27.3919.com/public_html/cron_content.txt
"; の場合(3との違いはファイルの最後を改行していることです。)
・結果↓
成功
ファイルの最後に、改行を入れると、絶対パスのパターンでもフルパスのパターンでも【成功】と出ました。
しかし、成功、と出てたとしても
echo system('crontab -l');
以上でクーロンタブの中身を確認しても
*/1 * * * * /toroku_delete.php
のままで、
*/1 * * * * /usr/local/bin/php /toroku_delete.php
上記のような中身に書き換えが行われていません。
お手数をおかけして申し訳ございませんが、何卒お力添え頂けますと幸いです。
cron.phpに関しては、URLをブラウザでアクセスして起動しております。
2015/01/20 15:38
system関数の引数に改行は入れないください。「2>&1」を追加したことで、弊害がでました。おそらく、
$ crontab /cron_content.txt; 2>&1
と解釈されたのではないでしょうか。そうなると、コマンドの実行ステータスは、0になってしまいます。
>"フルパス/cron_content.txt":1: premature EOF errors in crontab file, can't install.
cron_content.txtの最後に改行を追加してみてください。
2015/01/20 16:09
cron_content.txtの改行コードもLFになっているか確認してください。(ファイルの内容の話です。)
2015/01/20 16:43
申し上げて頂きました通り、
$command = "crontab フルパス/cron_content.txt";
以上で、cron_content.txtの最後を改行すると、
成功
と出て、ジョブを登録出来ました。
ただ、なぜかcron_content.txtの中身が、重複して登録されてしまいます。
本来であれば、
*/1 * * * * /usr/local/bin/php /toroku_delete.php
となって欲しいのですが、
*/1 * * * * /usr/local/bin/php /toroku_delete.php */1 * * * * /usr/local/bin/php /toroku_delete.php
以上のように一つ多く登録されてしまいます。
ジョブも実行されることはありません。
改行コードは、od -cコマンドを使って確認したところ、
0000000 * / 1 * * * * / u s r 0000020 / l o c a l / b i n / p h p / 0000040 t o r o k u _ d e l e t e . p h 0000060 p \n 0000062 0000062
以上のように出てきまして、改行コードがLFである目印である、【\n】があるので、LFであると思われます。
残る問題点としては、
・ジョブが重複されて登録されてしまうこと
・登録されたジョブが実行されないこと
の2点のような気がします。
大変お手数をおかけしますが、もし可能であれば、引き続き問題の解決にお力添え頂けますと幸いです。
何卒よろしくお願いいたします。
2015/01/20 17:46
これは明確にはわかりませんが、crontab -lの出力結果をechoなどで、2重に出力しているとか、cron_content.txtの記述に立て続けに2個書いてるなど、ミスしているだけだと思います。
>・登録されたジョブが実行されないこと
*/1 * * * * /usr/local/bin/php (フルパス)/toroku_delete.php
として見てください。
2015/01/20 20:58
おかげさまで、クーロンの設定を完了させることが出来ました。
ご指摘頂いた通り、パスが原因でした。
重複に関してもご指摘頂いた通りで、echoが原因でした。
このたびは、本当に最後までご親切に対応してくださりありがとうございました。
また機会がございましたら何卒よろしくお願いいたします。
ありがとうございました。