• ベストアンサー

fopenしてくれない。。。

こんにちは。PHP初級者です。 postgresqlに入れたデータをCSVファイルに書き込んで、出力してみたいと思って以下のプログラムを作ってみました。 $file_name ="insatu.csv"; //データベースから呼び出し以下の$arrayへいれるデータは省略します。 //今回は1行のみのデータを入力プログラムになってますが、本当は何行もやるプログラムとなってます。 $array = compact("a","b","c","d","e","f","g","h","i","j","k","l"); $string = implode("," , $array); $file = fopen($file_name, "a") or die ("openエラー $file_name"); flock($file, LOCK_EX); fputs($file, $string."\n"); flock($file, LOCK_UN); fclose($file); $file = fopen($file_name, "r"); while($array = fgetcsv($file, 1000, ",")){ echo "<hr> \n"; for($i=0; $i< count($array); $i++){ echo $array[$i]."<br>"; } } fclose($file); なぜか最初の fopenで dieの方へ行って OPENエラーメッセージが出てきます。 この作業をするためには何かあらかじめ入れなくてはいけない構文とかあるんでしょうか?何か間違っていますでしょうか? それともphp.iniを設定するとかしなくてはいけないんでしょうか? php5を使用してますが、php.iniやphp.ini-distはともに見つからず。 困り果ててます。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

>$file = fopen($file_name, "a") or die ("openエラー $file_name"); こういう書き方をしてはいけません。この行がどう動くかは処理系に依存し、環境によって結果が異なります。 言語の仕様では「or演算子は、右辺と左辺のどちらが先に評価されるかは、処理系に依存し、どちらを先に評価しても構わない。また、右辺と左辺のどちらか一方が成り立った場合、もう片方の評価が省略されるかどうかも、処理系に依存する」と言う事になっています。 つまり、同じ言語でも、バージョンが違ったりプラットホームが違ったりすると、右辺が先に処理されたり、左辺が先に処理されたり、評価結果に関わらず常に両辺が評価されたりします。 で、質問者さんの環境では「右辺が先に処理される」か「常に両辺が評価される」かどちらかの仕様になっている為、fopen関数を評価する前にdie関数が評価されます。 簡単に言えば「fopen関数が偽になった時だけdie関数が呼ばれる、と言う保証はどこにもない。そういうツモリで居たら痛い目に遭う」と言う事です。 なお、敢えてワザとこういう書き方をして「動作中の言語の種類とバージョンをリアルタイムに確かめる」と言う事もあるので「絶対にこう書いちゃダメ」と言う訳ではありません。

imapshig
質問者

お礼

chie65536様、早速のお返事どうもありがとうございます。 試してみたところ無事dieの方を通らない形になりました。 題目としてはこれで「スッキリ!」のはずなんですが、 今回のプログラムの後半部分のwhileの指令が行われてないようです。 #本来ならcsvファイルに入ったデータが画面に出力され、<hr>で区切られるように設定してあるつもりです。 そして、ファイル名(insatu.csv)もどうも作られてないようです。 どうしてなんでしょうか? $file_name ="insatu.csv"; $array = compact("a","b","c","d","e","f","g","h","i","j","k","l"); $string = implode("," , $array); $file = fopen($file_name, "a") or die ("openエラー $file_name"); flock($file, LOCK_EX); fputs($file, $string."\n"); flock($file, LOCK_UN); fclose($file); //ここから $file = fopen($file_name, "r"); while($array = fgetcsv($file, 1000, ",")){ echo "<hr> \n"; for($i=0; $i< count($array); $i++){ echo $array[$i]."<br>"; } } fclose($file); 続けざまの質問で恐縮です。

その他の回答 (1)

  • tany180sx
  • ベストアンサー率63% (239/379)
回答No.2

気になったのですが、 $array = compact("a", ...); はちゃんと作成されていますか? 普通はarrayで配列を作成しますが。 insatu.csvが作成されてないのであればfopen~fcloseが失敗しているのでは? flockをコメントアウトしてerror_reporting(E_ALL);で確認してみては。

imapshig
質問者

お礼

tany180sx様 ご回答ありがとうございます。 早速試してみました。 error_reporting(E_ALL); $file_name ="insatu.csv"; $array = compact("a","b","c","d","e","f","g","h","i","j","k","l"); $string = implode("," , $array); echo "$string <br>\n"; $file = @fopen($file_name, "a"); // 指示通りflock(2つ)をコメントアウトしてみました。 // flock($file, LOCK_EX); fputs($file, $string."\n"); // flock($file, LOCK_UN); fclose($file); $file = fopen($file_name, "r"); while($array = fgetcsv($file, 1000, ",")){ echo "<hr>n"; for($i=0; $i< count($array); $i++){ echo $array[$i]."<br>"; } } fclose($file); これで動かしてみたんですが、 echoの$stringが表示されるだけです。。。 $stringの内容は求めているものなので問題はありませんでした。 うーむ。。。なんででしょうか。。。?

imapshig
質問者

補足

質問者です。 なんと解決しました!! 原因は・・・パーミッションの問題でした。 作ってあったディレクトリーのオーナーがapacheでなかったのが原因でした。 chown で変更したら無事できました。 お騒がせいたしました。 お礼の方ですが、回答順とさせていただきます。 どうもありがとうございました。

関連するQ&A