忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

PHP クラス(class)のオーバーライドの使い方について・その3


以下の記事で、クラス(class)のオーバーライドの使い方について説明してきました。

PHP クラス(class)の使い方について
PHP クラス(class)のオーバーライドの使い方について・その2

そこで、今回は簡単なクラスでの説明ではなく、少し有用性があるクラスを作成し、それを元にオーバーライドの使い方について説明します。

以下のクラスは PHPExcel ライブラリを利用して指定されたエクセルファイルをオープンし、全ての行を順次読込むためのクラスです。 メソッドとしては以下の4個を持ちます。

  • コンストラクタ(__construct):ファイルを指定してインスタンス生成
  • ファイルオープン(open):ファイルをオープンして各種属性を取得
  • カラムMAX取得(getColMax):カラムの最大値を返す
  • 1行データ取得(getLine):データが存在した場合は配列データを返す(最後を超えた場合はfalse)

<?php
//  Excelライブラリ読込
require_once './PHPExcel-1.8/Classes/PHPExcel.php';

//  Excelファイル読込クラス[cExcelGet.php]
class cExcelGet
{
    // 共通変数宣言
    private $strFilePath;   //  ファイルフルパス名退避
    //  エクセル用カラム名
    private $arrColName = array(
      // 0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
       "AA","AB","AC","AD","AE","AF","AG","AH","AI","AJ","AK","AL","AM","AN","AO","AP","AQ","AR","AS","AT","AU","AV","AW","AX","AY","AZ",
       "BA","BB","BC","BD","BE","BF","BG","BH","BI","BJ","BK","BL","BM","BN","BO","BP","BQ","BR","BS","BT","BU","BV","BW","BX","BY","BZ",
    );

    //  ワークシートオブジェクト取得
    private $objWorksheet;
    private $intLine;         //  データ行数
    private $intColMax;       //  カラムMAX数
    private $intRowMax;       //  行MAX数

    //  コンストラクタ
    //  [引数]  $_strFilePath string  : ファイルフルパス名
    public function __construct ($_strFilePath)
    {
        //  ファイルフルパス名を退避
        $this->strFilePath =  $_strFilePath;
    }

    //  ファイルオープン
    //  [戻り値]    :true:正常、false:エラー
    public function open() {
        //  ファイル存在チェック
		if (!file_exists($this->strFilePath)) {
            // ファイル存在エラー
            return false;
		}
        //  エクセルファイル読込オブジェクト
        $objReader = PHPExcel_IOFactory::createReader("Excel2007");
        //  PHPExcelオブジェクト取得
        $objPHPExcel = $objReader->load($this->strFilePath);
        //  ワークシートオブジェクト取得
        $this->objWorksheet = $objPHPExcel->getActiveSheet();
        //  カラムMAX取得
        $strColMax = $this->objWorksheet->getHighestColumn();     //  カラム文字列
        $this->intColMax = PHPExcel_Cell::columnIndexFromString($strColMax);
        //  行MAX取得
        $this->intRowMax = $this->objWorksheet->getHighestRow();
        //  データ行数
        $this->intLine = 0;
        //  正常
        return true;
    }

    //  カラムMAX取得
    public function getColMax() {
        return $this->intColMax;
    }

    //  1行データ取得
    //  [戻り値]    :データが存在した場合は配列データ
    //               (array("A" => "aaa", "B" => "bbbb")の様にカラム文字列でアクセス可能 )
    //              :false:行最終
    public function getLine() {
        //  データ行数
        $this->intLine++;
        if ($this->intLine > $this->intRowMax) {
            //  処理行数がMAXを超えた場合
            return false;
        }
        //  1行データ取得・行指定
        $arrData = $this->getLineDirect($this->intLine);
        //  データ配列を返す
        return $arrData;
    }

    //  1行データ取得・行指定
    //  [引数]  $_intLine   : 行番号(PHPExcelでは行は1~)
    //  [戻り値]            :データが存在した場合は配列データ
    //                      (array("A" => "aaa", "B" => "bbbb")の様にカラム文字列でアクセス可能 )
    //                      :false:行最終
    public function getLineDirect($_intLine) {
        $arrData = array();
        for($c = 0; $c < $this->intColMax; $c++) { //colは [0] 始まりで [0] = "A" となる(rowは [1] 始まり)
            $arrData[$c] = $this->objWorksheet->getCellByColumnAndRow($c, $_intLine)->getValue();
            if (is_null($arrData[$c])) {
                $arrData[$c] = "";
            } else {
                $arrData[$c] = trim($arrData[$c]);
            }
            //  変換後のキーと値で設定
            $arrData[$this->arrColName[$c]] = $arrData[$c];
        }
        //  データ配列を返す
        return $arrData;
    }
}
?>


このクラスを使って以下のエクセルを読込んでみます。

<?php
//	クラスファイル読込
require_once 'cExcelGet.php';

//  [cExcelGet]クラスの生成
$insXlsx = new cExcelGet("ctest1.xlsx");
//  ファイルオープン
if ($insXlsx->open() == true) {
	//	1行データ取得
    while ($arrData = $insXlsx->getLine()) {
        $str = "";
        for ($i = 0; $i < $insXlsx->getColMax() ; $i++) {
            if ($str != "") $str .= ",";
            $str .= $arrData[$i];
        }
        $str .= "<br>\n";
        echo $str;
    }
} else {
    echo "open error.";
}
?>


これを実行するとブラウザに以下の様に表示されます。

AAAA,BBBBB,CCC,DD
123,2000,4000,500
ABC001,B001,5000,140
C001,D002,600,200


このクラスを少し改良して、CSVファイルの場合に使用できる様にします。 尚 PHPExcel ライブラリのCSVファイル処理を利用します。(以下の記事を参照して下さい)

PHP PHPExcel CSVファイルの読み込み・書き込みについて

上記の記事から、CSVファイルを読込んで PHPExcelオブジェクト を取得すれば、今回のクラスを親クラスとして利用できることが分かります。
それでは、その前に元のクラスを以下の様に変更します。

<?php
//  Excelライブラリ読込
require_once './PHPExcel-1.8/Classes/PHPExcel.php';

//  Excelファイル読込クラス
class cExcelGet
{
    // 共通変数宣言
    protected $strFilePath;   //  ファイルフルパス名退避
    //  エクセル用カラム名
    private $arrColName = array(
      // 0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
       "AA","AB","AC","AD","AE","AF","AG","AH","AI","AJ","AK","AL","AM","AN","AO","AP","AQ","AR","AS","AT","AU","AV","AW","AX","AY","AZ",
       "BA","BB","BC","BD","BE","BF","BG","BH","BI","BJ","BK","BL","BM","BN","BO","BP","BQ","BR","BS","BT","BU","BV","BW","BX","BY","BZ",
    );

    //  ワークシートオブジェクト取得
    protected $objWorksheet;
    private $intLine;         //  データ行数
    private $intColMax;       //  カラムMAX数
    private $intRowMax;       //  行MAX数

    //  コンストラクタ
    //  [引数]  $_strFilePath string  : ファイルフルパス名
    public function __construct ($_strFilePath)
    {
        //  ファイルフルパス名を退避
        $this->strFilePath =  $_strFilePath;
    }

    //  ファイルオープン
    //  [戻り値]    :true:正常、false:エラー
    public function open() {
        //  ファイル存在チェック
		if (!file_exists($this->strFilePath)) {
            // ファイル存在エラー
            return false;
		}
        //  エクセルファイル読込、ワークシートオブジェクト取得
        $this->openWorksheet();
        //  カラムMAX取得
        $strColMax = $this->objWorksheet->getHighestColumn();     //  カラム文字列
        $this->intColMax = PHPExcel_Cell::columnIndexFromString($strColMax);
        //  行MAX取得
        $this->intRowMax = $this->objWorksheet->getHighestRow();
        //  データ行数
        $this->intLine = 0;
        //  正常
        return true;
    }

    //  エクセルファイル読込、ワークシートオブジェクト取得
    protected function openWorksheet() {
        //  エクセルファイル読込オブジェクト
        $objReader = PHPExcel_IOFactory::createReader("Excel2007");
        //  PHPExcelオブジェクト取得
        $objPHPExcel = $objReader->load($this->strFilePath);
        //  ワークシートオブジェクト取得
        $this->objWorksheet = $objPHPExcel->getActiveSheet();
    }

