Wann verwenden Sie in PHP?
define('FOO', 1);
und wann benutzt du
const FOO = 1;
?
Was sind die Hauptunterschiede zwischen diesen beiden?
Wann verwenden Sie in PHP?
define('FOO', 1);
und wann benutzt du
const FOO = 1;
?
Was sind die Hauptunterschiede zwischen diesen beiden?
Antworten:
Ab PHP 5.3 gibt es zwei Möglichkeiten , Konstanten zu definieren : Entweder mit dem const
Schlüsselwort oder mit der define()
Funktion:
const FOO = 'BAR';
define('FOO', 'BAR');
Der grundlegende Unterschied zwischen diesen beiden Methoden besteht darin, dass const
Konstanten zur Kompilierungszeit definiert werden, während define
sie zur Laufzeit definiert werden. Dies führt zu den meisten const
Nachteilen. Einige Nachteile von const
sind:
const
kann nicht verwendet werden, um Konstanten bedingt zu definieren. Um eine globale Konstante zu definieren, muss sie im äußersten Bereich verwendet werden:
if (...) {
const FOO = 'BAR'; // Invalid
}
// but
if (...) {
define('FOO', 'BAR'); // Valid
}
Warum willst du das überhaupt tun? Eine häufige Anwendung besteht darin, zu überprüfen, ob die Konstante bereits definiert ist:
if (!defined('FOO')) {
define('FOO', 'BAR');
}
const
nimmt einen statischen skalar (Zahl, eine Zeichenfolge oder eine andere Konstante wie true
, false
, null
, __FILE__
), während define()
nimmt jeden Ausdruck. Seit PHP 5.6 sind auch konstante Ausdrücke zulässig const
:
const BIT_5 = 1 << 5; // Valid since PHP 5.6 and invalid previously
define('BIT_5', 1 << 5); // Always valid
const
nimmt einen einfachen konstanten Namen an, während define()
jeder Ausdruck als Name akzeptiert wird. Dies ermöglicht Folgendes:
for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}
const
s unterscheiden immer zwischen Groß- und Kleinschreibung, während define()
Sie Konstanten ohne true
Berücksichtigung der Groß- und Kleinschreibung definieren können, indem Sie als drittes Argument übergeben (Hinweis: Das Definieren von Konstanten ohne Berücksichtigung der Groß- und Kleinschreibung ist ab PHP 7.3.0 veraltet.):
define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
Das war also die schlechte Seite der Dinge. Schauen wir uns nun den Grund an, warum ich persönlich immer benutze, es const
sei denn, eine der oben genannten Situationen tritt auf:
const
liest einfach schöner. Es ist ein Sprachkonstrukt anstelle einer Funktion und stimmt auch mit der Definition von Konstanten in Klassen überein.const
Als Sprachkonstrukt kann es durch automatisierte Werkzeuge statisch analysiert werden.const
definiert eine Konstante im aktuellen Namespace, während define()
der vollständige Namespace-Name übergeben werden muss:
namespace A\B\C;
// To define the constant A\B\C\FOO:
const FOO = 'BAR';
define('A\B\C\FOO', 'BAR');
Da PHP 5.6- const
Konstanten auch Arrays sein können, werden Arrays define()
noch nicht unterstützt. In PHP 7 werden jedoch Arrays für beide Fälle unterstützt.
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
Schließlich ist zu beachten , dass const
auch innerhalb einer Klasse oder Schnittstelle verwendet werden kann , eine definieren Klasse konstant oder Schnittstelle konstant. define
kann nicht für diesen Zweck verwendet werden:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
Zusammenfassung
Wenn Sie keine bedingte oder expressive Definition benötigen, verwenden Sie const
s anstelle von define()
s - einfach aus Gründen der Lesbarkeit!
const
Sprachkonstrukt zu verwenden - siehe wiki.php.net/rfc/const_scalar_exprs
const
ist das Fehlen von Anführungszeichen. Dies bedeutet, dass die Formatierung dort erfolgt, wo sie in Ihrer IDE verwendet wird.
define('a', $_GET['param']);
, const b = a;
funktioniert einwandfrei und erhält den Wert, solange er const c = $_GET['param'];
ungültig ist. Ist const
wirklich Kompilierzeit? Ich glaube kaum ... (getestet auf PHP 7.0.7)
Bis PHP 5.3 const
konnte nicht im globalen Bereich verwendet werden. Sie können dies nur innerhalb einer Klasse verwenden. Dies sollte verwendet werden, wenn Sie eine konstante Option oder Einstellung für diese Klasse festlegen möchten. Oder vielleicht möchten Sie eine Art Aufzählung erstellen.
define
kann für den gleichen Zweck verwendet werden, kann jedoch nur im globalen Bereich verwendet werden. Es sollte nur für globale Einstellungen verwendet werden, die sich auf die gesamte Anwendung auswirken.
Ein Beispiel für eine gute const
Verwendung ist das Entfernen magischer Zahlen. Schauen Sie sich die Konstanten der gU an . Wenn Sie einen Abruftyp angeben müssen, geben Sie PDO::FETCH_ASSOC
beispielsweise ein. Wenn consts nicht verwendet würden, würden Sie am Ende etwas wie 35
(oder was auch immer FETCH_ASSOC
als definiert ist) eingeben . Dies macht für den Leser keinen Sinn.
Ein Beispiel für eine gute define
Verwendung ist möglicherweise die Angabe des Stammpfads Ihrer Anwendung oder der Versionsnummer einer Bibliothek.
const
mit Namespaces zu erwähnen .
Ich weiß, dass dies bereits beantwortet wurde, aber in keiner der aktuellen Antworten wird der Namespace und die Auswirkungen auf Konstanten und Definitionen erwähnt.
Ab PHP 5.3 sind Konstanten und Definitionen in den meisten Punkten ähnlich. Es gibt jedoch noch einige wichtige Unterschiede:
const FOO = 4 * 3;
funktioniert nicht, aber define('CONST', 4 * 3);
funktioniert. define
muss den Namespace enthalten, der in diesem Namespace definiert werden soll.Der folgende Code sollte die Unterschiede veranschaulichen.
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
Der Inhalt des Benutzer-Subarrays wird sein ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.
=== UPDATE ===
Das kommende PHP 5.6 wird etwas mehr Flexibilität mit ermöglichen const
. Sie können nun Konstanten als Ausdrücke definieren, vorausgesetzt, diese Ausdrücke bestehen aus anderen Konstanten oder Literalen. Dies bedeutet, dass ab 5.6 Folgendes gültig sein sollte:
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;
Sie können jedoch immer noch keine Konstanten in Bezug auf Variablen oder Funktionsrückgaben definieren
const RND = mt_rand();
const CONSTVAR = $var;
wird noch raus sein.
FORTY_TWO
als 54 definiert ?
Ich glaube, dass Sie ab PHP 5.3 auch const
außerhalb von Klassen verwenden können, wie hier im zweiten Beispiel gezeigt:
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
Ich benutze für globale Konstanten.
const
Ich benutze für Klassenkonstanten.
Sie können nicht define
in den Klassenbereich und mit const
Ihnen können. Es ist unnötig zu erwähnen, dass Sie keinen const
externen Klassenbereich verwenden können.
Außerdem wird const
es tatsächlich ein Mitglied der Klasse, und mit define
wird es in den globalen Bereich verschoben.
Die Antwort von NikiC ist die beste, aber lassen Sie mich eine nicht offensichtliche Einschränkung hinzufügen, wenn Sie Namespaces verwenden, damit Sie nicht mit unerwartetem Verhalten erwischt werden. Beachten Sie, dass sich Definitionen immer im globalen Namespace befinden, es sei denn, Sie fügen den Namespace explizit als Teil des Definitionsbezeichners hinzu. Was daran nicht offensichtlich ist, ist, dass der Namespace-Bezeichner den globalen Bezeichner übertrifft. Damit :
<?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);
}
?>
produziert:
What kind of bar is a cheers bar?
What kind of bar is a wonka bar?
willy wonka
three cheers
Was für mich die ganze Konstanten-Vorstellung unnötig verwirrend macht, da die Idee einer Konstante in Dutzenden anderer Sprachen ist, dass sie immer gleich ist, wo immer Sie sich in Ihrem Code befinden, und PHP garantiert das nicht wirklich.
BAR
und \foo\BAR
sind einfach nicht die gleichen Konstanten. Ich bin damit einverstanden, dass es wirklich verwirrend ist, aber wenn Sie auch Dinge wie die Namespace-Logik auf diese Weise als konsistent betrachten, und das weder const
nochdefine()
wie ein C- Makro ( #define
), dann kann PHP eine Entschuldigung haben.
Die meisten dieser Antworten sind falsch oder erzählen nur die halbe Geschichte.
Zum Beispiel:
const AWESOME = 'Bob'; // Valid
Schlechtes Beispiel:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
Um variable Konstanten zu erstellen, verwenden Sie define () wie folgt:
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
Ja, const werden zur Kompilierungszeit definiert und da Nikic-Zuständen kein Ausdruck zugewiesen werden kann, wie dies bei define () der Fall ist. Aber auch consts können nicht bedingt deklariert werden (aus dem gleichen Grund). dh. Du kannst das nicht machen:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
Während Sie mit einem define () könnten. Es kommt also nicht wirklich auf die persönlichen Vorlieben an, es gibt einen richtigen und einen falschen Weg, beide zu verwenden.
Nebenbei ... Ich würde gerne eine Art Klassenkonstante sehen, der ein Ausdruck zugewiesen werden kann, eine Art define (), die für Klassen isoliert werden kann.
Um die Antwort von NikiC hinzuzufügen. const
kann innerhalb von Klassen auf folgende Weise verwendet werden:
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
Sie können dies nicht mit tun define()
.
Niemand sagt etwas über PHP-Doc, aber für mich ist das auch ein sehr wichtiges Argument für die Präferenz von const
:
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';
Mit der Definition der Schlüsselwortkonstante erhalten Sie die Möglichkeit, die Groß- und Kleinschreibung nicht zu berücksichtigen, mit dem Schlüsselwort const jedoch nicht.
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
ist zweimal schneller alsdefine
. Informationen zum Laden der Seite und zur Speichernutzung: Siehe diese Frage und diesen Artikel ... Weitere Informationen zum Opcode-Cache finden Sie hier .