0

以下の2つの機能があります

function ListFiles($dir) {
    if($dh = opendir($dir)) {
        $files = array();
        $topics = array();
        $inner_files = array();
        while($file = readdir($dh)) {
            if($file != "." && $file != ".." && $file[0] != '.') {
                array_push($topics, $file);
                if(is_dir($dir . "/" . $file)) {
                    $inner_files = ListFiles($dir . "/" . $file);
                    if(is_array($inner_files)) $files = array_merge($files, $inner_files);
                } else {
                    array_push($files, $dir . "/" . $file);
                }
            }
        }
        closedir($dh);
        $topics = array();
        $i = 0;

        foreach ($files as $file) {
//wrong result
            $topics[] = getTopicFromPath($file);

//correct result
//$topics[] = getTopicFromPath("/Users/Unknown/Sites/sample/training/topic/acq/19ddb673359747ee9095.txt")
        }
        return $topics;
    }
}

function getTopicFromPath($path){
//$path = /Users/Unknown/Sites/sample/training/topic/acq/19ddb673359747ee9095.txt

    $string1 = substr($path,strpos($path,"topic/"));
//$string1 = topic/acq/19ddb673359747ee9095.txt

    $string2 = str_replace("topic/", "", $string1);
//$string2  = acq/19ddb673359747ee9095.txt

    $string3 = strstr($string2, '/', true);
//$string3 = null
//expecting $string3 = 'acq'

    return $string3;;
}

問題は、 getTopicFromPath($path) が readdir() メソッドからの文字列を解析できないことです。しかし、純粋な文字列を入れると、結果は正しいです。コードが明確であることを確認してください。

私がやりたいことは、ファイルパスを取得し、その親フォルダーをトピックとして保存することです。

別の方法でファイルを取得すると、問題が解決する場合があります。しかし、これらの機能の何が問題なのか知りたいです。

4

1 に答える 1

1

主な問題は、コードをきれいにして単純化する必要があることです。

1 - 関数 getTopicFromPath() で、string3が NULL の場合、 string2に「/」が見つかりません。Windows を使用していて、ディレクトリ セパレータが '/' ではなく '\' になっている可能性があります。

これらの問題を解決するには、ネイティブのDIRECTORY_SEPARATOR定数を使用します。

2 - 明らかに、この関数はファイル$pathのディレクトリ名を見つけようとします。次に、ディレクトリ関連の機能を使用し、過度に具体的なコーディングを避けることをお勧めします。具体的すぎるということは、多くの場合、コンテキストに依存し、壊れやすいことを意味します。

とにかく、私はあなたの関数を2行と2つのフレーバーで書き直します:

function getTopicFromPath($path) {
    $dir = dirname($path);
    return substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1);
}

また

function getTopicFromPath($path) {
    $dir = dirname($path);
    return basename($dir);
}

3 - getTopicFromPath()が再帰関数内で呼び出されます。多くのエントリは複数回処理されます。それは冗長です。

プロセスを 2 つの独立したステップに分割する必要があります。最初にファイルのフル パスを取得し、次にそれらをトリムします。再利用性と堅牢性が得られます。

4 - 最終的には、ListFile()関数を消去する必要があります。

closedir($dh);
$topics = array();
$i = 0;

$topics = array()この変数への上記の割り当ては、オーバーロードされるため役に立たないことを意味します。

$iその範囲では使用されません。

于 2013-05-22T13:46:12.020 に答える