PHP'de ne zaman kullanılır?
define('FOO', 1);
ve ne zaman kullanıyorsun
const FOO = 1;
?
Bu ikisi arasındaki temel farklar nelerdir?
PHP'de ne zaman kullanılır?
define('FOO', 1);
ve ne zaman kullanıyorsun
const FOO = 1;
?
Bu ikisi arasındaki temel farklar nelerdir?
Yanıtlar:
PHP 5.3'ten itibaren sabitleri tanımlamanın iki yolu vardır : Ya const
anahtar sözcüğü kullanarak ya da define()
işlevi kullanarak :
const FOO = 'BAR';
define('FOO', 'BAR');
Bu iki yol arasındaki temel fark const
, sabitleri derleme zamanında define
tanımlarken, onları çalışma zamanında tanımlamasıdır. Bu, const
dezavantajlarının çoğuna neden olur . Bazı dezavantajları const
:
const
koşullu olarak sabitleri tanımlamak için kullanılamaz. Küresel bir sabit tanımlamak için en dış kapsamda kullanılması gerekir:
if (...) {
const FOO = 'BAR'; // Invalid
}
// but
if (...) {
define('FOO', 'BAR'); // Valid
}
Bunu neden yapmak istiyorsun ki? Yaygın bir uygulama, sabitin önceden tanımlanmış olup olmadığını kontrol etmektir:
if (!defined('FOO')) {
define('FOO', 'BAR');
}
const
Statik bir sayıl (sayı, dize ya da benzeri diğer sabit kabul true
, false
, null
, __FILE__
), oysa define()
herhangi bir ifade alır. PHP 5.6 sabit ifadelerine de izin verildiğinden const
:
const BIT_5 = 1 << 5; // Valid since PHP 5.6 and invalid previously
define('BIT_5', 1 << 5); // Always valid
const
düz sabit bir ad alırken define()
, herhangi bir ifadeyi ad olarak kabul eder. Bu, bunun gibi şeyler yapmanıza izin verir:
for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}
const
s her zaman büyük / küçük harfe duyarlıdır, oysa büyük / define()
küçük harf duyarlı olmayan sabitleri true
üçüncü argüman olarak ileterek tanımlamanıza izin verir (Not: büyük / küçük harfe duyarlı olmayan sabitleri tanımlamak PHP 7.3.0'dan itibaren kullanımdan kaldırılmıştır):
define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
Yani, işlerin kötü tarafı buydu. Şimdi const
, yukarıdaki durumlardan biri meydana gelmedikçe kişisel olarak her zaman neden kullanmamın nedenine bakalım :
const
sadece daha güzel okur. Bir işlev yerine bir dil yapısıdır ve ayrıca sınıflardaki sabitleri nasıl tanımladığınızla tutarlıdır.const
, bir dil yapısı olan, otomatik takımlama ile statik olarak analiz edilebilir.const
define()
tam ad alanı adının geçirilmesi gerekirken , geçerli ad alanında bir sabit tanımlar :
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
sabitleri de diziler olabileceğinden, define()
henüz dizileri desteklemez. Ancak, PHP 7'de her iki durum için de diziler desteklenecektir.
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
Son olarak, const
bir sınıf sabitini veya arabirim sabitini tanımlamak için sınıf veya arabirim içinde de kullanılabileceğini unutmayın . define
bu amaçla kullanılamaz:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
özet
Herhangi bir koşullu veya ifade tanımına ihtiyacınız olmadığı sürece, const
s yerine s kullanın define()
- sadece okunabilirlik uğruna!
const
dil yapısının - bkz wiki.php.net/rfc/const_scalar_exprs
const
tırnak eksikliğidir, yani IDE'nizde kullanıldığı yerde biçimlendirilir.
define('a', $_GET['param']);
, const b = a;
mükemmel çalışır ve const c = $_GET['param'];
geçersizken değeri alır . Mı const
gerçekten derleme zamanı? Ben pek öyle düşünmüyorum ... (PHP 7.0.7 üzerinde test edilmiştir)
PHP 5.3'e kadar const
, global kapsamda kullanılamadı. Bunu sadece bir sınıf içinden kullanabilirsiniz. Bu, o sınıfa ait bir tür sabit seçenek veya ayar ayarlamak istediğinizde kullanılmalıdır. Ya da belki bir tür enum yaratmak istersiniz.
define
aynı amaç için kullanılabilir, ancak yalnızca global kapsamda kullanılabilir. Yalnızca tüm uygulamayı etkileyen genel ayarlar için kullanılmalıdır.
İyi bir const
kullanım örneği, sihirli sayılardan kurtulmaktır. PDO'nun sabitlerine bir göz atın . Bir getirme türü belirtmeniz gerektiğinde PDO::FETCH_ASSOC
, örneğin yazarsınız. Consts kullanılmasaydı, sonunda 35
(ya da FETCH_ASSOC
olarak tanımlanan herhangi bir şey) yazmak zorunda kalırsınız . Bu okuyucu için bir anlam ifade etmiyor.
İyi bir define
kullanım örneği, uygulamanızın kök yolunu veya kitaplığın sürüm numarasını belirtmektir.
const
alanlarıyla kullanımından bahsetmeye değer olabilir .
Bunun zaten cevaplandığını biliyorum, ancak mevcut cevapların hiçbiri ad boşluklarından ve sabitleri ve tanımları nasıl etkilediğinden bahsetmiyor.
PHP 5.3 itibariyle, sabitler ve tanımlar çoğu bakımdan benzerdir. Ancak yine de bazı önemli farklılıklar vardır:
const FOO = 4 * 3;
çalışmıyor ama çalışıyor define('CONST', 4 * 3);
. define
ad içermesi gerektiğini ad içinde tanımlanacak.Aşağıdaki kod farklılıkları göstermelidir.
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
Kullanıcı alt dizisinin içeriği olacaktır ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.
=== GÜNCELLEME ===
Yaklaşan PHP 5.6, biraz daha esneklik sağlayacaktır const
. Artık, bu ifadelerin diğer sabitlerden veya değişmez ifadelerden oluşması koşuluyla, ifadeleri ifade ederek tanımları tanımlayabileceksiniz. Bu, aşağıdakilerin 5.6'dan itibaren geçerli olması gerektiği anlamına gelir:
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;
Gereksinimleri yine de değişkenler veya işlev getirileri açısından tanımlayamazsınız, bu nedenle
const RND = mt_rand();
const CONSTVAR = $var;
hala dışarıda olacak.
FORTY_TWO
olarak 54 olarak tanımladınız mı?
PHP 5.3 itibariyle, const
burada ikinci örnekte gösterildiği gibi, sınıf 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;
?>
define
Global sabitler için kullanıyorum.
const
Sınıf sabitleri için kullanıyorum.
Yapamazsınız define
ile sınıf kapsam içine ve const
bunu yapabilirsiniz. Söylemeye gerek yok, const
dış sınıf kapsamını kullanamazsınız .
Ayrıca, const
aslında sınıfın bir üyesi haline gelir ve bununla birlikte define
küresel kapsama itilir.
NikiC'nin cevabı en iyisidir, ancak isim alanlarını kullanırken açık olmayan bir uyarı eklememe izin verin, böylece beklenmedik davranışlarla yakalanmıyorsunuz. Hatırlamanız gereken şey , ad alanını tanımlayıcı tanımlayıcının bir parçası olarak açıkça eklemediğiniz sürece , tanımların her zaman genel ad alanında olmasıdır. Bu konuda açık olmayan şey, ad boşluklu tanımlayıcının genel tanımlayıcıyı aşmasıdır. 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
Benim için tüm const kavramını gereksiz yere kafa karıştırıcı yapar çünkü onlarca başka dilde bir const fikri, kodunuzda nerede olursanız olun her zaman aynıdır ve PHP bunu gerçekten garanti etmez.
BAR
ve \foo\BAR
sadece vardır değil aynı sabitleri. Gerçekten kafa karıştırıcı olduğunu kabul ediyorum, ancak aynı zamanda ad boşlukları mantığı gibi şeylerin bu şekilde tutarlı olduğunu düşünürseniz ve bu ne bir C makrosu ( ) ne const
de ne olursa olsun , PHP'nin bir mazereti olabilir. define()
#define
Bu cevapların çoğu yanlış veya hikayenin sadece yarısını anlatıyor.
Örneğin:
const AWESOME = 'Bob'; // Valid
Kötü örnek:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
Değişken sabitleri oluşturmak için define () öğesini şu şekilde kullanın:
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
Evet, const derleme zamanında tanımlanır ve nikic durumlara tanım () 'ın yapabileceği gibi bir ifade atanamaz. Fakat aynı zamanda const'ler şartlı olarak beyan edilemez (aynı nedenden dolayı). yani. Bunu yapamazsın:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
Halbuki bir define () ile yapabilirsiniz. Yani, kişisel tercihe inmiyor, her ikisini de kullanmanın doğru ve yanlış bir yolu var.
Bir kenara ... Ben bir ifade atanabilir bir tür sınıf const, sınıflara izole edilebilir bir tür define () görmek ister misiniz?
NikiC'nin cevabına eklemek için. const
sınıflar içerisinde aşağıdaki şekilde kullanılabilir:
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
Bunu ile yapamazsın define()
.
Kimse php-doc hakkında bir şey söylemez, ama benim için bu da aşağıdakilerin tercihi için çok önemli bir argüman const
:
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';
Tanımlama anahtar kelime sabiti ile, büyük / küçük harfe duyarlı olmayan tesisler elde edersiniz, ancak const anahtar kelimesi ile almazsınız.
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
iki kat daha hızlıdırdefine
. Sayfa yükleme süresi ve bellek kullanımı hakkında: bu soruya ve bu makaleye bakın ... Ayrıca burada opcode önbellek ile ilgili bir şeye bakın .