Kat vs) (define

9 Cevap

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?

9 Cevap

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() 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:

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:

  • Consts bir ifadeden tanımlanamaz. const FOO = 4 * 3; çalışmaz, ama define('CONST', 4 * 3); yapar.
  • Geçirilen ad 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].

define i küresel sabitleri için kullanın.

const i sınıf sabitleri için kullanın.

You cannot define into class scope, and with const you can. Needless to say, you cannot use const outside class scope

Ayrıca, const ile, aslında define, küresel kapsamına itti olacak olan, sınıfın bir üyesi olur.

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.

  1. Sen ad kullanarak kapsam, sabitler yapabilirsiniz.
  2. You can use the "const" keyword outside of class definitions. However, just like in classes the values assigned using the "const" keyword must be constant expressions.

Ö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?

define genel amaçlı olduğunu ve const sınıflarında kullanılabilir.