PHPの継承について1から勉強しなおす
継承。わかっているようで全くわかっていなかったので、基礎から勉強しなおしました。
まずはこちらをご覧ください。
<?php class AnalysisFile { public function getFile($file) { $row = 1; if (($handle = fopen($file, "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); echo "$num fields in line $row\n"; $row++; print_r($data); } fclose($handle); } } } $af = new AnalysisFile(); $af->getFile("test.csv");
PHPマニュアル「fgetcsv」の例*1をほぼ引用。CSVファイルの全てのコンテンツを読み込み、表示しているだけです。でもこれ、正直言ってわかりにくい(と思うのは私だけ?)ので、もうちょっとわかりやすく書き直してみます。
っで、修正したものがこちらになります。
<?php class AnalysisFile { public function __construct() { $this->GetCount = 1; } public function getCount() { return $this->GetCount; } public function getFile($file) { if (($handle = fopen($file, "r")) !== FALSE) { $this->readFile($handle); fclose($handle); } } private function readFile($handle) { $row = $this->getCount(); while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); echo "$num fields in line $row\n"; $row++; $this->printArray($data); } } private function printArray($array) { print_r($array); } } $af = new AnalysisFile(); $af->getFile("test.csv");
多少強引にやってますが。まぁでもなんとなくオブジェクト指向っぽい(小並感)
ここまで書き終えると、こんな要望が来たとします。
「Web上にあるCSVファイルを取得して、保存して、同じように解析して。あっ、今までの機能は残しておいてね」
おk、把握した。getFile()に、ファイルが渡されたときとURLが渡されたときとで分けるよう処理を追加しよう。If文で、正規表現も使って・・・できた、デバッグするぞー、ってあれ?落ちた?どこで?と、とりあえず前の状態に戻して・・・。
なんてことをやっていたらアホです。えぇ、過去の私です、アホでした。こういうときは「継承」を使うのが便利、だそうです。早速修正してみましょう。
<?php class AnalysisFile { public function __construct() { $this->GetCount = 1; } public function getCount() { return $this->GetCount; } public function getFile($file) { if (($handle = fopen($file, "r")) !== FALSE) { $this->readFile($handle); fclose($handle); } } private function readFile($handle) { $row = $this->getCount(); while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); echo "$num fields in line $row\n"; $row++; $this->printArray($data); } } private function printArray($array) { print_r($array); } } class AnalysisDownloadFile extends AnalysisFile { public function getFile($url) { $file = $this->downloadFile($url); parent::getFile($file); } public function downloadFile($url) { $file = file_get_contents($url); $filePath = "/var/www/html/csv/downloadfile.csv"; file_put_contents($filePath, $file); return $filePath; } } $af = new AnalysisFile(); $adf = new AnalysisDownloadFile(); $af->getFile("/var/www/html/csv/test.csv"); $adf->getFile("http://hoge/piyo.csv");
というようにすると、元のクラスを一切変更することなく機能追加ができるわけです。はぁ、すごく便利。