O wydajności (strata czasu z mikrooptymalizacją jak ja), zobacz tę odpowiedź : constjest dwa razy szybsza niż define. Informacje o czasie ładowania strony i zużyciu pamięci: zobacz to pytanie i ten artykuł ... Zobacz także coś o pamięci podręcznej opcode tutaj .
Peter Krauss
2
Nie patrz tylko na aktualnie zaakceptowaną odpowiedź, ale spójrz na stackoverflow.com/a/3193704/1412157, tak jak powinna być zaakceptowana odpowiedź
LucaM
1
Właśnie zobaczyłem powiadomienie o Twoim komentarzu. Zaktualizowałem zaakceptowaną odpowiedź.
danjarvis
Odpowiedzi:
1039
W PHP 5.3 istnieją dwa sposoby definiowania stałych : albo za pomocą constsłowa kluczowego, albo za pomocą define()funkcji:
const FOO ='BAR';
define('FOO','BAR');
Podstawowa różnica między tymi dwoma sposobami polega na tym, że constdefiniuje stałe w czasie kompilacji, a definedefiniuje je w czasie wykonywania. To powoduje większość constwad. Niektóre wady const:
constnie można używać do warunkowego definiowania stałych. Aby zdefiniować stałą globalną, należy jej użyć w najbardziej zewnętrznym zakresie:
Dlaczego i tak chcesz to zrobić? Jedną z typowych aplikacji jest sprawdzenie, czy stała jest już zdefiniowana:
if(!defined('FOO')){
define('FOO','BAR');}
constPrzyjmuje skalarne statycznego (liczba znaków lub innych stałej jak true, false, null, __FILE__), przy czym define()bierze żadnej wypowiedzi. Ponieważ dozwolone są również wyrażenia stałe PHP 5.6 const:
const BIT_5 =1<<5;// Valid since PHP 5.6 and invalid previously
define('BIT_5',1<<5);// Always valid
constprzyjmuje zwykłą stałą nazwę, ale define()akceptuje każde wyrażenie jako nazwę. Pozwala to robić takie rzeczy:
consts zawsze rozróżniają małe i wielkie litery, podczas gdy define()pozwala ci definiować stałe bez rozróżniania wielkości liter, przekazując truejako trzeci argument (Uwaga: definiowanie stałych bez rozróżniania wielkości liter jest przestarzałe od PHP 7.3.0.):
define('FOO','BAR',true);
echo FOO;// BAR
echo foo;// BAR
To była zła strona. Spójrzmy teraz na powód, dla którego osobiście zawsze używam, constchyba że wystąpi jedna z powyższych sytuacji:
constpo prostu ładniej czyta. Jest to konstrukcja języka zamiast funkcji, a także jest spójna z tym, jak definiujesz stałe w klasach.
const, będący konstrukcją językową, może być analizowany statycznie za pomocą zautomatyzowanych narzędzi.
constdefiniuje stałą w bieżącej przestrzeni nazw, natomiast define()należy przekazać pełną nazwę przestrzeni nazw:
namespace A\B\C;// To define the constant A\B\C\FOO:const FOO ='BAR';
define('A\B\C\FOO','BAR');
Ponieważ conststałe PHP 5.6 mogą być również tablicami, a jednocześnie define()nie obsługują tablic. Jednak tablice będą obsługiwane dla obu przypadków w 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
Na koniec zauważ, że constmożna go również użyć w klasie lub interfejsie do zdefiniowania stałej klasy lub stałej interfejsu. definenie można użyć do tego celu:
classFoo{const BAR =2;// Valid}// ButclassBaz{
define('QUX',2);// Invalid}
Podsumowanie
O ile nie potrzebujesz żadnej definicji warunkowej lub wyrażeniowej, użyj consts zamiast define()s - po prostu ze względu na czytelność!
Jak wiem z PHP 5.6, będziesz mieć możliwość korzystania z prostych wyrażeń skalarnych nawet z constkonstrukcją języka - patrz wiki.php.net/rfc/const_scalar_exprs
mabe.berlin
6
Inną korzyścią z używania constjest brak cudzysłowów, co oznacza, że jest sformatowany tak samo, jak jest używany w twoim IDE.
rybo111
3
To powinno być to, co jest w dokumentach PHP. To najlepsze wytłumaczenie, jakie widziałem, szczególnie część, o której większość ludzi zapomina (kompilacja vs. środowisko uruchomieniowe).
James
4
define('a', $_GET['param']);, const b = a;działa idealnie i otrzymuje wartość, gdy const c = $_GET['param'];jest niepoprawna. Czy constnaprawdę jest czas kompilacji? Raczej nie sądzę ... (testowane na PHP 7.0.7)
mcserep
1
wiki.php.net/rfc/case_insensitive_constant_deprecation „ W PHP 8.0: Usuń możliwość deklarowania stałych bez rozróżniania wielkości liter. ” dla każdego, kto podejmie się tutaj w przyszłości w odniesieniu do rozróżniania wielkości liter
Scuzzy
196
Do PHP 5.3 constnie można było używać go w zakresie globalnym. Możesz użyć tego tylko z klasy. Należy tego użyć, gdy chcesz ustawić jakąś stałą opcję lub ustawienie, które dotyczy tej klasy. A może chcesz stworzyć jakiś wyliczenie.
definemożna użyć do tego samego celu, ale można go użyć tylko w zakresie globalnym. Należy go używać tylko do ustawień globalnych, które wpływają na całą aplikację.
Przykładem dobrego constużycia jest pozbycie się magicznych liczb. Spójrz na stałe PDO . Gdy musisz określić typ pobierania, wpisz PDO::FETCH_ASSOCna przykład. Gdyby consts nie były używane, skończyłbyś pisaniem czegoś takiego 35(lub cokolwiek FETCH_ASSOCzdefiniowanego jako). To nie ma sensu dla czytelnika.
Przykładem dobrego defineużycia może być określenie ścieżki katalogu głównego aplikacji lub numeru wersji biblioteki.
Warto wspomnieć o użyciu constz przestrzeniami nazw.
salathe
31
Należy również zauważyć, że PHP5.3 może bardzo dużo używać const w zakresie globalnym.
Gordon,
5.2 może również. Piękno consts vs. definiuje to, że musisz poprzedzić je nazwą klasy. Korzystanie z nich sprawia, że kod jest bardziej czytelny i ładniejszy. To dla mnie bonus.
lucifurious
1
@ryeguy, ale co z wersją PHP 5.3, gdzie const może być używany globalnie, tak jak zdefiniuj?
andho
1
@ andho, zrób kolejny krok do tańca PHP o jeden krok do przodu, jeden krok do tyłu, taniec „ulepszeń”. On. :)
Umowa prof. Falkena została naruszona
37
Wiem, że już na nie odpowiedziano, ale żadna z obecnych odpowiedzi nie wspomina o przestrzeni nazw i jej wpływie na stałe i definicje.
Począwszy od PHP 5.3, consts i definicje są podobne pod wieloma względami. Wciąż jednak istnieją pewne ważne różnice:
Stałych nie można zdefiniować na podstawie wyrażenia. const FOO = 4 * 3;nie działa, ale define('CONST', 4 * 3);działa.
Nazwa przekazywana do definemusi zawierać przestrzeń nazw, która ma zostać zdefiniowana w tej przestrzeni nazw.
Poniższy kod powinien zilustrować różnice.
namespace foo
{const BAR =1;
define('BAZ',2);
define(__NAMESPACE__ .'\\BAZ',3);}namespace{
var_dump(get_defined_constants(true));}
Nadchodzący PHP 5.6 pozwoli na nieco większą elastyczność const. Będziesz teraz mógł definiować stałe w kategoriach wyrażeń, pod warunkiem, że wyrażenia te składają się z innych stałych lub literałów. Oznacza to, że następujące informacje powinny obowiązywać od 5.6:
const FOOBAR ='foo '.'bar';const FORTY_TWO =6*9;// For future editors: THIS IS DELIBERATE! Read the answer comments below for more detailsconst ULTIMATE_ANSWER ='The ultimate answer to life, the universe and everything is '. FORTY_TWO;
Jednak nadal nie będziesz w stanie zdefiniować stałych w kategoriach zmiennych lub zwrotów funkcji, więc
Nie mogłem się powstrzymać od pytania: czy świadomie zdefiniowałeś FORTY_TWOjako 54?
Punchlinern
9
„Sześć na dziewięć? Czterdzieści dwa? Zawsze mówiłem, że z wszechświatem było coś zasadniczo nie tak”. Sprawdź dzieła Douglasa Adamsa, jeśli potrzebujesz pełnego wyjaśnienia.
GordonM,
2
O. Byłem świadomy, że 42 to odpowiedź na życie, wszechświat i wszystko, ale brakowało mi Szóstki o dziewięć części. Dziękuję za wyjaśnienie!
Punchlinern
22
Wierzę, że od PHP 5.3 możesz używać constpoza klasami, jak pokazano tutaj w drugim przykładzie:
Jak zauważono w innych odpowiedziach, const może być używany poza klasami w PHP 5.3+
MrWhite
Do utworzenia stałej w przestrzeni nazw można użyć tylko słowa kluczowego const, nie tylko klas
Alireza Rahmani Khalili,
16
Odpowiedź NikiC jest najlepsza, ale pozwól mi dodać nieoczywiste zastrzeżenie podczas korzystania z przestrzeni nazw, abyś nie złapał się na nieoczekiwanym zachowaniu. Należy pamiętać, że definicje są zawsze w globalnej przestrzeni nazw, chyba że jawnie dodasz przestrzeń nazw jako część identyfikatora definicji. Nie jest w tym oczywiste, że identyfikator przestrzeni nazw przebija identyfikator globalny. Więc :
<?php
namespace foo
{// Note: when referenced in this file or namespace, the const masks the defined version// this may not be what you want/expectconst 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);}?>
produkuje:
What kind of bar is a cheers bar?What kind of bar is a wonka bar?
willy wonka
three cheers
Co dla mnie sprawia, że całe pojęcie const jest niepotrzebnie mylące, ponieważ idea const w kilkudziesięciu innych językach jest taka, że zawsze jest taka sama, gdziekolwiek jesteś w kodzie, a PHP tak naprawdę tego nie gwarantuje.
Tak, ale BARi \foo\BARto tylko nie te same stałe. Zgadzam się, że to naprawdę mylące, ale jeśli weźmiesz również pod uwagę, że logika przestrzeni nazw jest spójna w ten sposób, i że ani constani nie define()jest jak makro C ( #define), to PHP może mieć jakąś wymówkę.
Sz.
1
Pojęcie stałej jest dokładnie takie, jak powinno się zachowywać - jesteś w przestrzeni nazw! Chcesz go bez identyfikatora przestrzeni nazw, a następnie utwórz go poza przestrzenią nazw. Uczyni to również spójność ze stałą zdefiniowaną w klasie, nawet jeśli używa innej składni. Tak, definicja jest również spójna, w inny sposób.
Gerard ONeill
12
Większość tych odpowiedzi jest błędna lub mówi tylko połowę historii.
Możesz zawęzić zakres przy użyciu przestrzeni nazw.
Możesz użyć słowa kluczowego „const” poza definicjami klas. Jednak, podobnie jak w klasach, wartości przypisane za pomocą słowa kluczowego „const” muszą być wyrażeniami stałymi.
PHP> = 5.6 wprowadzono pewne zmiany w kompilatorze Zend Engine i const jest teraz traktowany w inny sposób.
Ankit Vishwakarma
6
Tak, const są definiowane w czasie kompilacji, a ponieważ stanom nikic nie można przypisać wyrażenia, tak jak można zdefiniować (). Ale również stałych nie można warunkowo zadeklarować (z tego samego powodu). to znaczy. Nie możesz tego zrobić:
if(/* some condition */){const WHIZZ =true;// CANNOT DO THIS!}
Podczas gdy można to zrobić za pomocą definicji (). Tak więc tak naprawdę nie sprowadza się to do osobistych preferencji, istnieje poprawny i niewłaściwy sposób korzystania z obu.
Na marginesie ... Chciałbym zobaczyć jakąś klasę const, której można przypisać wyrażenie, rodzaj definicji (), którą można odizolować od klas?
const
jest dwa razy szybsza niżdefine
. Informacje o czasie ładowania strony i zużyciu pamięci: zobacz to pytanie i ten artykuł ... Zobacz także coś o pamięci podręcznej opcode tutaj .Odpowiedzi:
W PHP 5.3 istnieją dwa sposoby definiowania stałych : albo za pomocą
const
słowa kluczowego, albo za pomocądefine()
funkcji:Podstawowa różnica między tymi dwoma sposobami polega na tym, że
const
definiuje stałe w czasie kompilacji, adefine
definiuje je w czasie wykonywania. To powoduje większośćconst
wad. Niektóre wadyconst
:const
nie można używać do warunkowego definiowania stałych. Aby zdefiniować stałą globalną, należy jej użyć w najbardziej zewnętrznym zakresie:Dlaczego i tak chcesz to zrobić? Jedną z typowych aplikacji jest sprawdzenie, czy stała jest już zdefiniowana:
const
Przyjmuje skalarne statycznego (liczba znaków lub innych stałej jaktrue
,false
,null
,__FILE__
), przy czymdefine()
bierze żadnej wypowiedzi. Ponieważ dozwolone są również wyrażenia stałe PHP 5.6const
:const
przyjmuje zwykłą stałą nazwę, aledefine()
akceptuje każde wyrażenie jako nazwę. Pozwala to robić takie rzeczy:const
s zawsze rozróżniają małe i wielkie litery, podczas gdydefine()
pozwala ci definiować stałe bez rozróżniania wielkości liter, przekazująctrue
jako trzeci argument (Uwaga: definiowanie stałych bez rozróżniania wielkości liter jest przestarzałe od PHP 7.3.0.):To była zła strona. Spójrzmy teraz na powód, dla którego osobiście zawsze używam,
const
chyba że wystąpi jedna z powyższych sytuacji:const
po prostu ładniej czyta. Jest to konstrukcja języka zamiast funkcji, a także jest spójna z tym, jak definiujesz stałe w klasach.const
, będący konstrukcją językową, może być analizowany statycznie za pomocą zautomatyzowanych narzędzi.const
definiuje stałą w bieżącej przestrzeni nazw, natomiastdefine()
należy przekazać pełną nazwę przestrzeni nazw:Ponieważ
const
stałe PHP 5.6 mogą być również tablicami, a jednocześniedefine()
nie obsługują tablic. Jednak tablice będą obsługiwane dla obu przypadków w PHP 7.Na koniec zauważ, że
const
można go również użyć w klasie lub interfejsie do zdefiniowania stałej klasy lub stałej interfejsu.define
nie można użyć do tego celu:Podsumowanie
O ile nie potrzebujesz żadnej definicji warunkowej lub wyrażeniowej, użyj
const
s zamiastdefine()
s - po prostu ze względu na czytelność!źródło
const
konstrukcją języka - patrz wiki.php.net/rfc/const_scalar_exprsconst
jest brak cudzysłowów, co oznacza, że jest sformatowany tak samo, jak jest używany w twoim IDE.define('a', $_GET['param']);
,const b = a;
działa idealnie i otrzymuje wartość, gdyconst c = $_GET['param'];
jest niepoprawna. Czyconst
naprawdę jest czas kompilacji? Raczej nie sądzę ... (testowane na PHP 7.0.7)Do PHP 5.3
const
nie można było używać go w zakresie globalnym. Możesz użyć tego tylko z klasy. Należy tego użyć, gdy chcesz ustawić jakąś stałą opcję lub ustawienie, które dotyczy tej klasy. A może chcesz stworzyć jakiś wyliczenie.define
można użyć do tego samego celu, ale można go użyć tylko w zakresie globalnym. Należy go używać tylko do ustawień globalnych, które wpływają na całą aplikację.Przykładem dobrego
const
użycia jest pozbycie się magicznych liczb. Spójrz na stałe PDO . Gdy musisz określić typ pobierania, wpiszPDO::FETCH_ASSOC
na przykład. Gdyby consts nie były używane, skończyłbyś pisaniem czegoś takiego35
(lub cokolwiekFETCH_ASSOC
zdefiniowanego jako). To nie ma sensu dla czytelnika.Przykładem dobrego
define
użycia może być określenie ścieżki katalogu głównego aplikacji lub numeru wersji biblioteki.źródło
const
z przestrzeniami nazw.Wiem, że już na nie odpowiedziano, ale żadna z obecnych odpowiedzi nie wspomina o przestrzeni nazw i jej wpływie na stałe i definicje.
Począwszy od PHP 5.3, consts i definicje są podobne pod wieloma względami. Wciąż jednak istnieją pewne ważne różnice:
const FOO = 4 * 3;
nie działa, aledefine('CONST', 4 * 3);
działa.define
musi zawierać przestrzeń nazw, która ma zostać zdefiniowana w tej przestrzeni nazw.Poniższy kod powinien zilustrować różnice.
Zawartość pod-macierzy użytkownika będzie
['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.=== AKTUALIZACJA ===
Nadchodzący PHP 5.6 pozwoli na nieco większą elastyczność
const
. Będziesz teraz mógł definiować stałe w kategoriach wyrażeń, pod warunkiem, że wyrażenia te składają się z innych stałych lub literałów. Oznacza to, że następujące informacje powinny obowiązywać od 5.6:Jednak nadal nie będziesz w stanie zdefiniować stałych w kategoriach zmiennych lub zwrotów funkcji, więc
nadal będzie niedostępny.
źródło
FORTY_TWO
jako 54?Wierzę, że od PHP 5.3 możesz używać
const
poza klasami, jak pokazano tutaj w drugim przykładzie:http://www.php.net/manual/en/language.constants.syntax.php
źródło
define
Używam dla stałych globalnych.const
Używam dla stałych klas.Nie możesz
define
wchodzić w zakres zajęć, a wraz zconst
tobą możesz. Nie trzeba dodawać, że nie można używaćconst
poza zakresem klasy.Ponadto, z
const
, faktycznie staje się członkiem klasy, a zdefine
, zostanie przesunięty do zasięgu globalnego.źródło
Odpowiedź NikiC jest najlepsza, ale pozwól mi dodać nieoczywiste zastrzeżenie podczas korzystania z przestrzeni nazw, abyś nie złapał się na nieoczekiwanym zachowaniu. Należy pamiętać, że definicje są zawsze w globalnej przestrzeni nazw, chyba że jawnie dodasz przestrzeń nazw jako część identyfikatora definicji. Nie jest w tym oczywiste, że identyfikator przestrzeni nazw przebija identyfikator globalny. Więc :
produkuje:
Co dla mnie sprawia, że całe pojęcie const jest niepotrzebnie mylące, ponieważ idea const w kilkudziesięciu innych językach jest taka, że zawsze jest taka sama, gdziekolwiek jesteś w kodzie, a PHP tak naprawdę tego nie gwarantuje.
źródło
BAR
i\foo\BAR
to tylko nie te same stałe. Zgadzam się, że to naprawdę mylące, ale jeśli weźmiesz również pod uwagę, że logika przestrzeni nazw jest spójna w ten sposób, i że aniconst
ani niedefine()
jest jak makro C (#define
), to PHP może mieć jakąś wymówkę.Większość tych odpowiedzi jest błędna lub mówi tylko połowę historii.
Na przykład:
Zły przykład:
Aby utworzyć stałe zmiennych, użyj funkcji replace () w następujący sposób:
źródło
Tak, const są definiowane w czasie kompilacji, a ponieważ stanom nikic nie można przypisać wyrażenia, tak jak można zdefiniować (). Ale również stałych nie można warunkowo zadeklarować (z tego samego powodu). to znaczy. Nie możesz tego zrobić:
Podczas gdy można to zrobić za pomocą definicji (). Tak więc tak naprawdę nie sprowadza się to do osobistych preferencji, istnieje poprawny i niewłaściwy sposób korzystania z obu.
Na marginesie ... Chciałbym zobaczyć jakąś klasę const, której można przypisać wyrażenie, rodzaj definicji (), którą można odizolować od klas?
źródło
Aby dodać odpowiedź NikiC.
const
mogą być używane w ramach klas w następujący sposób:Nie możesz tego zrobić za pomocą
define()
.źródło
Nikt nie mówi nic o php-doc, ale dla mnie jest to również bardzo znaczący argument za preferencją
const
:źródło
Dzięki funkcji definiowania stałej słowa kluczowego uzyskasz możliwość rozróżniania wielkości liter, ale ze słowem kluczowym const nie.
źródło