PHPでディレクトリ内にあるファイルを一覧化したい

ソフトウェア,技術

この記事は2018年6月14日に書かれたものです。ご注意ください。

はい。はじまりました。
いつもの思いつきプログラムです。

わりとありがちです。ファイル一覧を取得したいの。特にログとかバージョン違いのファイルとか、なんかいっぱい。
ということでこんな感じでぱぱっと作りました。

初めてBootstrap使いました。くっそ便利ですね、これ。デモにいっぱい使おう…

テキトーコード

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
  <title>File</title>
</head>
<body>
  <div class="container">
    <div class="row">
    
      <!-- ALL -->
      <div class="col m-3">
        <h2>ALL</h2>
        <ul class="list-group">
          <?php
            $dir    = "files";
            $filelist = scandir($dir, 1);
            foreach($filelist as $file){
              $fileInfo = pathinfo($file);
              $basename = $fileInfo["basename"]; // foo.json
              $filename = $fileInfo["filename"]; // foo
              echo "<li class=\"list-group-item\">{$basename}</li>";
            }
            ?>
        </ul>
      </div>
      
      <!-- JSON -->
      <div class="col m-3">
        <h2>JSON Only</h2>
        <ul class="list-group">
          <?php
            $dir    = "files";
            $filelist = scandir($dir, 1);
            foreach($filelist as $file){
              $fileInfo = pathinfo($file);
              $basename = $fileInfo["basename"]; // foo.json
              $filename = $fileInfo["filename"]; // foo
              if($basename != $filename && $fileInfo["extension"] == "json"){
                echo "<li class=\"list-group-item\">{$basename}</li>";
              }
            }
            ?>
        </ul>
      </div>
      
    </div>
  </div>
</body>
</html>

PHPをキレイに出すためにHTML書いてます。ながい。入れ子いっぱぁい。

テキトー解説

今回はPHPの話なので、そこだけ絞っていきます。

<?php
  $dir = "files";
  $filelist = scandir($dir, 1);
  print_r ($filelist);
?>

ディレクトリ内のファイルを配列で取得するにはscandir($dir, 1);を使います。0で昇順、1で降順です。

Array(
    [0] => text.file2.txt
    [1] => text.file1.txt
    [2] => json2.json
    [3] => json1.json
    [4] => foo2
    [5] => foo1
    [6] => folder2
    [7] => folder1
    [8] => .bar2
    [9] => .bar1
    [10] => ..
    [11] => .
)

吐き出された配列は↑のような感じです。
ちなみに「.」は自身の、「..」は親のディレクトリです。。子のディレクトリも出てきちゃいますね、邪魔ですね!!!

<?php
  $dir = "files";
  $filelist = scandir($dir, 1);
  foreach($filelist as $file){
    echo $file;
  }
?>

吐き出された配列をforeach($filelist as $file){}で1つずつStringとして抜き出せます。改行とかしてないので、このまま出すと「text.file2.txttext.file1.txtjson2.jsonjson1.jsonfoo2foo1folder2folder1.bar2.bar1…」って珠つなぎになっちゃいますの。

<?php
  $dir = "files";
  $filelist = scandir($dir, 1);
  foreach($filelist as $file){
    $fileInfo = pathinfo($file);
    print_r ($fileInfo);
  }
?>

1つずつStringとして抜き出したファイル名をpathinfo($file);で調べていきます。

Array(
  [basename] => text.file1.txt
  [extension] => txt
  [filename] => text.file1
)
Array(
  [basename] => json1.json
  [extension] => json
  [filename] => json1
)
Array(
  [basename] => foo1
  [filename] => foo1
)
Array(
  [basename] => .bar1
  [extension] => bar1
  [filename] => 
)
Array(
  [basename] => ..
  [extension] => 
  [filename] => .
)
Array(
  [basename] => .
  [extension] => 
  [filename] => 
)

一部抜粋。ながい。こんな感じで情報を出力できます。filenameがファイル名、extensionが拡張子、basenameがファイル名&拡張子。
なお拡張子がないファイル・フォルダはextensionが返ってきません。
が、とりあえず「ファイル名」と「拡張子」が分かったので…

<?php
  $dir = "files";
  $filelist = scandir($dir, 1);
  foreach($filelist as $file){
    $fileInfo = pathinfo($file);
    $basename = $fileInfo["basename"]; // json1.json
    $filename = $fileInfo["filename"]; // json1
    $extension = $fileInfo["extension"]; // json
    if($extension == "json"){
      echo "{$fileInfo["basename"]}\n";
    }
  }
?>

ってすると「Notice: Undefined index: extension in C:\xampp\htdocs\xxx\index.php on line 10」って怒られます。
はい。 怒 ら れ ま す ! ! !

理由は$extension = $fileInfo["extension"]; // jsonが存在しない場合もあるから。
上にも書きましたが、拡張子がないファイル・フォルダはextensionが返ってきません。

では、拡張子がないファイル・フォルダをどうやって判定するか…
それは「basename」と「filename」で確認できます。
そう、if (basename == filename)に当てはまるモノが「拡張子がないファイル・フォルダ」なんです。(結構無理矢理な判定ですけど、どーなんでしょ?他に調べる方法ありそうですが楽でしたので…)

<?php
  $dir = "files";
  $filelist = scandir($dir, 1);
  foreach($filelist as $file){
    $fileInfo = pathinfo($file);
    $basename = $fileInfo["basename"]; // json1.json
    $filename = $fileInfo["filename"]; // json1
    if($basename != $filename && $fileInfo["extension"] == "json"){
      echo "{$fileInfo["basename"]}\n";
    }
  }
?>

それを踏まえ、拡張子を変数化するのをやめ、先に「拡張子がないファイル・フォルダ」か判定させる。それがfalseだった場合のみ、拡張子を判定させる…でできました。

json2.json
json1.json

むりやりなコードでした。
本当にファイルか否かの判定には使えないですね。