• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:フォルダ関連のライブラリについてアドバイスしてもらえないでしょうか?)

フォルダ関連のライブラリについてアドバイスしてもらえないでしょうか?

hogehoge78の回答

回答No.5

Zend/Iterator/Directory/File とした場合に、私がFileに記述する内容は、 単純にファイルの構造が記述されているようなものですかね。 (getSizeメソッドとかそういうもの。) Iteratorじゃないので、そこに記述するのが気持ち悪いなら、まぁ Zend/File とか、そういう感じになるんじゃないですかね? ラッパークラスのほうは、たとえば、単純に「再帰的にルート以下のディレクトリ構成を配列にしたい」とかなら、 Zend/Directory/Treeとか Zend/Tree/Directoryとか なんかそういう感じのものにすればいいんじゃないのかなぁとか。(これも実際どうだろうなぁ。) Zend_Iterator_Directory_Folderと Zend_Iterator_Directory_Fileは Zend_Iterator_Directoryインターフェイスを継承したクラス、とかにする感じですかね。 Floderのほうは、自身の持っているファイルやフォルダを順繰りに取得が出来て、Fileのほうは、ファイルの詳細情報が表示できるようなものと考えました。 で、既存のDirectoryIteratorは、ディレクトリのイテレータなので、フォルダとファイルが両方混ざって吐き出されてくるし、再帰的に何かやるときには、ディレクトリの名称なのであればそこで再度new DirectoryIteratorしてやらないといけないし(RecursiveDirectoryIteratorというのもあるようですけど) 質問者さんが目指したい方向と違いがあったりしませんか。 (しないのであれば素直にDirectoryIteratorを使うべきですが) また、deleteメソッドを実装するとしてましたが、これも、Iterator_Directoryは、閲覧のみとして、操作関連に関しては、Zend_Control_Directoryとか別のオブジェクトで操作させるという方法でもいい気がします。 まぁ、お急ぎでないのであれば、ネーミングとかディレクトリ構成とかそういうのは全部おいておいて 仮のネーミング等で実装したい機能とか全部つめたクラスを作り上げてから、リファクタリングとかするほうがいい気がします。

takagoo100
質問者

お礼

ご回答ありがとうございます。 自分でこの困り度で質問しておいて言うのもなんですが、 もしそちらが宜しければ、もう少し自分がある程度理解できるようになるまで アドバイスをして頂ければうれしいと思います。 一応自分なりの理解でイテレータの方を作成(文字数の関係で補足を参照してください)してみたのですが、 こんな感じで宜しいでしょうか? ただZend_Iterator_Directoryインターフェイスに何を記述すればよいのかが いまいち分かりません・・・ それと今までDirectoryとFolderを同じようなものだと思ってたのですが、 今ではなんとなく違いをイメージはできるのですが、具体的に説明となると・・・ hogehoge78さんのお考えを教えてもらえないでしょうか?

takagoo100
質問者

補足

interface Zend_Iterator_Directory { // Zend_Iterator_Directory_FolderにもZend_Iterator_Directory_Fileにも共通する // メソッドなどを記述すると思いますが、具体的にそれはなんでしょうか? } class Zend_Iterator_Directory_File implements Zend_Iterator_Directory { protected $path = null; public function __construct($path) { $this->path = $path; } public function isFile() { return is_file($this->path); } public function getSize() { return filesize($this->path); } public function getPath() { return $this->path; } } class Zend_Iterator_Directory_Folder implements Iterator, Zend_Iterator_Directory { private $position = 0; private $array = array(); public function __construct($path) { $this->read($path); } public function rewind() { $this->position = 0; } public function current() { return $this->array[$this->position]; } public function key() { return $this->position; } public function next() { ++$this->position; } public function valid() { return isset($this->array[$this->position]); } protected function read($path) { if (false === ($dir = @opendir($path))) { throw new Exception('open error'); } while (false !== ($item = readdir($dir))) { if ($item === '.' || $item === '..') { continue; } $tmpPath = $path . '\\' . $item; $this->array[] = new Zend_Iterator_Directory_File($tmpPath); if (is_dir($tmpPath)) { $this->read($tmpPath); } } closedir($dir); } } $path = 'C:\myfolder'; $obj = new Zend_Iterator_Directory_Folder($path); foreach($obj as $file) { if ($file->isFile()) { print "file path=" . $file->getPath() . ' size=' . $file->getSize() . "<br>\n"; } else { print "folder path=" . $file->getPath() . "<br>\n"; } }

関連するQ&A

