• ベストアンサー

ディレクトリ削除

お世話になっております。 画像をアップロード(ディレクトリ生成&そのディレクトリ内に保存)した後、安易な考えか、アップロードし直すという流れのとき、一旦生成したディレクトリを削除し、新たにディレクトリを生成、そしてその中に保存したいと考えておりますが、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/'); このようなコードがとあるサイトで紹介されておりましたが、やはりこれもセッションが必要なのかな?などと・・・お恥ずかしい質問ばかりで恐縮ですが、ご教授頂ければ幸いです。宜しくお願い致します。

  • PHP
  • 回答数5
  • ありがとう数3

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

  • ベストアンサー
  • giraffa96
  • ベストアンサー率70% (106/150)
回答No.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しようとすると「既にファイルがある」と言われてしまいます。

sadacha
質問者

お礼

giraffa96様 こんにちは。お忙しい中、順を追っての説明を有難う御座います。初心者の私にとって、とても判りやすく勉強になりました。 報告が後になってしまいましたが、今回のアドバイスの基、無事解決させる事が出来ました。 本当に有難う御座いました!

その他の回答 (4)

回答No.4

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
sadacha
質問者

お礼

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

  • giraffa96
  • ベストアンサー率70% (106/150)
回答No.3

ふたたび、こんにちは。 だいぶ進んでるみたいですね。 エラーはそのまま訳しても良く判らないことが多いですよね。 ちょっと長くなりますがひとつづつやっていけば必ずうまく行きますので、 根気良くやってみてくださいね。 まず、ここを見てみて下さい。 >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終わりの}の直前で閉じましょう。 これで実行してみて下さい。 だいぶ長文になってしまったので、どこか判りにくかったり、 うまく行かなかったりしたらまた聞いて下さいね。

sadacha
質問者

補足

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);

  • giraffa96
  • ベストアンサー率70% (106/150)
回答No.2

こんにちは。 ちょっと気になったのは、コード内の以下の部分 >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); に変更しましょう。

sadacha
質問者

補足

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

  • giraffa96
  • ベストアンサー率70% (106/150)
回答No.1

3行目にreaddir関数がありますよね。 このreaddir関数で、ディレクトリ内の全てのファイルのリストを得ることが可能です。 つまりこのサンプルコード単体で、指定ディレクトリ内の 全てのファイルのリストを取得し、削除し、 最後にそのディレクトリ自体を削除する。 という一連の流れを全てやってくれます。 とりあえずこのスクリプトを使う上で特にセッションは必要ありませんよ。

sadacha
質問者

お礼

giraffa96様 おはよう御座います。早速のご回答を有難う御座います。 readdir関数ですが、マニュアルを読んでは居たものの、素人の私にとって理解が乏しい状況の中、ご丁寧なご指導に感謝いたします。有難う御座いました。 ところで、質問内にあるコードですが、上手くいかず、はじめに $rootPath = "/home/httpd/vhosts/test.aaa.com/test/'; のようなコードを素人ながらに入れてはみたももの、 Fatal error: Call to undefined function: deletedir() といったエラーが出ております。ホントお恥ずかしい限りでは御座いますが、今一度ご指導頂ければ幸いです。

