もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

CakePHP4で非推奨となる File and Folderを推奨されている書き方で置き換えてみた

はじめに

こんばんは。

最近CakePHPの案件に携わっていて、CakePHPのドキュメントとか結構見たりしているのですが、以下のページでこんな文言を見つけました。

book.cakephp.org

Deprecated since version 4.0: The File and Folder classes will be removed in 5.0. Use SPL classes like SplFileInfo or SplFileObject and iterator classes like RecursiveDirectoryIterator, RecursiveRegexIterator etc. instead.

どうやら File クラスや Folder クラスが4系から非推奨になり、5系で廃止されるようです。

正直僕どちらも使った経験がなかったので、便利かどうかも知らないのですが、今携わっているCakePHP3の案件でも使われているようなので、この FileFolder を、推奨されているものを使用して書き換えてみます。

本題

step1

まず、そもそも File クラス、 Folder クラスがどんなもんかがわかってないので、それを調べます。

ドキュメントどおりに進めて、対象フォルダ内にある対象ファイルを調べてみます。

実装
<?php
require dirname(__DIR__) . '/vendor/autoload.php';

use Cake\Filesystem\Folder;
use Cake\Filesystem\File;

$dir = new Folder('../src/Controller');
$files = $dir->find('.*\.php');
var_dump($files);
結果
$ php file_and_folder_test.php 
array(3) {
  [0]=>
  string(19) "ErrorController.php"
  [1]=>
  string(17) "AppController.php"
  [2]=>
  string(19) "PagesController.php"
}

他にもフォルダ作ったりできる感じです。

実装
<?php
require dirname(__DIR__) . '/vendor/autoload.php';

use Cake\Filesystem\Folder;
use Cake\Filesystem\File;

$dir = new Folder('../src/Controller');
$dir->create(date('Ymd'));
結果
$ php file_and_folder_test.php
$ ls -l ../src/Controller
total 24
drwxr-xr-x  2 kojirock  staff    64  5  3 02:27 20200502/  ← 出来てる
-rw-r--r--  1 kojirock  staff  1595  6 27  2019 AppController.php
drwxr-xr-x  3 kojirock  staff    96  6 27  2019 Component/
-rw-r--r--  1 kojirock  staff  1731  6 27  2019 ErrorController.php
-rw-r--r--  1 kojirock  staff  2152  6 27  2019 PagesController.php

Fileに関しては、こんな感じでファイルサイズ貰ったり、最終更新日貰ったり出来ます。

実装
<?php
require dirname(__DIR__) . '/vendor/autoload.php';
use Cake\Filesystem\Folder;
use Cake\Filesystem\File;

$dir = new Folder('../src/Controller');
$fileNames = $dir->find('.*\.php');
foreach ($fileNames as $fileName) {
    $file = new File($dir->pwd() . '/' . $fileName);
    var_dump("{$fileName} サイズ: {$file->size()}, 最終更新日: {$file->lastChange()}");
    $file->close();
}
結果
$ php file_and_folder_test.php
string(64) "ErrorController.php サイズ: 1731, 最終更新日: 1561602647"
string(62) "AppController.php サイズ: 1595, 最終更新日: 1561602647"
string(64) "PagesController.php サイズ: 2152, 最終更新日: 1561602647"

他にもファイル操作・フォルダ操作を扱うための標準機能や便利機能があります。

だいたい理解できました。

次は、4以降から推奨されているやり方でこれを置き換えてみます。

step2

step1でやった、対象フォルダ内にある対象ファイルを調べる ことをやってみます。

実装
<?php                                                                                                                          

$directoryIterator = new RecursiveDirectoryIterator('../src/Controller', FilesystemIterator::SKIP_DOTS);                       
$files = new RecursiveIteratorIterator(new RecursiveRegexIterator($directoryIterator, '/.*\.php/'));                           
foreach ($files as $fileInfo) {                                                                                                
    var_dump($fileInfo->getFilename());                                                                                          
}
結果
$ php spl_test.php
string(19) "ErrorController.php"
string(17) "AppController.php"
string(19) "PagesController.php"

ファイル情報の取得です。これは RecursiveIteratorIterator が SplFileInfo返してるので、簡単です。

実装
<?php
$directoryIterator = new RecursiveDirectoryIterator('../src/Controller', FilesystemIterator::SKIP_DOTS);                       
$files = new RecursiveIteratorIterator(new RecursiveRegexIterator($directoryIterator, '/.*\.php/'));                           
foreach ($files as $fileInfo) {                                                                                                
    var_dump("{$fileInfo->getFilename()} サイズ: {$fileInfo->getSize()}, 最終更新日: {$fileInfo->getMTime()}");
} 
結果
$ php spl_test.php
string(64) "ErrorController.php サイズ: 1731, 最終更新日: 1561602647"
string(62) "AppController.php サイズ: 1595, 最終更新日: 1561602647"
string(64) "PagesController.php サイズ: 2152, 最終更新日: 1561602647"

こんな感じです。

終わりに

簡単なので、相当難しい使い方していない限りは簡単に置換可能かなーと思っています。

とりあえず、現場からは以上です。