  • PHP初心者 再帰処理について

    あるフォルダ以下に含まれる全てのフォルダ名をフルパスですべて列挙するという処理を描こうと下記のブログを参考にして自分で少し書き換えたのですが、うまくいきません。 http://blog.asial.co.jp/12 <参考にした部分> function getFileList($dir) { $files = scandir($dir); $files = array_filter($files, function ($file) { // 注(1) return !in_array($file, array('.', '..')); }); $list = array(); foreach ($files as $file) { $fullpath = rtrim($dir, '/') . '/' . $file; // 注(2) if (is_file($fullpath)) { $list[] = $fullpath; } if (is_dir($fullpath)) { $list = array_merge($list, getFileList($fullpath)); } } return $list; } </参考にした部分> <自分で変更したコード> function getFileList($dir) { $files = scandir($dir); $files = array_filter($files, function ($file) { // 注(1) return !in_array($file, array('.', '..')); }); $list = array(); foreach ($files as $file) { $fullpath = rtrim($dir, '/') . '/' . $file; if (is_dir($fullpath)) { $list[] = $fullpath; $list[] = array_merge($list, getFileList($fullpath)); } } return $list; } </自分で変更したコード> 変更といってもis_fileの部分の削除と$list[] = $fullpath;を追加しただけなのですが、「~ bytes exhausted」というエラーになってしまいます。 再帰関数が内部的にどういう処理をしているのかよくわかってないので、正直変更したコードがどういう動きをしているのかいまいち理解できません。参考書にある再帰関数は腑に落ちないながらも結果としてはそうなるということは理解しました。 あとそれ以前に $files = array_filter($files, function ($file) {   return !in_array($file, array('.', '..')); の部分がわかりません。 scandirの戻り値には要素の最初の方に「.」と「..」が付くのでそれを削除する目的だとブログにはありますが、in_arrayはただ第一引数のものを第二引数から検索するだけのはずなのに、$filesの中身をarray_filtersの処理後に確認してみるとちゃんと「.」と「..」が削除されていて不思議です。あとin_arrayは第一引数のものを第二引数の中から検索するという関数だと思いますが、なぜそれをわざわざ反転させて((array('.', '..'), $file);じゃなく($file, array('.', '..'));)!in_arrayとしてるんでしょうか? *ちなみに引用したブログのコードの動作は確認済みで元のコードは完全に正しいです。引用したコードに文句をつけているわけではなく自分がわかっていないだけです。(^^ゞ 以上です。よろしくお願いします。

    • ベストアンサー
    • PHP
  • サブフォルダ内のフォルダ名取得

    連続処理のため、特定フォルダ以下のフォルダ名全てを取得する必要があります。 そこで本に書いてあったコードを試してみたのですが、フォルダ以下のサブフォルダまでしか取得できませんでした。 サブフォルダ以下にもフォルダがあるのですが、どのようにして取得すればいいのでしょうか? ↓以下が試してみてコードになります With CreateObject("Scripting.FileSystemObject")  With .getfolder(Start_Path)   For Each Obj_Folder In .subfolders    WorkSheets.Cells(i, 2).Value = Obj_Folder.name    i = i + 1   Next Obj_Folder  End With End With

  • EXCEL フォルダだけを検索したい

