Oldukça basit bir soru: PHP, sen ne kullanıyorsun
define('FOO', 1);
ve ne zaman kullanabilirim
const FOO = 1;
Bu ikisi arasındaki temel farklar nelerdir?
PHP 5.3 kadar, const, küresel kapsamda kullanılan olamazdı. Sen sadece bir sınıf içinde bu kullanabilirsiniz. O sınıfın ilgilidir sabit seçenek veya ayar çeşit ayarlamak istediğinizde bu kullanılmalıdır. Ya da belki enum çeşit oluşturmak istiyorum.
define, aynı amaç için kullanılabilir, ancak yalnızca küresel kapsamında kullanılabilir. Sadece tüm uygulamayı etkileyen global ayarlar için kullanılmalıdır.
Iyi const kullanımının bir örneği sihirli numaraları kurtulmak için. PDO's constants bir göz atın. Eğer bir getirme türü belirtmek gerektiğinde, örneğin, PDO::FETCH_ASSOC yazarsınız. Consts kullanılmadığı olsaydı, 35 (veya FETCH_ASSOC olarak tanımlanır ne olursa olsun) gibi bir şey yazarak bitirmek istiyorum. Bu okuyucu için hiçbir mantıklı.
Iyi define kullanımının bir örneği belki uygulamanın kök yolunu ya da bir kütüphanenin sürüm numarasını belirterek edilir.
PHP 5.3 olarak iki yolu vardır define constants: const anahtar sözcüğünü kullanarak veya define() a> işlevini kullanarak Ya:
const FOO = 'BAR';
define('FOO', 'BAR');
Bu iki yol arasındaki temel fark define bunları zamanında tanımlayan oysa const, derleme zamanında sabitlerini tanımlar olmasıdır. Bu sizin için ne anlama geliyor?
const koşullu sabitleri tanımlamak için kullanılamaz. Bu dış kapsamında kullanılmak üzere var
if (...) {
const FOO = 'BAR'; // invalid
}
// but
if (...) {
define('FOO', 'BAR'); // valid
}
Niye zaten bunu yapmak istersiniz? Bir yaygın uygulama sürekli zaten tanımlı olup olmadığını kontrol etmektir:
if (!defined('FOO')) {
define('FOO', 'BAR');
}
const statik skaler (kabul numarası dize veya gibi diğer sabit true, false, null, __FILE__ ) define() herhangi bir ifade alır oysa:
const BIT_5 = 1 << 5; // invalid
define('BIT_5', 1 << 5); // valid
define() adı olarak herhangi bir ifade kabul eder oysa const, düz bir sabit adını alır. Bu gibi şeyler yapmanızı sağlar:
for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}
const s her zaman define() Eğer true üçüncü argüman olarak ileterek harf duyarsız sabitleri tanımlamak için izin verir, oysa küçük harf duyarlıdır:
define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
Yani, o şeylerin kötü tarafı oldu. Şimdi ben şahsen her zaman kullanabilirsiniz const sürece yukarıdaki durumlardan biri oluşursa neden bir bakalım:
const Sadece güzel okur. Bu bir işlevi yerine bir dil yapısı var ve aynı zamanda sınıflarında sabitleri tanımlamak nasıl tutarlıdır.const s dil yapıları ve derleme zamanında tanımlandığı gibi define() s biraz daha hızlıdır.
Bu, iyi bir sabitler sayıda kullanırken PHP define() s yavaş olduğu bilinmektedir. İnsanlar bile bu almak için apc_load_constants() and hidef a> gibi şeyler icat.
const, yaklaşık iki kat daha hızlı (xdebug kalkınma makinelerde daha açık) sabitleri tanımını yapmak var. (Her ikisi de sabit tipleri aynı arama tablo paylaşmak gibi) diğer taraftan arama süresi değişmez: Demo.
Summary
Eğer koşullu veya anlatım tanımının her türlü ihtiyacınız olmadıkça, const yerine define() s s kullanabilirsiniz - sadece okunabilirlik uğruna!
Ben ikinci örnekte burada görüldüğü gibi PHP 5.3 gibi, sen sınıfların const dışında kullanabilirsiniz inanıyorum:
http://www.php.net/manual/en/language.constants.syntax.php
<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';
echo CONSTANT;
?>
Ben bu zaten cevap olduğunu biliyorum, ama şimdiki cevapların hiçbiri sabitleri ve tanımlar nasıl etkilediğini Namespacing herhangi bir anma yapmak ve.
PHP 5.3 itibariyle consts ve tanımlar birçok bakımdan benzer. Bazı önemli farklılıklar, ancak, hala var:
const FOO = 4 * 3; çalışmaz, ama define('CONST', 4 * 3); yapar.define bu ad içinde tanımlanacak ad içermelidir.Aşağıdaki kod farklılıkları göstermek gerekir.
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
Kullanıcı alt dizinin içeriği olacak ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3].
Nikic cevabı iyi olduğunu, ancak beklenmedik davranış ile yakalandı alamadım bu yüzden ad kullanırken bana olmayan bir açık ihtar ekleyelim. Hatırlanması gereken şey, açıkça tanımlayan kimliğinin bir parçası olarak ad eklemek sürece tanımlar küresel ad always olmasıdır. Ne bu konuda açık değildir isimalanlı tanımlayıcı küresel tanımlayıcı koz olduğunu. Yani:
<?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);
}
?>
üretir:
What kind of bar is a cheers bar?
What kind of bar is a wonka bar?
willy wonka
three cheers
Diğer dillerde onlarca bir const fikri size kodu olan yerde her zaman aynı olduğunu ve PHP gerçekten garanti etmez çünkü benim için bütün const kavramının gereksiz yere kafa karıştırıcı yapar Hangi.
Bu cevapların çoğu yanlış ya da sadece yarısı hikaye anlatıyorsun.
Örneğin:
const AWESOME = 'Bob'; // Valid
Kötü bir örnek:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
: Değişken sabitler oluşturmak için çok () gibi tanımlar kullanmak
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
Evet, const derleme sırasında tanımlanır ve () 'ler yapabilirsiniz tanımlamak gibi Nikic devletler, bir ifade atanamaz. Ama aynı zamanda const en şartlı (aynı nedenle) ilan edilemez. yani. Bunu yapamazsınız:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
Bir define () ile olabilir oysa. Yani, gerçekten kişisel tercihinize aşağı gelmez, doğru ve hem de kullanmak için yanlış bir yolu yoktur.
Bir kenara ... Ben sınıflar için izole edilebilir bir ifade atanabilir sınıf const çeşit, tanımlamak bir tür () görmek istersiniz?