関連するQ&A

  • ディレクトリ削除

    rmdirでディレクトリを削除しようとしているのですが、 ディレクトリの中にファイルやディレクトリがある為削除できません。 ディレクトリの中には何階層もディレクトリがあり(いくつあるかわからない)ます。 この場合ディレクトリ以下全て消したいのですがどうやって実装すればいいでしょうか? ご存知の方ご教授お願いいたします。

    • ベストアンサー
    • PHP
  • Perlでディレクトリごと削除したい

    telnet.cgiを使って、カレントディレクトリで、 rm -rf * を行っても、なぜか(permissin 755にも関わらず)permission denyといわれうまく削除できませんでした。 そこで、perlを使って削除を試みたいのですがどのようにすれば、削除できますか? 参考になりそうなソースを見つけたのですが、ディレクトリの中にディレクトリがある構造のためうまく削除できませんでした。 どなたか、改良していただけないでしょうか? お手数ですが、宜しくお願い致します。 #!/usr/local/bin/perl $dir = "./d/"; opendir DIR, $dir; @files = grep { !m/^(\.|\.\.)$/g } readdir DIR; close DIR; $flag = @files; if ( $flag ) { foreach $file ( @files ) { unlink "$dir$file"; } } rmdir $dir;

    • ベストアンサー
    • CGI
  • ファイルアップロードのエラーに関して

    こんばんは。お世話になっております。 これまで、以下のようなスクリプト(一部ですが)にて、ファイルのアップロードを行っておりますが、ローカルでのテスト環境で、突然エラー表示が出るようになってしまいました。(phpバージョン 5.2.2) $folder = $_SESSION['id']; function deleteDir($rootPath){ if(is_dir($rootPath)){ if($strDir = opendir($rootPath)){ while($strFile = readdir($strDir)){ if($strFile != '.' && $strFile != '..'){ unlink($rootPath.'/'.$strFile); } } closedir($strDir); rmdir($rootPath);//ここで「rmdir(/home/public_html/html/member_picture/4/) [function.rmdir]: Permission denied in 」というエラー } } } deleteDir("/home/public_html/html/member_picture/$folder/"); mkdir ("/home/public_html/html/member_picture/$folder/",0707);//ここで、「mkdir() [function.mkdir]: File exists in 」というエラー これまで何ら問題なく作動していただけに、突然のエラー表示に(スキル不足故に)成す術もなく、スプリプトのおかしな点などを含め、アドバイスなど頂戴出来ればと投函しました。 お忙しい中恐縮ですが、宜しくお願い申し上げます。 ※提示したスクリプトが不適切(提示不足)なものであったらお許し下さい。

    • ベストアンサー
    • PHP
  • ディレクトリ内のCSVファイル一括削除について

    ディレクトリ内のCSVファイルを一括削除したのですがうまくいきません。 下記のように記述しているのですが。 unlink($path/*.csv);

    • ベストアンサー
    • Perl
  • ファイルやディレクトリの削除コマンドについて

    ファイルやディレクトリの削除コマンドについて 現在、サーバ内のあるディレクトリ内に保存されているファイルやフォルダを 全て消去したいと思い、batファイルを作成してテストを行っているのですが、 うまくいきません。 ファイルの削除はうまくいきますが、空フォルダが残ってしまします。 batファイルの中身は以下の通りです。 del /s /q x:\test\abc\*.* rd /s /q x:\test\abc\* testやabcは実際のディレクトリ名では有りませんが、 やりたいことは、abcディレクトリ下のフォルダおよびファイルを 全て削除し、abcディレクトリは消さずに残すようなbatファイルが作りたいということです。 abcディレクトリの下には多くのファイルやディレクトリがあり、毎日違う名前のファイルや フォルダが作成されるのでそれを毎日まとめて消す方法をご教授願います。 よろしくお願いします。

  • ファイルアップローダ+複数のディレクトリを削除するシステムについて

    以下のようなフォルダ構成で、複数のディレクトリを削除するシステムを構築しよと しましたが、1ディレクトリのみしか削除できませんでした。 20090601 - xxx1.txt yyy1.txt zzz1.txt のフォルダ20090601と、ファイルxxx1.txt,yyy1.txt,zzz1.txt のみしか削除できませんでした。理想は、すべてのディレクトリ、ファイルを削除しようと、試行錯誤 しましたが、なかなかうまくいきません。 わかる人がいたら、ご教授のほどよろしくお願いします。 ============フォルダ構成==================================== 20090601 - xxx1.txt yyy1.txt zzz1.txt 20090602 - xxx2.txt yyy2.txt zzz2.txt 20090603 - xxx3.txt yyy3.txt zzz3.txt 20090604 - xxx4.txt yyy4.txt zzz4.txt $_WK_dir_name[1] = "20090601" $_WK_dir_name[2] = "20090602" $_WK_dir_name[3] = "20090603" $_WK_dir_name[4] = "20090604" ============プログラム====================================== // ファイルアップロード処理 (省略) // ディレクトリ数のカウント処理 (省略) // ディレクトリとディレクトリの中身を削除 for ($i = 1; $i < 4; $i++) { // 削除するディレクトリパスを設定 $_dir_path = './' . $_WK_dir_name[$i] . '/'; printf("★1"); // ディレクトリ・ハンドルをオープン $res_file = opendir( $_dir_path ); printf("★2"); // ディレクトリ内のファイル名を1つずつを取得 while( $file_name = readdir( $res_file ) ){ // ファイルかどうか判定する if (is_file($_dir_path . $file_name)) { unlink($_dir_path . $file_name); } } printf("★3"); closedir( $res_file ); printf("★4"); rewinddir( $res_file ); printf("★5"); // ディレクトリの中身が空になったところで、ディレクトリを削除する。 rmdir($_WK_dir_name[$i]); printf("★6"); } ============================================================

    • ベストアンサー
    • PHP
  • ディレクトリ下のファイルとサブディレクトリを全削除

    バッチファイル作成の際、分からないことがあるのですが。 タイトルの通り、ディレクトリ下のファイルとサブディレクトリを全削除したいのですが、そのディレクトリ自体は残したいのです。 例えば "Temp"以下の全ファイルとサブディレクトリを削除したい場合 del "Temp" /s とするとサブディレクトリは残ってしまい、 rd "Temp" /s とすると"Temp"自体削除されてしまいます。 この場合、一度rdコマンドで削除した上でmdなどで新たにディレクトリを作成してやるしかないのでしょうか?

  • アップロードした画像の削除

    フォームから画像をアップロードするものを作っています。 アップロードから画像の表示まではできているのですが 画像の削除の方法について教えてください。 単純に削除であればunlinkでいいのですが入力画面内にての 途中の工程でのいい方法がわからず困っております。。。 必須項目が5つありそのうちファイル選択が1つというのが前提です。 1・フォームからをファイルを選択 ※他の項目は空の状態 2・ファイルが選択されていれば必要なエラーチェックを行い 問題なければ一度でも送信ボタンを押したら他のフォームの値が 空でエラーがあってもファイルデータ保持のためバイナリデータ としセッションで保持した後サーバーにファイルをアップロード ※他のフォームが空なのでエラーとなり確認画面へページ移管は せず再度入力画面を表示 3・バイナリデータをもったセッションがあれば画像表示のため 別のphpファイルを読み込み入力画面中に確認用画像として表示 ※セッションを使用 4・画像表示と一緒に画像削除用のリンクを表示 ※<a href="hoge.php?action=del">削除<a> ※一度でも画像をアップロードすれば削除をクリックしセッション 削除しない限りファイルの選択は無効となる 5・削除をクリックしたら以下のソースでファイルに関しての 必要なセッション削除 if ($_GET['action'] == 'del') { // アップされたファイル削除 @unlink($_SESSION['file']['image_path']); // セッション削除 unset($_SESSION['file']); // 削除後移動 header('Location:' . $_SERVER['SCRIPT_NAME']); exit(); } これで問題なく画像は消えるのですが他のフォームに入力している 値までが削除(初期化?)されてしまいます。 ※header関数を使わなくてもアドレスがhoge.php?action=delと なるだけで結果は同じでした。 希望としては削除をクリックしたらファイルに必要なセッション のみを削除し他の入力されている項目の値残したいのですが どのような方法がありますでしょうか? 他の項目の値はセッションで保持している訳ではないのでheader 関数で移動すれば値も消えていて当然というのはわかるので実現 できる事なのかすらわからない状況です。 わかりづらい質問となってしまい申し訳ございませんが宜しく お願い致します。

    • 締切済み
    • PHP
  • FFFTPで、CGI転送後に削除出来ないディレクトリ。

    初めまして。 現在困っていることがありまして、経験者様等のご意見をお聞きしたく、また是非ともアドバイスを頂きたく思い、質問をさせて頂きました。 私はある無料サーバーをお借りして、ホームページを作成しています。 そのサーバー様はWEB上でHTML等は編集出来ず、編集・アップロード等出来る方法はFFFTPを使った転送のみなので、今までFFFTPは使ったことが無く不慣れながら何とかあと少しでホームページが完成、というところまで来ました。 お借りしているサーバー様はCGI・PHPの使用が可能ですので、私は掲示板はCGIにしようと思い、無料で配布されているサイト様からCGIをダウンロードをしてお借りして来ました。 しかし、一度は転送・アップロードをしたものの後にそのCGIが不要になり、使用しないものを置いていても意味は無いので削除しようとしました。 ですが、そのCGIが入っていたディレクトリを削除したくても出来ないのです。 CGIが入っていたディレクトリの中身のCGI本体やファイルなどは削除出来ましたが、CGIが入っていたディレクトリ自体を削除することが出来ません。 ディレクトリのパーミッションを「777」に変更したり、ディレクトリの名前を変更してからも削除を再度試みましたが、出来ませんでした。 Yahoo!などで検索をして色々と調べているのですが、やはり出来ません。 検索をして調べている内に、「サーバーによっては、セキュリティの関係から「.htaccess」や「.csh」などある種のファイルをユーザーから隠しているサーバーが存在するため、そういった特殊なファイルを消したりリネームしたりすることは出来ない」と書かれている文章を見ました。 私は今回削除出来なくなったディレクトリにCGIを置く際に「.htaccess」のファイルもアップロードをしていたので、上記に書かれているようにこれが原因なのでは…と思いまして…。 もしこれが原因の場合、個人の手でどうにかすることは出来ないとも書かれていましたので、一応先程サーバーの管理者様にメールで問い合わせをさせて頂きまして、現在は管理者様からのお返事待ちです。 しかし、まだ他にも何か方法があるのならそれを試したいので、是非ともご意見・アドバイス等お聞かせ頂けると嬉しいです。 文章が上手く纏まらずに伝わりにくいものとなり申し訳ございませんが、よろしくお願い致します。

  • DOS(バッチ)でディレクトリの削除

    e:\test\foo\bar と言うディレクトリ構成があると仮定します。 この時、ディレクトリ "foo" を削除するにはどのようにすればいいの でしょうか? ---- sample.bat ---- chdir e:\test del /f /s /q foo -------------------- 上記の sample.bat では、中身のファイルは削除されるのですが、 ディレクトリは残ったままです。 ディレクトリ "foo" そのものを削除したいのですが可能でしょうか? windows 2000pro sp2

専門家に質問してみよう