CSVライブラリも削除
This commit is contained in:
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
namespace Site\Lib;
|
||||
|
||||
enum Delimiter: int {
|
||||
case COMMA = 1;
|
||||
case SEMICOLON = 2;
|
||||
case TAB = 3;
|
||||
case PIPE = 4;
|
||||
|
||||
public static function default(): self {
|
||||
return self::COMMA;
|
||||
}
|
||||
|
||||
public function getChar(): string {
|
||||
return match ($this) {
|
||||
self::COMMA => ",",
|
||||
self::SEMICOLON => ";",
|
||||
self::TAB => "\t",
|
||||
self::PIPE => "|",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSVパーシングクラス
|
||||
*/
|
||||
class Csv {
|
||||
// リクエスト関連のプロパティ
|
||||
private bool $isHeader = false;
|
||||
private int $length = 8192;
|
||||
private Delimiter $delimiter;
|
||||
private string $filename;
|
||||
private $fp;
|
||||
|
||||
public function __construct(string $filename, int $length = 8192) {
|
||||
$this->length = $length;
|
||||
$this->filename = $filename;
|
||||
$this->delimiter = Delimiter::default();
|
||||
|
||||
$this->fp = fopen($this->filename, 'r');
|
||||
if ($this->fp === false) {
|
||||
$msg = "ファイルを開けられません。";
|
||||
logger(\LogType::Csv, $msg);
|
||||
throw new \Exception($msg);
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
if ($this->fp !== false) {
|
||||
fclose($this->fp);
|
||||
}
|
||||
}
|
||||
|
||||
public function parse(?Delimiter $delimiter = null, bool $isHeader = false): array {
|
||||
$res = [];
|
||||
$this->isHeader = $isHeader;
|
||||
$this->delimiter = $delimiter ?? $this->delimiter;
|
||||
|
||||
$delimChar = $this->delimiter->getChar();
|
||||
|
||||
rewind($this->fp);
|
||||
|
||||
if ($this->isHeader) {
|
||||
$res = ['header' => [], 'body' => []];
|
||||
$head = fgets($this->fp, $this->length);
|
||||
if ($head !== false) {
|
||||
$res['header'] = str_getcsv($head, $delimChar);
|
||||
}
|
||||
}
|
||||
|
||||
while (($buffer = fgets($this->fp, $this->length)) !== false) {
|
||||
$row = str_getcsv($buffer, $delimChar);
|
||||
if ($this->isHeader) $res['body'][] = $row;
|
||||
else $res[] = $row;
|
||||
}
|
||||
|
||||
if (!feof($this->fp)) {
|
||||
$msg = "エラー:fgets()の失敗";
|
||||
logger(\LogType::Csv, $msg);
|
||||
throw new \Exception($msg);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
<?php
|
||||
namespace Site\Test;
|
||||
|
||||
require_once __DIR__.'/../../../autoload.php';
|
||||
|
||||
use Site\Lib\Tester;
|
||||
use Site\Lib\Csv;
|
||||
use Site\Lib\Delimiter;
|
||||
|
||||
if (CSV_ENABLED) {
|
||||
$test = new Tester([
|
||||
'colorOutput' => true,
|
||||
'verboseOutput' => true
|
||||
]);
|
||||
|
||||
$test->describe('Csvの基本的なパーシング', function($test): void {
|
||||
$test->it('簡単なCSVファイルをパーシングするはず', function($test): void {
|
||||
$str = "岩田聡,プロジューサー\n宮本茂,デザイナー\nJeffrey Epstein,幼児性愛者";
|
||||
|
||||
$tmpFile = tempnam(sys_get_temp_dir(), 'csv_test');
|
||||
file_put_contents($tmpFile, $str);
|
||||
|
||||
$csv = new Csv($tmpFile);
|
||||
$res = $csv->parse();
|
||||
|
||||
unlink($tmpFile);
|
||||
|
||||
$expect = [
|
||||
["岩田聡", "プロジューサー"],
|
||||
["宮本茂", "デザイナー"],
|
||||
["Jeffrey Epstein", "幼児性愛者"]
|
||||
];
|
||||
|
||||
$test->assertNotNull($res);
|
||||
$test->assertEquals($res, $expect);
|
||||
});
|
||||
|
||||
$test->it('異なるデリミタでCSVをパーシングするはず', function ($test): void {
|
||||
// セミコロン
|
||||
$semiStr = "岩田聡;プロジューサー\n宮本茂;デザイナー";
|
||||
$tmpFile = tempnam(sys_get_temp_dir(), 'csv_semi_test');
|
||||
file_put_contents($tmpFile, $semiStr);
|
||||
|
||||
$csv = new Csv($tmpFile);
|
||||
$res = $csv->parse(Delimiter::SEMICOLON);
|
||||
|
||||
unlink($tmpFile);
|
||||
|
||||
$expect = [
|
||||
["岩田聡", "プロジューサー"],
|
||||
["宮本茂", "デザイナー"]
|
||||
];
|
||||
|
||||
$test->assertEquals($res, $expect, "セミコロンデリミタでパーシングに失敗");
|
||||
|
||||
// タブ
|
||||
$tabStr = "岩田聡\tプロジューサー\n宮本茂\tデザイナー";
|
||||
$tmpFile = tempnam(sys_get_temp_dir(), 'csv_tab_test');
|
||||
file_put_contents($tmpFile, $tabStr);
|
||||
|
||||
$csv = new Csv($tmpFile);
|
||||
$res = $csv->parse(Delimiter::TAB);
|
||||
|
||||
unlink($tmpFile);
|
||||
|
||||
$test->assertEquals($res, $expect, "タブデリミタでパーシングに失敗");
|
||||
|
||||
// パイプ
|
||||
$pipeStr = "岩田聡|プロジューサー\n宮本茂|デザイナー";
|
||||
$tmpFile = tempnam(sys_get_temp_dir(), 'csv_pipe_test');
|
||||
file_put_contents($tmpFile, $pipeStr);
|
||||
|
||||
$csv = new Csv($tmpFile);
|
||||
$res = $csv->parse(Delimiter::PIPE);
|
||||
|
||||
unlink($tmpFile);
|
||||
|
||||
$test->assertEquals($res, $expect, "パイプデリミタでパーシングに失敗");
|
||||
});
|
||||
|
||||
$test->it('ヘッダー付きCSVをパーシングするはず', function ($test) {
|
||||
$str = "name,job title\n岩田聡,プロジューサー\n宮本茂,デザイナー";
|
||||
|
||||
$tmpFile = tempnam(sys_get_temp_dir(), 'csv_header_test');
|
||||
file_put_contents($tmpFile, $str);
|
||||
|
||||
$csv = new Csv($tmpFile);
|
||||
$res = $csv->parse(Delimiter::COMMA, true); // isHeader = true
|
||||
|
||||
unlink($tmpFile);
|
||||
|
||||
$expect = [
|
||||
'header' => ["name", "job title"],
|
||||
'body' => [
|
||||
["岩田聡", "プロジューサー"],
|
||||
["宮本茂", "デザイナー"],
|
||||
],
|
||||
];
|
||||
|
||||
$test->assertNotNull($res);
|
||||
$test->assertEquals($res, $expect, "ヘッダーパーシングに失敗");
|
||||
});
|
||||
|
||||
$test->it('セル内にカンマを含むCSVをパーシングするはず', function ($test): void {
|
||||
$str = "\"守矢, 諏訪子\",エンジニア\n\"青, 猫ちゃん\",サーバー管理者";
|
||||
|
||||
$tmpFile = tempnam(sys_get_temp_dir(), 'csv_quoted_comma_test');
|
||||
file_put_contents($tmpFile, $str);
|
||||
|
||||
$csv = new Csv($tmpFile);
|
||||
$res = $csv->parse(\Site\Lib\delimiter::COMMA);
|
||||
|
||||
unlink($tmpFile);
|
||||
|
||||
$expect = [
|
||||
["守矢, 諏訪子", "エンジニア"],
|
||||
["青, 猫ちゃん", "サーバー管理者"]
|
||||
];
|
||||
|
||||
$test->assertNotNull($res);
|
||||
$test->assertEquals($res, $expect, "セル内にカンマを含むパーシングに失敗");
|
||||
});
|
||||
});
|
||||
|
||||
$test->printSummary();
|
||||
}
|
||||
Reference in New Issue
Block a user