かなり簡単な質問:PHPでは、いつ使うのですか
define('FOO', 1);
そしていつ使用しますか
const FOO = 1;
両者の主な違いは何ですか?
PHP 5.3以降、 定数の定義 には2つの方法があります。const
キーワードを使うか、 define()
関数を使うかのいずれかです。
const FOO = 'BAR';
define('FOO', 'BAR');
これら2つの方法の基本的な違いは、const
はコンパイル時に定数を定義するのに対し、define
は実行時にそれらを定義することです。これはconst
のほとんどの不利な点を引き起こします。 const
の短所は次のとおりです。
const
を使用して定数を条件付きで定義することはできません。グローバル定数を定義するには、それを最も外側のスコープで使用する必要があります。
if (...) {
const FOO = 'BAR'; // invalid
}
// but
if (...) {
define('FOO', 'BAR'); // valid
}
どうしてそんなことをしたいのですか?一般的な用途の1つは、定数がすでに定義されているかどうかを確認することです。
if (!defined('FOO')) {
define('FOO', 'BAR');
}
const
は静的スカラー(数値、ストリング、またはtrue
、false
、null
、__FILE__
などの定数)を受け入れますが、define()
は任意の式を取ります。 PHP 5.6定数式はconst
でも使用できます。
const BIT_5 = 1 << 5; // valid since PHP 5.6, invalid previously
define('BIT_5', 1 << 5); // always valid
const
はプレーンな定数名を取りますが、define()
は任意の式を名前として受け入れます。これにより、次のようなことが可能になります。
for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}
const
は常に大文字と小文字を区別しますが、define()
では3つ目の引数としてtrue
を渡すことで大文字と小文字を区別しない定数を定義できます。
define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
だから、それは物事の悪い面でした。それでは、上記の状況のいずれかが発生しない限り、私が個人的に常にconst
を使用する理由を見てみましょう。
const
は単に読みやすくなります。これは関数ではなく言語構造であり、クラスで定数を定義する方法とも矛盾しません。const
は言語の構成要素であるため、自動化ツールによって静的に分析することができます。const
は現在のネームスペースの定数を定義しますが、define()
はフルネームスペース名を渡す必要があります。
namespace A\B\C;
// To define the constant A\B\C\FOO:
const FOO = 'BAR';
define('A\B\C\FOO', 'BAR');
PHP 5.6 const
定数も配列になることができますが、define()
はまだ配列をサポートしていません。ただし、PHP 7では、両方の場合で配列がサポートされます。
const FOO = [1, 2, 3]; // valid in PHP 5.6
define('FOO', [1, 2, 3]); // invalid in PHP 5.6, valid in PHP 7.0
最後に、const
はクラスまたはインターフェース内で クラス定数 またはインターフェース定数を定義するためにも使用できることに注意してください。 define
はこの目的には使用できません。
class Foo {
const BAR = 2; // valid
}
// but
class Baz {
define('QUX', 2); // invalid
}
まとめ
何らかの種類の条件付き定義や式定義が必要な場合を除き、define()
sの代わりにconst
sを使用してください - 単に読みやすくするためです。
PHP 5.3までは、グローバルスコープでconst
を使用できませんでした。これはクラス内からしか使えません。これは、そのクラスに関連するある種の定数オプションまたは設定を設定したい場合に使用する必要があります。あるいは、なんらかの列挙型を作成したいと思うかもしれません。
define
は同じ目的で使用できますが、グローバルスコープでのみ使用できます。アプリケーション全体に影響するグローバル設定にのみ使用してください。
const
の良い使い方の例はマジックナンバーを取り除くことです。 PDOの定数 を見てください。フェッチタイプを指定する必要がある場合は、たとえばPDO::FETCH_ASSOC
と入力します。 constが使用されていない場合は、35
(またはFETCH_ASSOC
が定義されているものは何でも)のように入力することになります。これは読者には意味がありません。
define
の適切な使用例は、アプリケーションのルートパスまたはライブラリのバージョン番号を指定することです。
私はこれがすでに答えられているのを知っています、しかし現在の答えのどれも名前空間とそれが定数と定義にどう影響するかについての言及をしません。
PHP 5.3以降、constsとdefineはほとんどの点で似ています。ただし、まだいくつか重要な違いがあります。
const FOO = 4 * 3;
は機能しませんが、define('CONST', 4 * 3);
は機能します。define
に渡される名前には、そのネームスペース内で定義されるネームスペースを含める必要があります。以下のコードは違いを説明するはずです。
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
ユーザーサブ配列の内容は['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
になります。
=== UPDATE ===
今後のPHP 5.6では、const
を使用してもう少し柔軟に対応できます。これらの式が他のconstまたはリテラルで構成されている場合、式に関してconstを定義できるようになります。これは、5.6から以下が有効になるはずであることを意味します。
const FOOBAR = 'foo ' . 'bar';
const FORTY_TWO = 6 * 9; // For future editors: THIS IS DELIBERATE! Read the answer comments below for more details
const ULTIMATE_ANSWER = 'The ultimate answer to life, the universe and everything is ' . FORTY_TWO;
それでも、変数や関数の戻り値の観点からconstを定義することはできません。
const RND = mt_Rand();
const CONSTVAR = $var;
まだ出ます。
PHP 5.3以降、2番目の例に示すように、クラスの外でconst
を使用できるようになります。
http://www.php.net/manual/en/language.constants.syntax.php
<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';
echo CONSTANT;
?>
define
私はグローバル定数に使用します。
const
私はクラス定数に使用します。
define
をクラスのスコープに入れることはできません。また、const
を使用することもできます。言うまでもなく、クラススコープ外でconst
を使用することはできません。
また、const
では実際にはクラスのメンバーになり、define
ではグローバルスコープにプッシュされます。
NikiCの答えが最も良いのですが、名前空間を使うときには明白でない警告を付け加えておきましょう。覚えておくべきことは、define名前空間をdefine識別子の一部として明示的に追加しない限り、defineはグローバル名前空間の always にあるということです。それについて明白ではないのは、名前空間付き識別子がグローバル識別子よりも優れているということです。そう :
<?php
namespace foo
{
// Note: when referenced in this file or namespace, the const masks the defined version
// this may not be what you want/expect
const BAR = 'cheers';
define('BAR', 'wonka');
printf("What kind of bar is a %s bar?\n", BAR);
// To get to the define in the global namespace you need to explicitely reference it
printf("What kind of bar is a %s bar?\n", \BAR);
}
namespace foo2
{
// But now in another namespace (like in the default) the same syntax calls up the
// the defined version!
printf("Willy %s\n", BAR);
printf("three %s\n", \foo\BAR);
}
?>
生成します:
What kind of bar is a cheers bar?
What kind of bar is a wonka bar?
willy wonka
three cheers
他の何十もの言語でのconstの考え方は、コードのどこにいても同じであるということであり、PHPはそれを保証するものではありません。
これらの答えのほとんどは間違っているか、あるいは物語の半分しか語っていません。
例えば:
const AWESOME = 'Bob'; // Valid
悪い例:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
変数定数を作成するには、define()を次のように使用します。
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
NikiCの答えを追加する。 const
は、クラス内で次のように使用できます。
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
define()
ではこれができません。
はい、constはコンパイル時に定義され、ニック状態には式を代入できません(define()の場合と同様)。しかし、constも条件付きで宣言することはできません(同じ理由で)。すなわち。これはできません。
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
あなたがdefine()でできるのに対して。それで、それは実際に個人的な好みに帰着しません、両方を使う正しいと間違った方法があります。
余談ですが、私は式を代入することができるある種のクラスconst、クラスに分離することができる一種のdefine()を見たいですか?
誰もphp-docについて何も言っていませんが、私にとっては、これもconst
を優先するための非常に重要な議論です。
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';
キーワード定数を定義すると、大文字と小文字を区別することができます。
鈍感ですが、constキーワードではそうではありませんでした。
define("FOO", 1,true);
echo foo;//1
echo "<br/>";
echo FOO;//1
echo "<br/>";
class A{
const FOO = 1;
}
echo A::FOO;//valid
echo "<br/>";
//but
class B{
define FOO = 1;//syntax error, unexpected 'define'
}
echo B::FOO;//invalid