2013年3月22日金曜日

PHP 定数

定数宣言

PHPでは定数を宣言する方法として、「define()」関数を使用する方法と、「const」キーワードを使用する方法があります。
どちらを使用しても定数名はすべて大文字で単語の区切りは「_(アンダーバー)」にするのがお約束です。
例:MY_CONST_VALUE
定数に指定できるデータ型はスカラー値(型がboolean, integer, double, string, NULL) のみで配列などは指定できません。


define()関数

構文
define('定数名', 定数値);

使用例
<?php
//定数名「TAX」値「0.05」を定義します。
define('TAX', 0.05);

//定数「TAX」を使用
$price = 1000;
$total = $price + ($price * TAX);
print($total);
?>
define()関数で定義した定数はスコープがグローバルになり、プログラム中のどんな場所でも使用することができます。
あちこちでdefine()関数を使用した定数を定義すると可読性が悪くなります。

define()関数は値の宣言時に演算やメソッドの戻り値が利用できます。
<?php

define('TAX1', 0.05);
//定数値に演算が使える
define('TAX2', 1 * TAX1);
//定数値にメソッドの戻り値を使える
define('TAX3', getTax('2015/01/01'));

function getTax($date) {
    //2014/04/01以前 消費税5%
    //2014/04/01以降 消費税8%
    //2015/10/01以降 消費税10%
    $dt = new DateTime($date);
    $tax = 0;
    if ($dt < new DateTime('2014/04/01')) {
        $tax = 0.05;
    } elseif (($dt >= new DateTime('2014/04/01')) && ($dt < new DateTime('2015/10/01'))) {
        $tax = 0.08;
    } elseif ($dt >= new DateTime('2015/10/01')) {
        $tax = 0.10;
    }
    return $tax;
}

//定数を使用
$price = 1000;

$total1 = $price + ($price * TAX1);
print($total1 .'</br>');

$total2 = $price + ($price * TAX2);
print($total2 .'</br>');

$total3 = $price + ($price * TAX3);
print($total3 .'</br>');

?>
実行結果


constキーワード

クラス内で定数を定義する場合はconstキーワードを使用します。
constキーワードはPHP5から利用可能です。
<?php
class Constant {
    
    const TAX1 = 0.05;
    const TAX2 = 0.08;
    
    public function showTax() {
        print(Constant::TAX1 .'</br>');
        print(self::TAX2 .'</br>');
    }
}
?>
クラスに定義されている定数を使用するサンプルです。
<?php

print(Constant::TAX1 .'</br>');

$obj = new Constant();
print($obj::TAX2 .'</br>');

print($obj->showTax());
?>
クラス内からconstキーワードで定義された定数にアクセスするには「クラス名::定数名」または「self::定数名」とします。
クラス外からアクセスするには「クラス名::定数名」とします。
インスタンス経由でアクセスすることもできます。
$obj = new Constant();
print($obj::TAX2);

constキーワードはdefine()関数と違って、定数の宣言に演算やメソッドの戻り値を利用することはできません。
たとえば以下のような定数定義はエラーになります。
//演算を使う
const TAX = 1 * 0.05;
//ほかの定数を使う
const STR1 = 'aaa';
const STR2 = STR1 .'bbb';
//もちろんほかのメソッドの戻りなんて使えない
const VALE = getHoge();
またconstキーワードにはアクセス修飾子はつけられません。
そのためクラス内だけで有効なクラス外に公開したくない定数などは定義できません。


クラス定数の使いどころ

クラス定数の有効な使い方がわからなかったのでググってみたところ定数をグルーピングする方法がありました。
define()で定義した定数です。
define('WEEKDAY_MON', 1);
define('WEEKDAY_TUE', 2);
define('WEEKDAY_WED', 3);
define('WEEKDAY_THU', 4);
define('WEEKDAY_FRI', 5);
define('WEEKDAY_SAT', 6);
define('WEEKDAY_SUN', 7);

define('RESULT_YES', 1);
define('RESULT_NO', 2);
define('RESULT_CANCEL', 3);
クラス定数で定義すると以下のようになります。
define()で定義するより可読性がいいですが、列挙子のような感じですね。
class Weekday {
    const MON = 1;
    const TUE = 2;
    const WED = 3;
    const THU = 4;
    const FRI = 5;
    const SAT = 6;
    const SUN = 7;
}

