デストラクタでファイルに書き込むと挙動不審? - PHPプロ!Q&A掲示板

1381

  • 200P

デストラクタでファイルに書き込むと挙動不審?

質問日時 / 2008年8月11日 17:00 (最終編集:8月12日 19:25)    回答数 / 5件

Questioner:  NurseAngel  このエントリーをはてなブックマークに追加 

キーワード / デストラクタ    __destruct   

<?phpとかreturnとかそこらへんは省略しています。


fileReader.class.php
  1. class fileReaderClass{
  2.  
  3.       protected $file_name=NULL;
  4.       protected $contents=NULL;
  5.  
  6.       public function __construct($file_name){
  7.             $this->file_name=$file_name;
  8.       }
  9.       
  10.       public function putContents($contents){
  11.             $this->contents.=$contents;
  12.       }
  13.       
  14.       public function __destruct(){
  15.             $ret=file_put_contents($this->file_name,$this->contents);
  16.  
  17.             var_dump($this->file_name,$ret,file_get_contents($this->file_name));
  18.       }
  19. }

sample.php
  1. require_once('./fileReader.class.php');
  2.       $fp=new fileReaderClass('file.txt');
  3.       $fp->putContents('abcdefg');


__constructでファイル名を指定、putContentsで中身を指定、__destructでファイルに保存しています。
var_dumpの時点では以下のように正しく表示されます。

$this->file_name→string(8) "file.txt"
$ret→int(7)
file_get_contents($this->file_name)→string(7) "abcdefg" 


ところが実際には保存されていません。


試してみました。

file_put_contentsをメンバ変数ではなく直書き
fileReader.class.php
  1. $ret=file_put_contents("file.txt",$this->contents);

保存される(※勘違い。実際には保存されません//2008/08/12)

・newをフルパスに
sample.php
  1. $fp=new fileReaderClass('C:\xampp\htdocs\file.txt');

保存される

・デストラクタではなく普通のメソッドにする
fileReader.class.php
  1. public function destruct(){
  2.             $ret=file_put_contents($this->file_name,$this->contents);
  3.       }

sample.php
  1. require_once('./fileReader.class.php');
  2.       $fp=new fileReaderClass('file.txt');
  3.       $fp->putContents('abcdefg');
  4.       $fp->destruct();


保存される


中でも特に、直書きだとOKなのに$this->file_nameと書くとアウトな原因がまったくわからないのですが、
何か理由があるのでしょうか?


XAMPP1.6.6a、PHP: 5.2.5、Apache/2.2.8 (Win32)

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┗A01pascal予想通り、書き込み自体は正常にされていました。 た
 ┗A01-1kaitau横からですが補足。 パスについてですが、デストラ
  ┗A01-1-1NurseAngel適当な場所で unset($fp); するとカレントディレク
   ┗A01-1-1-1kaitau> #しかしそうすると > #file_put_contents("file.tx
    ┗A01-1-1-1-1NurseAngel勘違いでした。 ぐばぁ おそらくunsetとかで試し

回答一覧

並び替え:

A01 満足
answererpascal [8月11日 17:30]

予想通り、書き込み自体は正常にされていました。
ただ、その場所が予想外でした。

「C:\xampplite」にインストールしたXAMMP Lite 1.65の環境で試したのですが、「file.txt」が作成されたのは「C:\xampplite\apache」でした。
ドキュメントルートかPHPのインストールディレクトリあたりかなぁと思っていたのですが・・・

「ファイルを作る時はなるべくフルパスで指定しよう!」ということのようです。

この意見に回答する

ツリーへ TOPへ

A01-1 満足
replyerkaitau [8月11日 17:39] (最終編集:8月11日 17:50)

横からですが補足。

パスについてですが、デストラクタの挙動が不審というわけではなく、
スクリプト終了時の作業ディレクトリが想定外、という事ですね。

PHPのデストラクタは、スクリプト実行中に特にオブジェクトが
解放されない場合は、スクリプト終了時の処理で
コールされることになりますから、

デストラクタの中に
var_dump(getcwd());
を入れてから、

呼び出し側を以下の2パターンで挙動を確認してみてください。

  1. sample1.php
  2. <?php
  3. require_once('./fileReader.class.php');
  4.       $fp=new fileReaderClass('file.txt');
  5.       $fp->putContents('abcdefg');
  6. //特になにもせず、スクリプト終了時の処理に任せる
  7. ?>

  1. sample2.php
  2. <?php
  3. require_once('./fileReader.class.php');
  4.       $fp=new fileReaderClass('file.txt');
  5.       $fp->putContents('abcdefg');
  6. //明示的に破棄して、スクリプト終了前にデストラクタが走るようにする
  7.       $fp = null;
  8. ?>

まぁ、明示的に破棄することを前提にクラスをコーディングすると
いろいろやっかいなことになるので、フルパス指定か、もしくは
コンストラクタで一回フルパスに翻訳してあげる作業をした方が安全でしょうねぇ。

====
追記。
ちなみに、マニュアルにシャットダウン時のデストラクタの作業ディレクトリについて注意がありますね。
http://www.php.net/manual/ja/language.oop5.decon.php

この意見に回答する

ツリーへ TOPへ

A01-1-1
replyerNurseAngel [8月11日 18:07] (最終編集:8月11日 18:09)

適当な場所で
unset($fp);
するとカレントディレクトリに保存されました。
スクリプト中と終了後で挙動が違うのは怖いなあ・・・


>「C:\xampplite」にインストールしたXAMMP Lite 1.65の環境で試したのですが、「file.txt」が作成されたのは「C:\xampplite\apache」でした。

↓で見つかりました。
C:\xampp\apache\file.txt

検索したはずなのになあ・・・orz


ありがとうございました。






#しかしそうすると
#file_put_contents("file.txt",$this->contents);
#がOKな理由がますますわからない

この意見に回答する

ツリーへ TOPへ

A01-1-1-1 満足
replyerkaitau [8月11日 18:21]

> #しかしそうすると
> #file_put_contents("file.txt",$this->contents);
> #がOKな理由がますますわからない 

こちらではその現象は確認できなかったです。きっちりApache直下にできました。

同じ試行を何回か繰り返してると、実は確認してるのが別の試行のものだった、
というのがわりとありがちだったりします。
保存するときにタイムスタンプとかユニークなIDなんかを付与して照合の材料に加えて
再確認するといいかもしれません。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1
replyerNurseAngel [8月12日 19:24]

勘違いでした。
ぐばぁ

おそらくunsetとかで試した時のがまざってたのでしょう。
確認って大事だね☆


ありがとうございました。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
動的なURLを静的に見せる方法
 このエントリーをはてなブックマークに追加 
A
普通に考えて、mod_rewrite でしょうね。 http://www.nishishi.com/blog/2006/01/mod_rewrite_url.html...

>>続きを読む

GETのままでは検索エンジンのロボットが拾ってくれなかったためにSEO対策として有効だと言われていますね。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)