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 constSchlüsselwort oder mit der define()Funktion:
const FOO = 'BAR';
define('FOO', 'BAR');
Der grundlegende Unterschied zwischen diesen beiden Methoden besteht darin, dass constKonstanten zur Kompilierungszeit definiert werden, während definesie zur Laufzeit definiert werden. Dies führt zu den meisten constNachteilen. Einige Nachteile von constsind:
constkann 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');
}constnimmt 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 validconstnimmt 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);
}consts unterscheiden immer zwischen Groß- und Kleinschreibung, während define()Sie Konstanten ohne trueBerü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; // BARDas war also die schlechte Seite der Dinge. Schauen wir uns nun den Grund an, warum ich persönlich immer benutze, es constsei denn, eine der oben genannten Situationen tritt auf:
constliest einfach schöner. Es ist ein Sprachkonstrukt anstelle einer Funktion und stimmt auch mit der Definition von Konstanten in Klassen überein.constAls Sprachkonstrukt kann es durch automatisierte Werkzeuge statisch analysiert werden.constdefiniert 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- constKonstanten 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.0Schließlich ist zu beachten , dass constauch innerhalb einer Klasse oder Schnittstelle verwendet werden kann , eine definieren Klasse konstant oder Schnittstelle konstant. definekann 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 consts anstelle von define()s - einfach aus Gründen der Lesbarkeit!
constSprachkonstrukt zu verwenden - siehe wiki.php.net/rfc/const_scalar_exprs
constist 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 constwirklich Kompilierzeit? Ich glaube kaum ... (getestet auf PHP 7.0.7)
Bis PHP 5.3 constkonnte 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.
definekann 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 constVerwendung ist das Entfernen magischer Zahlen. Schauen Sie sich die Konstanten der gU an . Wenn Sie einen Abruftyp angeben müssen, geben Sie PDO::FETCH_ASSOCbeispielsweise ein. Wenn consts nicht verwendet würden, würden Sie am Ende etwas wie 35(oder was auch immer FETCH_ASSOCals definiert ist) eingeben . Dies macht für den Leser keinen Sinn.
Ein Beispiel für eine gute defineVerwendung ist möglicherweise die Angabe des Stammpfads Ihrer Anwendung oder der Versionsnummer einer Bibliothek.
constmit 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. definemuss 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_TWOals 54 definiert ?
Ich glaube, dass Sie ab PHP 5.3 auch constauß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 definein den Klassenbereich und mit constIhnen können. Es ist unnötig zu erwähnen, dass Sie keinen constexternen Klassenbereich verwenden können.
Außerdem wird constes tatsächlich ein Mitglied der Klasse, und mit definewird 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.
BARund \foo\BARsind 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 constnochdefine() 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. constkann 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
constist 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 .