ちょっと先の未来クイズ第4問

お世話になっております。
画像をアップロード(ディレクトリ生成&そのディレクトリ内に保存)した後、安易な考えか、アップロードし直すという流れのとき、一旦生成したディレクトリを削除し、新たにディレクトリを生成、そしてその中に保存したいと考えておりますが、rmdir関数ではファイルが存在した場合、削除が出来ないと思いますが、ファイルが存在しても全て削除できるようにするには どのようにすれば良いのでしょうか?

一旦ファイルを削除して・・とも考えたのですが、そのような場合、やはりセッションを用いてファイル名を引き渡す?という流れになるのでしょうか?

/* ディレクトリ削除メソッド */
function deleteDir($rootPath){

$strDir = opendir($rootPath);
while($strFile = readdir($strDir)){
if($strFile != '.' && $strFile != '..'){ //ディレクトリでない場合のみ
unlink($rootPath.'/'.$strFile);
}
}
rmdir($rootPath);
}
deleteDir('/home/httpd/vhosts/test.aaa.com/test/');

このようなコードがとあるサイトで紹介されておりましたが、やはりこれもセッションが必要なのかな?などと・・・お恥ずかしい質問ばかりで恐縮ですが、ご教授頂ければ幸いです。宜しくお願い致します。

A 回答 (5件)

修正したコード拝見しました。



>deleteDir("/home/public_html/member/check/$nam/");
この行が、functionの中に入っちゃってますね。
カッコの外に出してあげて下さい。

つまり、最後の2行(deleteDirの行と、mkdirの行)は、
どのカッコの中にも入ってない状態にして下さい。

これでうまく行くと思います。

