tsvファイル を機械的に処理したくなったので、自分用の簡易パッケージを作成しました。サクッと済ませたかったので全体的にガバガバですが……。
経緯
最初は
csv を処理するパッケージを使ってサクッと実装しようとした
……のですが、何故か結果が空配列となってしまい一向に進まなかったので自前で記述することに……。
コード
<?php
declare(strict_types=1);
namespace PhpTsvParser;
require_once __DIR__ . '/../vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Exception;
date_default_timezone_set('Asia/Tokyo');
class PhpTsvParser
{
protected Logger $logger;
protected string $err_msg = 'データファイル読み込みでエラーが発生しました。';
protected string $filepath;
protected int $array_length;
protected string $linefeed;
protected string $separator;
protected string $charset_from;
protected string $charset_to;
protected string $data;
/**
* @param string $filepath
* @param snt $array_length
* @param string $separator
* @param string $charset_from
* @param string $charset_to
*/
public function __construct(string $filepath, int $array_length, string $linefeed = "\n",string $separator = "\t", string $charset_from = 'UTF-8', string $charset_to = 'UTF-8')
{
$this->logger = new Logger('PhpTsvParser');
$this->logger->pushHandler(new StreamHandler(__DIR__ . '/../logs/app.log', Logger::WARNING));
$this->filepath = $filepath;
$this->array_length = $array_length;
$this->linefeed = $linefeed;
$this->separator = $separator;
$this->charset_from = $charset_from;
$this->charset_to = $charset_to;
}
/**
* @return array
*/
public function read(): array
{
if(
!file_exists($this->filepath)
|| file_get_contents($this->filepath) === false
) {
$this->logger->error(
$this->err_msg,
[
'filepath' => $this->filepath,
]
);
throw new Exception($this->err_msg);
}
// データ文字列から改行文字で配列へ
$dataArr = explode($this->linefeed, file_get_contents($this->filepath));
// 結果の配列を用意
$resultArr = [];
// ループ
for($i = 0; $i < count($dataArr); ++$i ){
// 文字コード
$elm = nl2br(
mb_convert_encoding(
$dataArr[$i],
$this->charset_to,
$this->charset_from
)
);
// 行が空文字列ならば指定要素数の空文字列の配列を生成、そうでなければ指定区切り文字列で分解した要素の配列を生成
$elmArr = $elm === '' ? array_fill(0, $this->array_length, '') : explode($this->separator, $elm);
$resultArr[] = $elmArr;
}
return $resultArr;
}
}
最初は fgetcsv
を利用しようかと思ったのですが、これも文字コードの絡み等を考えて没に。
結局 file_get_contents()
+ explode()
という形に落ち着きました。
その性質上、大量のデータを処理することは想定していないです。せいぜい 300 x 20 くらいのサイズ感で考えています。
後は最低限ですが monolog
を使っているくらいですかね。
参考
mb_convert_encoding()
explode()
file_get_contents()
array_fill()
Github 上の自作パッケージを Composer で読む
- Composerのパッケージを作成して公開するまで – Innovator Japan Engineers’ Blog
- composerでGitHubのリポジトリからパッケージ追加する方法 – namaozi’s memo
- GitHubのプライベートリポジトリに自作パッケージ上げてComposerでインストールする – キリウ君が読まないノート
Monolog
PHPUnit
- 2. PHPUnit 用のテストの書き方 — PHPUnit latest Manual
- PHPUnitの”expectException()”は、例外を発生させる箇所より前に記載する – Qiita
- PHPUnitで例外をテスト – Qiita