class Result {
    const YES = 1;
    const NO = 2;
    const CANCEL = 3;
}


定数を定数値と定数名のペアで管理する

定数は定数値と定数名をペアで管理したい(定数名とは別に別名も管理したい)です。

スタティックメンバを使用した方法

PHPでクラスが使えるならと、いつも使っている方法で書いてみました。
なんだかな・・・といった書き方になってしまいました(´・ω・`)
クラスの変数の初期化にnew演算子が使えない事、スタティック変数を初期化するためのスタティックコンストラクタがないことが不便ですね・・・
cd; }
    public function get_name() { return $this->name; }
    public function get_aliasName() { return $this->aliasName; }
    
    protected function __construct($cd, $name, $aliasName = '') {
        $this->cd = $cd;
        $this->name = $name;
        $this->aliasName = $aliasName;
    }
}
//曜日定数クラス
final class Weekday extends ConstBase {
    protected function __construct($cd, $name, $aliasName = '') {
        parent::__construct($cd, $name, $aliasName);
    }

    private static $MON;
    private static $TUE;
    private static $WED;
    private static $THU;
    private static $FRI;
    private static $SAT;
    private static $SUN;

    public static function MON(){
        if (is_null(self::$MON)) { self::$MON = new Weekday(1,'月曜日','月'); }
        return self::$MON;
    }
    public static function TUE(){
        if (is_null(self::$TUE)) { self::$TUE = new Weekday(2,'火曜日','火'); }
        return self::$TUE;
    }
    public static function WED(){
        if (is_null(self::$WED)) { self::$WED = new Weekday(3,'水曜日','水'); }
        return self::$WED;
    }
    public static function THU(){
        if (is_null(self::$THU)) { self::$THU = new Weekday(4,'木曜日','木'); }
        return self::$THU;
    }
    public static function FRI(){
        if (is_null(self::$FRI)) { self::$FRI = new Weekday(5,'金曜日','金'); }
        return self::$FRI;
    }
    public static function SAT(){
        if (is_null(self::$SAT)) { self::$SAT = new Weekday(6,'土曜日','土'); }
        return self::$SAT;
    }
    public static function SUN(){
        if (is_null(self::$SUN)) { self::$SUN = new Weekday(7,'日曜日','日'); }
        return self::$SUN;
    }
}
//使用例
print(Weekday::MON()->get_cd() .':' .Weekday::MON()->get_name());
?>

連想配列を使用した方法

クラスの変数に配列を指定できるので、連想配列を使ってもうちょっとシンプルにしてみました。
<?php
define('CD','Cd');
define('NAME','Name');
define('ALIAS_NAME','AliasName');

//曜日定数クラス
final class Weekday {
  public static $MON = array(CD=>1, NAME=>'月曜日', ALIAS_NAME=>'月');
  public static $TUE = array(CD=>2, NAME=>'火曜日', ALIAS_NAME=>'火');
  public static $WED = array(CD=>3, NAME=>'水曜日', ALIAS_NAME=>'水');
  public static $THU = array(CD=>4, NAME=>'木曜日', ALIAS_NAME=>'木');
  public static $FRI = array(CD=>5, NAME=>'金曜日', ALIAS_NAME=>'金');
  public static $SAT = array(CD=>6, NAME=>'土曜日', ALIAS_NAME=>'土');
  public static $SUN = array(CD=>7, NAME=>'日曜日', ALIAS_NAME=>'日');
  
  public static function getItems(){
   return array(self::$MON, self::$TUE, self::$WED, self::$THU, self::$FRI, self::$SAT, self::$SUN);
  }

}
//使用例
print (Weekday::$MON[CD] .'</br>');
print (Weekday::$TUE[NAME] .'</br>');
print (Weekday::$WED[ALIAS_NAME] .'</br>');

foreach (Weekday::getItems() as $item) {
 print( $item[CD] .':' .$item[NAME] .'</br>' );
}

?>


定数で値と名称をペアで管理することって普通にあると思うんですけど、PHPでは一般的にどうするのでしょう?
PHPerの人だれか教えてm(´・ω・`)m

0 件のコメント: