【PHP】 変数、const、defineの使い方と使い分け

PHPの変数には、明確な宣言が不要、変数名の頭に$をつけるなど、いくつか特徴があります。

PHPでは、変数名に変数を用いるメタプログラミングも簡単に書くことができます。

変数の宣言

PHPには、これと言って変数の宣言はありません。動的型付け言語であるため、型の指定もありません。Python等と同様に、代入されると変数が自動で作成されます。

また、変数名の頭に$を必ず付ける必要があります。

// いきなり代入で良い
$s = "Hello, PHP World!";
print($s);

変数名は$でスタートしますが、他言語と同様に数値を1つ目に持ってくることはできません。

$1stName = "hoge"; // NG
$_1stName = "hoge"; // OK

変数の初期化をせずに利用した場合

一切代入をしていない変数を使用しようとした場合、型が推測され、その型のデフォルトの値が取得されます。しかし、重大なバグの元になりうるため、通常は使わないようにします。

初期化していない変数を読み取ろうとすると警告が出るため、問題に気がつくことは可能です。

$a + 10; // 数値と計算しているので初期値は0。0 + 10になる
$b . "hoge"; // 文字列となら、初期値は空文字列になる
$c + 1.5; // 0.0になる (0ではない)

// 比較演算子を使うと、比較対象に関わらずnullになる
if ($z === null) {
    print("\$aは初期化されていないのでnull");
}

===は厳密等価演算子で、自動的な型変換を行わずに比較するものです。

例えば0 == falsetrueになりますが、0 === falseは型が異なるためfalseになります。

定数

PHPでは、constdefineを使用して定数を宣言できます。

const

PHPでは、constを付けることで代入不可能な変数を作成できます。この時、頭に$は不要です。

ここで、constには変数を代入できません100"hoge" . "fuga"といった変数を使わない値や式のみです。関数の戻り値やクラスのインスタンス (要はオブジェクト型) を代入などもできません。配列や連想配列は代入できます。

C++のconstexpr違い、関数の結果をコンパイル時に決定することができないなど、機能が小さめです。

また、PHPのconstは、オブジェクトの中身の変更もできなくなります。

const a = 100;
print(a); // 100

$b = 500;
const bb = $b; // Constant expression contains invalid operations

const c = a + 200; // 定数と値のみを使った式はOK

const d = [1, 2, 3];
d[1] = 200; // Cannot use temporary expression in write context

const e = ["a" => 100, "b" => 200];
e["a"] = 500; // 同上

後述するdefineを経由すれば、関数の戻り値や変数を設定できます。が、無意味なので普通はしないと思います。

define("HOGE", (function (){ return 100; })());

// const FUGA = (function (){ return 100; })(); はNG
const FUGA = HOGE;

print(FUGA); // 100
$hoge = 100;
define("HOGE", $hoge);

// const FUGA = $hoge; はNG
const FUGA = HOGE;

print(FUGA); // 100

constは、トップレベルやクラス内、namespace内のみで使用できます。 (つまり、関数内やブロック内では使用不可能)

if (true) {
    // トップレベルでないためNG
    const c = 100; // syntax error, unexpected token "const"
}

class Hoge {
    const FUGA = "100"; // OK

    function f() {
        return self::FUGA; // 使うときは self::定数名
    }
}

constは、名前空間が適用されます。

namespace Foo;

const HOGE = "hoge";
print(\Foo\HOGE); // hogeを出力

define

defineも定数を定義するものです。

defineでは、define("定数名", "入れる値");のように書きます。constと違い、入れる値には変数や関数の戻り値なども使用できます。 ただ、関数本体やインスタンスなど、オブジェクト型の値を入れることはできません。

define("HOGE", 100);
print(HOGE);

$a = 200;
define("FUGA", $a);
print(FUGA);

define("HIGE", (function() { return 300; })());
print(HIGE);
result
100200300
define("AA", function () {}); // Fatal error: Uncaught TypeError: define(): Argument #2 ($value) cannot be an object, ...

class Hoge {}
$hoge = new Hoge();
define("BB", $hoge); // ほぼ同上

define自体はどこでも宣言できますが、どこで宣言してもグローバルになります。

app.php
namespace Fuga {
    include "hoge.php";

    function f() {
        // namespace Fuga内で宣言しているが、hoge.phpのnamespace Hoge内でも使える
        define("FOO", 100);

        // hoge.phpのf()を呼び出し
        \Hoge\f();
    }
    f();
}
hoge.php
namespace Hoge {
    function f() {
        // app.phpのnamespace Fuga内で宣言したdefineが使える
        print(FOO);
    }
}

しかし、defineは実際にdefineされた後でないと使用できません。defineした後ならどこでも使えます。

function f() {
    define("FOO", 100);
}

// print(FOO); // Fatal error: Uncaught Error: Undefined constant "FOO" ...

f();
print(FOO); // OK

変数、const、defineの比較

普通の変数、const、defineの動作の違いを見てみましょう。

内容変数constdefine
再代入OXX
代入できる値何でも定数や、オブジェクト型でない値定数や、オブジェクト型でない変数や値、関数の戻り値
名前空間の反映OOX
クラスの反映OOX
スコープの反映O(トップレベル以外宣言不可能)X

書き換えができる変数はよく使いますが、constdefineの違いを知って適切に使い分けるようにすることが重要です。基本的には名前空間やクラスが反映されるconstを推奨します。

変数の削除

PHPでは、unsetを利用して変数を削除する (未定義の状態にする) ことができます。メモリ量が心配な場合などに使うと良いですが、基本的にはスコープで管理する、そもそものメモリ量を見直すなどをするため、変数の削除はあまり使いません。

unsetは配列や連想配列の要素削除にも用います。どちらかというと、その用途がメインです。

$a = 10;
print($a);
unset($a);
print($a);
result
10
Warning: Undefined variable $a in D:\Projects\shcool\app\資料用\practice\php\app.php on line 5

変数名に変数を用いる

変数名に変数を用いるメタプログラミングは、高度なプログラムを書くときに見受けられます。PHPでは、${式}のようにすることで、式の結果を変数名にすることができます。

$hoge = 'fuga';
$f = ${'ho' . 'ge'};
print($f . "\n");

$varname = 'hoge';
$f = ${$varname}; // $hoge の値を代入
print($f . "\n");

$varname = 'f';
${$varname} = 'foobar'; // $f に代入
print($f . "\n");
result
fuga
fuga
foobar

${ $varname }のように、波括弧にスペースが入っていても問題ありません。

まとめ

PHPの変数の宣言は、代入が実質的な宣言となります。動的型付け言語のため、型の指定もありません。

定数の扱いではconstdefineの違いを把握し、使い分けることが重要となります。

php var thumb

役に立ったらシェアしよう!