deleteDirの行では、
>function deleteDir($rootPath){
で作成した「deleteDir」という関数を、
>deleteDir("/home/public_html/member/check/$nam/");
の行で呼び出して実行しています。

functionのあとのカッコで囲まれた部分は全て関数とみなされるため、
呼び出す部分が関数自身の中に入ってしまっていると、
結果的に「deleteDir」という関数は
どこからも呼び出されていないことになります。

「deleteDir」関数は、呼び出されて初めて実行されますから、
呼び出されていない=実行されていない=つまりディレクトリは削除されていない
なので、同名でmkdirしようとすると「既にファイルがある」と言われてしまいます。
    • good
    • 0
この回答へのお礼

giraffa96様

こんにちは。お忙しい中、順を追っての説明を有難う御座います。初心者の私にとって、とても判りやすく勉強になりました。

報告が後になってしまいましたが、今回のアドバイスの基、無事解決させる事が出来ました。
本当に有難う御座いました!

お礼日時:2006/06/22 16:56

PHP関数の中には再帰的なディレクトリ削除関数は提供されていないのですね。

安全の為かな。

横着な方法として、プログラム関数を使う手があります。
当然、削除するファイルの実行権限をPHPが持っているという前提です。

UNIX系の場合
$cmd = "rm -rf TARGET_DIR";
Windowsの場合
$cmd = "rmdir /S /Q TARGET_DIR";

exec($cmd);

どうでしょうか?

参考URL:http://taketan.mydns.jp/xoops/modules/bwiki/?PHP
    • good
    • 0
この回答へのお礼

taketan_mydns_jp様

はじめまして、こんにちは。ご親切にサイトまでご紹介いただき・・・と思ったら、taketan_mydns_jp様のサイトだったのですね~!これまで何度か訪問させて頂いております。有意義な情報、およびサイトを有難う御座いました。

お礼日時:2006/06/22 16:51

ふたたび、こんにちは。



だいぶ進んでるみたいですね。
エラーはそのまま訳しても良く判らないことが多いですよね。

ちょっと長くなりますがひとつづつやっていけば必ずうまく行きますので、
根気良くやってみてくださいね。

まず、ここを見てみて下さい。
>deleteDir('/home/public_html/member/check/$nam/');
ここのパスはシングルクォーテーションで囲まれていますが、
シングルクォーテーションで囲まれた部分は全て文字列として認識されてしまいます。

つまり、$namには指定されたディレクトリ名を代入したいのに
そうではなく「$namという名前のディレクトリ」だと認識してしまいます。

No3に、「No such file or directory」(ファイルもしくはディレクトリがない)
と出ているのは、これが原因です。
また、ここでディレクトリが削除できないまま同名でmkdirしようとするので
No4で「File exists」(ファイルがあります)と言われてしまいます。

こういう場合は、ダブルクォーテーションを使って
deleteDir("C:/Apache/htdocs/test/$nam/");
と書くか、もしくは
deleteDir('C:/Apache/htdocs/test/'.$nam.'/');
と書きましょう。

最後のmkdirのところも同じです。
今はダブルクォーテーションなのでそのままでも動きます。
(できれば統一したほうが良いです。)

ここで一度試しに実行してみてください。
たぶんエラーの状態が少し変わったと思います。

では、No1にあたる、
>$strDir = opendir($rootPath);
を見てみてください。
ここで、文字通りディレクトリをOPENしているわけですが、
簡単に言うと、OPENしたら、CLOSEする必要があります。
OPENしたままrmdirしようとするとエラーになります。

ですので、
>rmdir($rootPath);
の前にCLOSEしましょう。
closedir($strDir);
と一行入れてあげて下さい。

これで一通り動くようになったはずです。
試しに実行してみて下さい。
一度消して、同じ名前でまた作るのであれば
見た目は中身のファイルが消えただけ、のように見えると思います。

ここからは、
やってもやらなくても変わらないように見えるかもしれませんが
やったほうが良いと思うことを書いておきます。

まず、さきほどの
>$strDir = opendir($rootPath);
ですが、opendirに失敗する可能性もあります。
opendirに失敗した場合、そのあとの処理はスキップさせましょう。
この行を
if($strDir = opendir($rootPath)){
に変えて、このifは
>rmdir($rootPath);
の次の行で閉じましょう。

それともっと重要なのが、質問者様もお気づきの通り、
ディレクトリがなかったら、の処理です。

例えば$namディレクトリが存在するかどうかは、is_dir関数を使います。
is_dir($nam)
とやって、存在すればTRUE、存在しなければFALSEが返ります。

>function deleteDir($rootPath){
の直後、この関数の一番初めに
if(is_dir($rootPath)){
を入れて、最後のfunction終わりの}の直前で閉じましょう。

これで実行してみて下さい。

だいぶ長文になってしまったので、どこか判りにくかったり、
うまく行かなかったりしたらまた聞いて下さいね。

この回答への補足

giraffa96様

おはよう御座います。夜遅くのお返事有難う御座います。大変分かり易いご丁寧なご指導に感謝です!
全て「なるほど...」と思うものばかりで大変勉強させられます。(感謝)

ところで、現在のコードは以下の通りですが、mkdirのところで「ファイルが存在する」といったエラーが表示され、再度アップロードしたファイルが既存のディレクトリ($nam)に追加で登録される、といった状況です。
ご指導の通り記述してみたつもりですが…引き続きご指導頂ければ幸いです。(実際はコード中にコメントとして、giraffa96様に教えていただいた説明も記載していますが、以下は見やすくするため削除しているので、削除する際、コメントではないところも削除しているかも…です)


$nam=$_POST['id'];
function deleteDir($rootPath){
if(is_dir($rootPath)){
if($strDir = opendir($rootPath)){
while($strFile = readdir($strDir)){
if($strFile != '.' && $strFile != '..'){unlink($rootPath.'/'.$strFile);
}
}
closedir($strDir);//opendirでオープンしているためクローズする
rmdir($rootPath);
}
}
deleteDir("/home/public_html/member/check/$nam/");
}
mkdir ("/home/public_html/member/check/$nam",0755);

補足日時:2006/06/22 09:50
    • good
    • 0

こんにちは。



ちょっと気になったのは、コード内の以下の部分
>deleteDir('/home/httpd/vhosts/test.aaa.com/test/');
「deleteDir」の「r」が、全角になっていませんか?

Fatal error: Call to undefined function
とは、存在しない関数が呼び出されていますというエラーです。
つまり、「deleteDirという関数はありませんよ」という意味です。

function deleteDir($rootPath){
↑の部分でdeleteDirという関数を作っていますので、
 うまく行っていれば、「deleteDirという関数はありませんよ」
 というエラーは出ないハズです。

もしこのエラー文、そのままコピー&ペーストされたものでしたら
恐らく「r」が全角になっているのが原因だと思います。

まずはこれを直してみて下さいね。


あと、はじめに
>$rootPath = "/home/httpd/vhosts/test.aaa.com/test/';
を入れてみたとのことですが、これを入れたのであれば
関数を呼び出す以下の部分
>deleteDir('/home/httpd/vhosts/test.aaa.com/test/');
は、
>deleteDir($rootPath);
に変更しましょう。

この回答への補足

giraffa96様

こんにちは。引き続きご丁寧なアドバイスを有難う御座います。
「r」ですが…ご指摘通り全角になっていました!素晴らしい。。

少々長文になってしまうので補足欄にて失礼しますが、現在の実際のコードは、

$nam=$_POST['id']; //フォームで入力した文字をディレクトリ名としている
function deleteDir($rootPath){

$strDir = opendir($rootPath); //No1
while($strFile = readdir($strDir)){ //No2
if($strFile != '.' && $strFile != '..'){ //ディレクトリでない場合のみ
unlink($rootPath.'/'.$strFile);
}
}
rmdir($rootPath); //No3
}
deleteDir('/home/public_html/member/check/$nam/');

mkdir ("/home/public_html/member/check/$nam",0755); //No4

と、なっております($namディレクトリを削除し、新たに生成したい。)以上を実際に動かしてみると、
No1に、failed to open dir: Invalid argumentというエラー。
No2に、readdir(): supplied argument is not a valid Directory resource
No3に、No such file or directory
No41に、File exists
というエラーが出ています。訳してみたものの、何処が可笑しいのかが判らなくて…お手数お掛けいたしますが、引き続きご指導頂けたら幸いです。

追伸:今回のコードの最初に、$namというディレクトリが存在するか?というコードも設定したいのですが、このような場合、どういった関数になるのでしょうか?色々と調べてはいるものの、初心者故の専門用語に頭を悩ましております。こちらも併せてご指導頂けたら幸いです。

補足日時:2006/06/21 17:46
    • good
    • 0

3行目にreaddir関数がありますよね。


このreaddir関数で、ディレクトリ内の全てのファイルのリストを得ることが可能です。
つまりこのサンプルコード単体で、指定ディレクトリ内の
全てのファイルのリストを取得し、削除し、
最後にそのディレクトリ自体を削除する。
という一連の流れを全てやってくれます。

とりあえずこのスクリプトを使う上で特にセッションは必要ありませんよ。
    • good
    • 0
この回答へのお礼

giraffa96様

おはよう御座います。早速のご回答を有難う御座います。
readdir関数ですが、マニュアルを読んでは居たものの、素人の私にとって理解が乏しい状況の中、ご丁寧なご指導に感謝いたします。有難う御座いました。

ところで、質問内にあるコードですが、上手くいかず、はじめに
$rootPath = "/home/httpd/vhosts/test.aaa.com/test/';
のようなコードを素人ながらに入れてはみたももの、
Fatal error: Call to undefined function: deletedir()
といったエラーが出ております。ホントお恥ずかしい限りでは御座いますが、今一度ご指導頂ければ幸いです。

お礼日時:2006/06/21 09:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報