    EXCEL2003を使っています。 開いているファイルと同じフォルダ内に「テストフォルダ」があるかどうかを調べ、存在した場合に削除したいのですが、以下のような書き方ではフォルダだけでなくファイルも検索してしまうようです。 フォルダだけを検索するにはどうしたらいいでしょうか? FSOでできることは分かっていますが、以下の方法で試してみたいのです。どうぞ宜しくお願い致します。 Sub test() my_path = ActiveWorkbook.Path & "\" f_name = Dir(my_path, 16) Do Until f_name = "" If f_name = "テストフォルダ" Then RmDir "テストフォルダ" End If f_name = Dir() Loop End Sub

  • フォルダの中身がカラか調べる

    vbaです。 フォルダ(新しいフォルダ)を作り、その中にサブフォルダ(Test用フォルダ)を作って --------------------------------------------------------- Sub フォルダの中身がカラか調べる() If Dir("D:\新しいフォルダ\Test用フォルダ\*.*") = "" Then MsgBox "カラです" Else MsgBox "カラではありません" End If End Sub --------------------------------------------------------- を実行すると、新しいフォルダの中にフォルダがあるのに、 「カラです」が表示されてしまいます。 新しいフォルダのファイルサイズは0です。 If Dir("D:\新しいフォルダ\Test用フォルダ\*.*") = "" Then のコードは、フォルダの中のファイル数ではなく、 フォルダのサイズを取得してしまうのでしょうか?

  • サブフォルダ内の全てのテキストファイルを1発処理する方法

    Excel2007のVBAを使い、下記のようなマクロを作成しました。 (質問に必要そうな所だけ掲載しています。) Dim dir_name As String ' ディレクトリ名 Dim file_name As String ' ファイル名 Dim EffectiveRow As Integer ' 開始行数/Excel/Row(行) Dim ShellApp As Object ' SHDOCVW.DLL / MIC Dim oFolder As Object ' フォルダパス EffectiveRow = Range("A65536").End(xlUp).Row Set ShellApp = CreateObject("Shell.Application") Set oFolder = ShellApp.BrowseForFolder(0, "フォルダ選択", 1) dir_name = oFolder.items.Item.Path ChDir dir_name file_name = Dir("*.txt", vbNormal) Do Until file_name = "" EffectiveRow = EffectiveRow + 1 Call ImportText(file_name, EffectiveRow) file_name = Dir() Loop ShellApp.BrowseForFolderを使い、指定したフォルダを選択すると、 その中に有る、テキストファイル(.txt)を、全てExcelに書き込む というマクロを作成したのですが、もっと汎用性を高くするために、 下記の内容を実現したく思っています。 - ↓ 実現したい事↓ - - 状況 - *フォルダの中に、サブフォルダが複数有り、そのサブフォルダの中に、 テキストファイル(.txt)が複数入っている。 - 処理 - サブフォルダを格納している*フォルダを、ShellApp.BrowseForFolderで 選択し、一度でサブフォルダ内のテキストファイルを全てExcelに書き込 めるようにしたい。 上記のマクロから発展させて、このような処理を行う事は出来るでしょうか? また、どのようにすれば実現させることが出来るでしょうか? ご教授のほど、よろしくお願いします。m(_ _)m ※ [*フォルダ ] は同一フォルダです。

  • サブフォルダの親フォルダを変えたい

    フォルダの中のサブフォルダを取得してくて、 http://officetanaka.net/excel/vba/tips/tips95.htm の --------------------------------------------------------- Sub Sample4() Dim buf As String, msg As String buf = Dir("*.*", vbDirectory) Do While buf <> "" If InStr(buf, ".") = 0 Then msg = msg & buf & vbCrLf buf = Dir() Loop MsgBox msg End Sub --------------------------------------------------------- をやってみたら、サブフォルダを取得できたのですが、 上記のコードを実行すると 元々のフォルダのパスが「C:\Users」で、 「C:\Users」のサブフォルダが取得されてしまいます。 でも上記のコードでは、「C:\Users」は指定してないと思うのですが、 なぜ「C:\Users」のサブフォルダが取得されてしまうのでしょうか? 例えば 「C:\Users」ではなく、「C:\Program Files」のサブフォルダを取得するには、 どのようにコードを書き換えればいいのでしょうか? ご教授よろしくお願いします。

  • RmDirでフォルダが削除できない vba

    http://www.k1simplify.com/vba/tipsleaf/dir.html を参考にしたのですが Sub test() RmDir "\\test-PC\Users\Public\test" End Sub でフォルダの削除ができると思ったのですが パス名が無効ですというエラーになってしまいます。 ネットワークパスだからダメなのでしょうか? パスはフォルダからコピペしたので間違いないです。

  • PHP 変数 aタグで囲いたい

    失礼します。echo の中の変数をaタグで囲いたいのですがやり方がわかりません。 よろしくお願いします。 foreach($files as $file_path => $file_info) { if (!$file_info->isFile()) { continue; } echo 'file path : ' .$file_path ."</br>"; echo 'file size : '. $file_info->getSize() ."</br>"; echo 'contents : '. file_get_contents($file_path) ."</br>"; }

    • ベストアンサー
    • PHP
  • vbaでフォルダの中のファイルを削除したい

    vbaでフォルダの中のファイルを削除したいのですが その場合は、 Sub フォルダの中身を全て削除する() Set myFSO = CreateObject("Scripting.FileSystemObject") With myFSO MyFolderName = ConsT_フォルダ名 & "\" MyFileName = Dir(MyFolderName & "\*.*") Do While MyFileName <> "" myFSO.DeleteFile MyFolderName & "\" & MyFileName MyFileName = Dir() Loop End With Set myFSO = Nothing End Sub の様にして、一つ一つループして消していかないとダメでしょうか? フォルダは残して、カラのフォルダにしたいです。

  • フォルダの属性について 別途

    MediaWiki1.2でサイト作成中です。 画像(test.jpg)をアップロードするとフォルダが2つ自動作成されます。 例:サイトルート/images/5/2a/test.jpg imagesフォルダはデフォルトで存在するもので、「5」「2a」が自動で作成されます。 前回、「5」「2a」のフォルダのパーミッションが644になって不具合が出てしまうので質問しました。 chmodを利用すると、「2a」フォルダだけは777にすることはできました。 ディレクトリ作成と思われるソース抜粋は以下の通り。 /** * Make directory, and make all parent directories if they don't exist * * @param $dir String: full path to directory to create * @param $mode Integer: chmod value to use, default is $wgDirectoryMode * @param $caller String: optional caller param for debugging. * @return bool */ function wfMkdirParents( $dir, $mode = 0777, $caller = null ) { global $wgDirectoryMode; if ( FileBackend::isStoragePath( $dir ) ) { // sanity throw new MWException( __FUNCTION__ . " given storage path '$dir'." ); } if ( !is_null( $caller ) ) { wfDebug( "$caller: called wfMkdirParents($dir)\n" ); } if( strval( $dir ) === '' || file_exists( $dir ) ) { return true; } $dir = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, $dir ); if ( is_null( $mode ) ) { $mode = $wgDirectoryMode; } // Turn off the normal warning, we're doing our own below wfSuppressWarnings(); $ok = mkdir( $dir, $mode, true ); // PHP5 <3 chmod($dir,0777); wfRestoreWarnings(); if( !$ok ) { // PHP doesn't report the path in its warning message, so add our own to aid in diagnosis. trigger_error( sprintf( "%s: failed to mkdir \"%s\" mode 0%o", __FUNCTION__, $dir, $mode ), E_USER_WARNING ); } return $ok; chmod($dir,0777); } ※chmodの使用タイミングが理解未熟なので、2か所に登場しています。 「$dir」はフルパスなんですが、上記方法だと「2a」だけ777になって「5」フォルダは777にならないのです。 そこで、 「$dir」のひとつ上の階層(最下層のひとつ上になります)のフォルダのパーミッションを指定して777にしたいのですが、どのようにすればよいのでしょうか。上記例の場合、「5」フォルダの名称は自動生成なので「../5」のようにソースに書けなくて困っています。

    • ベストアンサー
    • PHP