[PHP] Type-Hinting für elementare Datentypen

[PHP] Type-Hinting für elementare Datentypen

Parantatatam

mag Cookies & Kekse
einfach nur crack hat eine neue Ressource erstellt:

[PHP] Type-Hinting für elementare Datentypen - [PHP] Type-Hinting für elementare Datentypen

Hallo Tutorianer,

es gibt eine Sache, die mich stets in PHP genervt hat. Es geht dabei darum, dass ich in eigenen Funktionen immer erst überprüfen muss, ob die übergebenen Werte den von mir erwarteten Datentypen haben. In anderen Sprachen wird das über Type-Hinting gelöst, was jedoch in PHP nur schwach ausgeprägt ist (Objekte, Arrays und ab Version 5.4 auch Callables). Deshalb habe ich nach einer Lösung gesucht, um dies auch für die elementaren Datentypen (Boolean, Integer, Double, String,...

Weitere Informationen zu dieser Ressource...
 
Zuletzt bearbeitet von einem Moderator:
Sehr interessant die Fehlerbehandlungsroutine für solche Zwecke zu "missbrauchen" ;)

Hast du schon mal einen Benchmark bezüglich der Performance erstellt?
 
Sehr interessant die Fehlerbehandlungsroutine für solche Zwecke zu "missbrauchen" ;)

Hast du schon mal einen Benchmark bezüglich der Performance erstellt?

Nein, bisher nicht, aber die Benchmarks unter den Kommentaren der verlinkten PHP-Seite sahen gut aus. Zumindest jene, die ohne das debug_backtrace() auskamen. Deshalb habe ich das auch unterschieden und verwende die Funktion nur dann, wenn sie wirklich gebraucht wird.

Nachtrag: Meine eigenen Benchmarks kann man jetzt auf Github einsehen.

Nebenbei: Nennt man so einen Missbrauch nicht für gewöhnlich "Hack"? :D
 
Zuletzt bearbeitet:
Nebenbei: Nennt man so einen Missbrauch nicht für gewöhnlich "Hack"? :D
Ja, durchaus ;)

Zu den Benchmarks:
Du misst bei denen nur die Zeit für den Funktionsaufruf. Die anfängliche Deklaration der Funktion verbraucht natürlich auch Zeit. Ich wollte darauf hinaus, in welcher Größenordnung der Performanceunterschied liegt, wenn man bei einem mittel bis großem Projekt alle Funktionen und Methoden mit deinen Type Hintings hinterlegt (- im Gegensatz zu den Funktionen ohne deine Type Hintings).

Ich probiere es mal jetzt selber aus.

Nachtrag Verglichen mit einem normalen Funktionsaufruf sind deine Type Hintings mindestens 50% langsamer. (Dies kann natürlich auch von diversen Optimierungen des PHP Bytecode-Compilers herrühren, z. B. meine Funktion mit leerem Rumpf als No-Op ansehen. Insgesamt sollte man mit selbst erstellten Benchmarks vorsichtig sein. An jeder Stelle kann der Compiler dies oder jenes noch machen, was man auf den ersten Blick nicht sieht. Aber dass deine Type Hintings langsamer sind, das ist ziemlich sicher daraus abzulesen.)
 
Bisher waren Benchmarks nicht so meine Sache. Genau genommen habe ich auf so etwas bisher nicht wirklich geachtet. Insofern wären Hinweise für richtige und gute Benchmarks gerne gesehen.
 
Siehe Aktualisierung oben.

Man könnte den XDebug Profiler mal ausprobieren.
Nicht direkt für PHP, aber für Java sehr relevant: http://www.ibm.com/developerworks/library/j-benchmark1/

Auf jeden Fall sollte die Anzahl der Durchläufe erhöht werden. Du bewest dich im Mikrosekunden-Bereich. Je höher die Anzahl der Durchläufe, desto mehr Aussagekraft wird der Mittelwert haben.
 
Mir war das durchaus bewusst, dass meine Benchmarks keine derartig spezifische Aussagekraft haben, jedoch kann man daraus durchaus eine Tendenz ablesen, die Du schon richtig geschildert hast. Außerdem war auch nicht davon auszugehen, dass der Code annähernd gleich lang für die Ausführung braucht.

Falls Du es schaffen solltest, ein besseres Benchmark zu erstellen, wäre es schön, wenn Du das irgendwo im Zusammenhang mit dieser Diskussion/diesem Artikel veröffentlichen könntest.
 
Super coole Idee. Ich hoffe nur das bald Facebooks Hack besser vertreten wird. Damit hat man diese Probleme dann nicht mehr.
 
einfach nur crack hat gesagt.:
Nebenbei: Nennt man so einen Missbrauch nicht für gewöhnlich "Hack"?

