PHPでは、いつ使用しますか
define('FOO', 1);
いつ使用しますか
const FOO = 1;
?
これら2つの主な違いは何ですか?
PHPでは、いつ使用しますか
define('FOO', 1);
いつ使用しますか
const FOO = 1;
?
これら2つの主な違いは何ですか?
回答:
PHP 5.3のようには二つの方法があるの定数を定義するには:使用していずれかの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 and invalid previously
define('BIT_5', 1 << 5); // Always valid
const
プレーンな定数名を取りますが、define()
任意の式を名前として受け入れます。これにより、次のようなことが可能になります。
for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}
const
sは常に大文字と小文字を区別define()
しますがtrue
、3番目の引数として渡すことで大文字と小文字を区別しない定数を定義できます(注:大文字と小文字を区別しない定数の定義は、PHP 7.3.0で非推奨になりました)。
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 and valid in PHP 7.0
最後に、const
はクラスまたはインターフェース内で使用して、クラス定数またはインターフェース定数を定義することもできます。define
この目的には使用できません:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
概要
条件や式の定義が必要でない限り、単に読みやすくするために、const
sではなくsを使用してdefine()
ください。
const
言語構造を-見wiki.php.net/rfc/const_scalar_exprs
const
は、引用符がないことです。つまり、IDEで使用されるのと同じようにフォーマットされます。
define('a', $_GET['param']);
、const b = a;
完全に機能し、がconst c = $_GET['param'];
無効である間に値を取得します。でconst
、実際にコンパイル時間は?私はそうは思わない...(PHP 7.0.7でテスト済み)
PHP 5.3までconst
は、グローバルスコープでは使用できませんでした。クラス内からのみ使用できます。これは、そのクラスに関連するある種の定数オプションまたは設定を設定する場合に使用する必要があります。あるいは、ある種の列挙型を作成したいかもしれません。
define
同じ目的で使用できますが、グローバルスコープでのみ使用できます。アプリケーション全体に影響するグローバル設定にのみ使用してください。
良いconst
使い方の例は、マジックナンバーを取り除くことです。PDOの定数を見てください。フェッチタイプを指定する必要がある場合はPDO::FETCH_ASSOC
、たとえばと入力します。constsが使用されなかった場合は、次のようなもの35
(またはFETCH_ASSOC
定義されているもの)を入力することになります。これは読者には意味がありません。
良いdefine
使い方の例としては、アプリケーションのルートパスやライブラリのバージョン番号を指定することなどが考えられます。
const
名前空間での使用について言及する価値があるかもしれません。
私はこれがすでに回答されていることを知っていますが、現在の回答では、名前空間とそれが定数と定義にどのように影響するかについて言及していません。
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]
。
===更新===
次の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;
まだ出ます。
FORTY_TWO
54と定義しましたか?
PHP 5.3以降const
では、2番目の例に示すように、クラスの外でも使用できると思います。
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の答えが最善ですが、名前空間を使用する場合は、明白でない警告を追加して、予期しない動作に巻き込まれないようにします。覚えておくべきことは、定義がは、定義識別子の一部として名前空間を明示的に追加しない限り、常にグローバル名前空間にあるということです。それについて明白ではないのは、名前空間付き識別子がグローバル識別子より優先されるということです。そう :
<?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の概念全体を不必要に混乱させます。
BAR
と\foo\BAR
だけありません同じ定数。私はそれが本当に紛らわしいことに同意しますが、名前空間ロジックのようなものもこのように一貫していて、C マクロ()のようでもconst
ないと考える場合、PHPは何らかの言い訳を持つことができます。define()
#define
これらの答えのほとんどは間違っているか、話の半分しか伝えていません。
例えば:
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
はい、constはコンパイル時に定義されます。また、define()のようにnikic状態に式を割り当てることはできません。しかし、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';
defineキーワード定数を使用すると、大文字と小文字を区別しない機能が提供されますが、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
const
2倍の速さよりもありますdefine
。ページの読み込み時間やメモリ使用量について:参照この質問とこの記事を ...また、オペコード・キャッシュについて何かを参照してくださいここに。