Hat PHP Symbole wie Ruby? Oder sollte ich einfach Strings als Schlüssel in einem assoziativen PHP-Array verwenden?
Ich vermute, es ist die gleiche Antwort wie die Frage Gibt es ein Python-Äquivalent zu Ruby-Symbolen?
Wenn Sie die Verwendung von Strings als Array-Schlüssel und die Tatsache, dass das Array kopiert und nicht jedes Mal als Verweis übergeben wird, als Problem betrachten, kann ich Ihnen vorschlagen, stdClass
zu verwenden, was im Grunde eine Objektklasse ist dynamisch verändert, Array-ähnlich, aber es verhält sich wie ein Objekt.
PHP hat nichts wie Symbole, und selbst Konstanten arbeiten in PHP deutlich anders als in Ruby. Array-Schlüssel müssen Zeichenfolge oder numerisch sein. Sie können einer Konstante eine Zeichenfolge oder eine Zahl zuweisen und dann die Konstante als Array-Schlüssel verwenden. Aber Konstanten sind in PHP statisch, also ist dies möglicherweise nicht das, was Sie wollen, erfordert mehr "Boilerplate" -Code, und der tatsächliche Array-Schlüssel wird immer noch entweder eine Zeichenkette oder eine Zahl sein (basierend auf dem Wert der Konstante).
Nein, PHP hat so etwas nicht. Die naheliegendste Annäherung in PHP wäre die Verwendung von Strings in einfachen Anführungszeichen für Ihre Hash-Schlüssel - nur um sicherzustellen, dass es keine "Interpolationen" in ihnen geben würde.
Einige Beispiele:
$arr[key]
- dies würde in den meisten Fällen wie $arr['key']
funktionieren, hat aber einige Nachteile:
a) Wenn es tatsächlich eine definierte Konstante gibt (z. B. define('key', 'rubbish')
- Zugriff auf $arr['rubish']
. So ist es einfach unsicher.
b) es würde "PHP Notice" -Nachrichten erzeugen (außer wenn Hinweise unterdrückt werden)
$arr[@key]
- wie vorher, aber ohne Hinweise. In der Tat ist die Unterdrückung von Fehlern sehr schlecht in Bezug auf die Wartbarkeit.
$arr["key"]
- absolut gültige Methode, es sei denn, Sie haben einige Sonderzeichen innerhalb der Zeichenfolge in doppelten Anführungszeichen. Zum Beispiel: "ab\ntc" != 'ab\ntc'
, "ab$c" != 'ab$c'
und so weiter. Aber es ist ein wenig paranoid, an solche Fälle zu denken, glaube ich.
$arr['key']
- das ist meiner Meinung nach am nächsten zu Rubys arr[:key]
, wie man es in PHP bekommen kann.
Sie können einfache Objekte verwenden, um ähnliche Effekte wie Symbole in Ruby zu erzielen. Einige Datenbankfunktionen verfügen über die Option FETCH_OBJECT, um diesen Effekt zu emulieren.
%Vor%Der Hauptvorteil von Symbolen ist die Verwendung als Hash-Schlüssel, um die Leistung und die Speichernutzung zu optimieren. Da PHP "Copy on write" zum Speichern von Variablen verwendet, können Strings ähnlich wie Symbole in Ruby sein. Aber PHP verwendet eine Art von Übersetzungstabelle, um den Index für ein Array von einem Hash-Schlüssel zu erhalten. Jedes kleine Array hat also einen gewissen Overhead.
Testscript
Ich habe dieses kleine Skript geschrieben, um den Speicherbedarf mit PHP zu testen.
%Vor%Hier sind die Ergebnisse mit den offiziellen Docker Images für PHP. Der richtige Wert ist der Speicherverbrauch in Bytes.
PHP 5.6
%Vor%PHP 7.0
%Vor%PHP 7.1
%Vor%Fazit
Objekte benötigen weniger Speicherplatz wie erwartet. Aber PHP 5.6 scheint Probleme mit der Garbage Collection mit Objekten zu haben. Die Ergebnisse von PHP 7.1 scheinen eine Art Compiler-Optimierung zu sein, denn es gibt keinen Unterschied zwischen "Copy on write" und dem Erstellen der Arrays.