Warum ist "traditionelles" Typhinweisen in PHP nicht erlaubt?

8

Habe gerade entdeckt, dass type-inding in PHP erlaubt ist, aber nicht für Ints, Strings , Bools oder Schwimmer.

Warum erlaubt PHP keine Typhinweise für Typen wie Integer, Strings, ...?

    
mpen 21.01.2011, 00:46
quelle

3 Antworten

9

PHP ist locker typisiert, wo Ihre "primitiven" Typen automatisch typ-jongliert sind basierend auf dem Kontext, in dem sie verwendet werden. Type-Hinting würde das nicht wirklich ändern, da eine Zeichenfolge könnte als int verwendet werden, oder umgekehrt. Typ-Hinting wäre nur für komplexe Typen wie Arrays und Objekte hilfreich, die nicht sauber als Ints, Strings oder andere Primitive jongliert werden können.

Um es anders auszudrücken, da PHP kein Konzept für bestimmte Typen hat, könnten Sie irgendwo ein int nicht benötigen, weil es nicht wirklich weiß, was ein int ist ist. Auf der anderen Seite ist ein Objekt eines bestimmten Typs, da eine MyClass nicht mit einer MyOtherClass austauschbar ist.

Hier ist nur, was passiert, wenn Sie versuchen, zwischen solchen Typen zu konvertieren (keine erschöpfende Liste):

In Objekt konvertieren ( ref )
"Wenn ein Objekt in ein Objekt konvertiert wird, wird es nicht geändert. Wenn ein Wert eines anderen Typs in ein Objekt konvertiert wird, wird eine neue Instanz der integrierten Klasse stdClass erstellt Wert war NULL, die neue Instanz ist leer. Arrays werden in ein Objekt mit Eigenschaften konvertiert, die durch Schlüssel und entsprechende Werte benannt sind. Für jeden anderen Wert enthält eine Elementvariable mit dem Namen skalar den Wert. "

Objekt für int / float ( ref )
undefiniertes Verhalten

Objekt zu boolean ( ref )
in PHP5 immer TRUE

Objekt zu string ( ref )
Die __toString() magische Methode des Objekts wird aufgerufen, wenn anwendbar.

Objekt für Array ( ref )
"Wenn ein Objekt in ein Array konvertiert wird, ist das Ergebnis ein Array, dessen Elemente die Eigenschaften des Objekts sind. Die Schlüssel sind die Namen der Mitgliedsvariablen, mit einigen bemerkenswerten Ausnahmen: auf Integer-Eigenschaften kann nicht zugegriffen werden, private Variablen haben den Klassennamen Variablenname: Geschützte Variablen haben vor dem Variablennamen ein '*'. Diese vorangestellten Werte haben auf jeder Seite null Bytes. Dies kann zu unerwartetem Verhalten führen. "

Array zu int / float ( ref )
undefiniertes Verhalten

Array zu boolean ( ref )
Wenn das Array leer ist (d. H. Keine Elemente), wird FALSE ausgewertet - andernfalls TRUE.

Array zu string ( ref )
die Zeichenkette "Array"; Verwenden Sie print_r() oder var_dump() , um den Inhalt eines Arrays zu drucken

Array to object ( ref )
"Arrays konvertieren in ein Objekt mit Eigenschaften, die durch Schlüssel und entsprechende Werte benannt sind."

    
Wiseguy 21.01.2011, 00:56
quelle
10

Ab PHP 7.0 gibt es Unterstützung für bool , int , float und string . Unterstützung wurde im skalaren RFC-Typ hinzugefügt. Es gibt zwei Modi: schwach und streng. Ich empfehle, den RFC zu lesen, um die Unterschiede vollständig zu verstehen, aber im Wesentlichen treten Typumwandlungen nur im schwachen Modus auf.

Gegeben dieser Code:

%Vor%

Im schwachen Modus (der Standardmodus) wird "1" in 1 konvertiert.

Um strikte Typen zu aktivieren, fügen Sie declare(strict_types=1); am Anfang der Datei hinzu. Im strikten Modus wird ein Fehler ausgegeben:

  

Fataler Fehler: Argument 1, das an mul2 () übergeben wurde, muss vom Typ integer, string

sein
    
Levi Morrison 12.05.2015 18:31
quelle
1

Es ist nicht korrekt, es "type hinting" zu nennen. "Andeutung" impliziert, dass es sich um eine optionale Eingabe handelt, ein einfacher Hinweis anstelle einer Anforderung, jedoch sind eingegebene Funktionsparameter überhaupt nicht optional. Wenn Sie einen falschen Typ angeben, erhalten Sie den schwerwiegenden Fehler. Es "Typ Hinting" zu nennen war ein Fehler.

Nun zu den Gründen, warum es keine primitive Typisierung für Funktionsparameter in PHP gibt. PHP hat keine Barriere zwischen primitiven Typen - also String, Integer, Float, Bool - sind mehr oder weniger austauschbar, Sie können $a = "1"; und dann echo $a+3; haben und 4 bekommen. Alle internen Funktionen funktionieren auch auf diese Weise - wenn die Funktion eine Zeichenfolge erwartet und Sie eine Ganzzahl übergeben, wird sie in eine Zeichenfolge konvertiert. Wenn die Funktion einen Gleitkommawert erwartet und eine Ganzzahl erhält, wird sie in Gleitkomma umgewandelt usw. es gibt keine Konvertierung zwischen, sagen wir, SimpleXMLElement und DirectoryIterator - beides könnte nicht sein, es würde keinen Sinn ergeben.

Wenn Sie also eine Funktion einführen, die die Ganzzahl 1 und nicht die Zeichenfolge 1 akzeptiert, erstellen Sie eine Inkompatibilität zwischen internen Funktionen und Benutzerfunktionen und erstellen Probleme für jeden Code, der davon ausgeht, dass diese weitgehend übereinstimmen. Dies wäre eine große Veränderung in der Art und Weise, wie PHP-Programme sich verhalten, und diese Änderung muss durch den gesamten Code, der solche Funktionen verwendet, weitergegeben werden, da ansonsten Fehler beim Übergang zwischen "striktem" und "nicht-strengem" Code auftreten. Dies würde eine Notwendigkeit von Typenvariablen, typisierten Eigenschaften, typisierten Rückgabewerten usw. implizieren - große Veränderung. Und da PHP keine kompilierte Sprache ist, profitieren Sie nicht von der statischen Steuerung mit den Schattenseiten - Sie bekommen nur Unannehmlichkeiten, aber nicht die zusätzliche Sicherheit. Dies ist der Grund, warum Parameter-Typisierung in PHP nicht akzeptiert wird.

Es gibt eine andere Option - die zwangsweise Typisierung, d. h. das Verhalten, das analog zu dem ist, was interne Funktionen tun - zwischen den Typen zu konvertieren. Leider befriedigt dieser die Befürworter der strengen Typisierung nicht, und daher ist bisher kein Konsens gefunden worden und somit ist keiner da.

Andererseits wurden Objekttypen nie kontrovers diskutiert - es ist klar, dass es keine Konvertierung zwischen ihnen gibt, kein Code geht davon aus, dass sie austauschbar sind und Prüfungen können nur für sie streng sein, und dies ist sowohl bei internen als auch bei externen Funktionen der Fall . Daher war die Einführung strenger Objekttypen kein Problem.

    
StasM 21.01.2011 01:26
quelle

Tags und Links