Ja, das ist leider ein Hack. Ich rate deshalb davon ab, den Code zu nutzen. Das soll aber überhaupt nicht heißen, dass das nicht gut programmiert ist oder so. Ein Bier gebe ich dir dafür gerne aus, falls ich dich mal treffe. Das ist definitiv kreativ. :)

Einige Probleme:

  1. Ich halte es nicht für sinnvoll, eine Anwendung darauf aufzubauen, interne PHP-Fehlermeldungen zu parsen. Das ist in meinen Augen nicht robust oder zukunftssicher.
  2. Sobald Namespaces im Spiel sind, muss es use int; oder function f(\int $i) { /* ... */ } heißen (der reguläre Ausdruck des Parsers muss entsprechend erweitert werden). Das sind eben keine Schlüsselwörter, es sind tatsächlich Klassen im globalen Namensraum, die nach den Regeln spielen müssen.
  3. Passend dazu: Sollten die PHP-Entwickler wirklich mal int und so als Schlüsselwörter einführen, zerbricht das einen mehr oder weniger großen Teil des Codes (indirekt vermutlich allen), der den hier vorgestellten Ansatz nutzt. Anders gesagt: Jeder, der diesen Ansatz nutzt, gibt den PHP-Entwicklern leider einen Grund, besagte Schlüsselwörter nicht hinzuzufügen (Abwärtskompatibilität). Auch ist es nur Spekulation, dass die Datentypen aus diesem Projekt und die Datentypen, die PHP vielleicht mal erhalten könnte, inhaltlich deckungsgleich wären.
  4. Es wird schwierig bis unmöglich, bestimmte andere Error-Handler zu setzen als den, den dieses Projekt benötigt. Error-Handler sind eben dummerweise global. Verdeutlichung dazu: Sobald eine andere Library auch diese Feature nutzt, gibt es hässliche Zuständigkeitskonflikte, die womöglich nur lösbar sind, indem permanent die Handler vertauscht werden. Das ist in PHP aber ein allgemeines Problem, das an zig Stellen besteht.
  5. Da die Klassen nur virtuell sind, verstehen IDEs und sonstige Tools das womöglich nicht.

Die Gewichtung dieser Einwände ist schon irgendwie Ermessenssache. Es ist natürlich auch möglich, das einfach nur für PHP 5.5 zu entwickeln. Dort lässt sich das ja wie vorgesehen nutzen.

Es ist nur leider so, dass es sich dabei thematisch um eine sehr grundlegende Geschichte handelt, die weitere Programmierung in hohem Maße beeinflusst. (Das ist wohl tatsächlich auch ein Grund, warum sich die Core-Leute damit so schwer tun.) Wenn ich mir durch dieses Projekt sicher sein kann, dass ein Parameter nur einen Integer (wie auch immer der genau definiert ist) enthalten kann, muss ich das in einer Funktion zum Beispiel nicht mehr testen und dergleichen. Ich kann den Code in der Funktion dann also auf eine bestimmte Weise schreiben.

Wenn dann aber wirklich mal entsprechende Schlüsselwörter in den Core kommen oder wenn irgendein Hack-Gedöns (das Facebook-Zeugs jetzt) übernommen wird, dann ist die Art und Weise, auf die ich meine Funktionen programmiert habe, vermutlich nicht mehr kompatibel. Dann muss ein großer Teil des Codes überarbeitet werden.

Das sind die Probleme mit den Hacks. Hacks sind nicht normativ, wodurch immer die Gefahr besteht, dass sie sich außerhalb dessen bewegen, was die Sprachdesigner möglicherweise im Sinn haben. Es ist leider nahezu unmöglich, das irgendwie sinnvoll zu kalkulieren.

Das ist alles… *seufz* ärgerlich. Ich schätze, solange niemand von der Größenordnung von hacklang das Zepter da mal wirklich in die Hand nimmt und die Infrastruktur umkrempelt, wird es keine befriedigenden Lösungen geben. :(
 
Zuletzt bearbeitet:
@einfach nur crack:

Ach ja, der Benchmark... :eek: Ehrlich gesagt kann mich gerade nicht dazu bewegen, dies in Angriff zu nehmen (ein wenig "kritisieren, aber selbst nichts machen"-Attitüde) :p

@mermshaus:

Schön zusammengeschrieben! Meiner Meinung nach hättest du schon nach Punkt #1 aufhören können. Dieser reicht für mich aus.

In letzter Zeit gibt es ja auch vermehrt Programmiersprachen, die einfach mittels einem Cross-Compiler in eine andere (low-level) Sprache umgewandelt werden. Beispiele sind TypeScript, Coffe Script, LESS, Haml, usw.
Wobei man bei TypeScript anmerken muss, dass sich die Autoren wirklich an zukünftigen EcmaScript-Standards orientieren.
 
Zurück