    //  カラムMAX取得
    public function getColMax() {
        return $this->intColMax;
    }

    //  1行データ取得
    //  [戻り値]    :データが存在した場合は配列データ
    //               (array("A" => "aaa", "B" => "bbbb")の様にカラム文字列でアクセス可能 )
    //              :false:行最終
    public function getLine() {
        //  データ行数
        $this->intLine++;
        if ($this->intLine > $this->intRowMax) {
            //  処理行数がMAXを超えた場合
            return false;
        }
        //  1行データ取得・行指定
        $arrData = $this->getLineDirect($this->intLine);
        //  データ配列を返す
        return $arrData;
    }

    //  1行データ取得・行指定
    //  [引数]  $_intLine   : 行番号(PHPExcelでは行は1~)
    //  [戻り値]            :データが存在した場合は配列データ
    //                      (array("A" => "aaa", "B" => "bbbb")の様にカラム文字列でアクセス可能 )
    //                      :false:行最終
    public function getLineDirect($_intLine) {
        $arrData = array();
        for($c = 0; $c < $this->intColMax; $c++) { //colは [0] 始まりで [0] = "A" となる(rowは [1] 始まり)
            $arrData[$c] = $this->objWorksheet->getCellByColumnAndRow($c, $_intLine)->getValue();
            if (is_null($arrData[$c])) {
                $arrData[$c] = "";
            } else {
                $arrData[$c] = trim($arrData[$c]);
            }
            //  変換後のキーと値で設定
            $arrData[$this->arrColName[$c]] = $arrData[$c];
        }
        //  データ配列を返す
        return $arrData;
    }
}
?>

クラスの中で、子クラスから参照される変数と、子クラスによりオーバーライドされるメソッドを protected として宣言します。 そこで、protected の部分を作成しCSVファイル読込クラスを宣言します。

<?php
//  CSVファイル読込クラス(エクセル読込クラスから派生)
class cCsvGet extends cExcelGet
{
    //  コンストラクタ
    //  [引数]  $_strFilePath string  : ファイルフルパス名
    public function __construct ($_strFilePath)
    {
        parent::__construct($_strFilePath);
    }

    protected function openWorksheet() {
        // CSV読込クラス生成
        $objReader = new PHPExcel_Reader_CSV();
        // CSVファイルの文字コード:Shift-JIS
        $objReader->setInputEncoding('SJIS');
        // 区切り記号(カンマ)
        $objReader->setDelimiter(',');
        // 文字列の囲み文字(")
        $objReader->setEnclosure('"');
        // シートの位置
        $objReader->setSheetIndex(0);
        // 読込の結果としてPHPExcelオブジェクトが返る
        $objPHPExcel = $objReader->load($this->strFilePath);
         //  ワークシートオブジェクト取得
        $this->objWorksheet = $objPHPExcel->getActiveSheet();
    }
}
?>


このクラスを使って以下のCSVファイルを読込んでみます。("ctest1.csv"ファイル)

aaaaaaaaaa,bbbbbb,cccccccc,dd
123,456,1000,2000
a01,b01,2000
c02,d03,500,600

以下が読込を実行するソースです。

<?php
//  クラスファイル読込
require_once 'cExcelGet.php';
require_once 'cCsvGet.php';

//  [cCsvGet]クラスの生成
$insCsv = new cCsvGet("ctest1.csv");
//  ファイルオープン
if ($insCsv->open() == true) {
    while ($arrData = $insCsv->getLine()) {
        $str = "";
        for ($i = 0; $i < $insCsv->getColMax() ; $i++) {
            if ($str != "") $str .= ",";
            $str .= $arrData[$i];
        }
        $str .= "<br>\n";
        echo $str;
    }
} else {
    echo "open error.";
}
?>

これを実行するとブラウザに以下の様に表示されます。

aaaaaaaaaa,bbbbbb,cccccccc,dd
123,456,1000,2000
a01,b01,2000,
c02,d03,500,600

以上、有用性があると言いましたが、特に使い勝手が良くないかもしれませんので、改良して使って頂ければと思います。












PR

コメント

コメントを書く