Facebook
Twitter
Google+
Kommentare
16

Arrays und „Strings“

So das Jahr ist fast rum. Morgen wird es den letzten Beitrag 2009 geben. Da ich morgen einen kleinen Jahresrückblick vorbereitet habe, habe ich heute noch mal die Chance mich ein wenig über PHP aufzuregen. Ja genau: ein kleines „What the fuck“ zum Jahresende. Eigentlich ist es ein wtf über das ich mich schon eine Weile aufrege, habe aber heute erst Lust darüber zu schreiben.

Ihr wisst ja, dass ich ein Freund der statischen Code-Analyse bin. Ich habe auch schon einige Artikel über den PHP_CodeSniffer veröffentlicht. Leider macht es einem PHP immer mal wieder besonders schwer Code zu analysieren. Schwache Typisierung, mein Freund „mixed“ oder variable Variablen machen einem zum Beispiel oft einen Strich durch die Rechnung. Tja dass ich halt der Preis, den man sich erkauft hat und dafür eine schnell erlernbare Sprache entwickelt hat. Das passt schon irgendwie. Zumindest rege ich mich nicht mehr drüber auf.

Betrachten wir aber mal einen ganz einfachen Fall eines Sniff für den Code Sniffer. Finde mir alle kleingeschriebenen Konstanten. Ganz einfach? Naja ich würde sagen Konstanten sind einfach zu finden. Doch leider fällt mir da mindestens ein Fall ein, bei dem das absolut nicht klappt. Nehmen wir den folgenden Ausdruck:

$array[ersterEintrag] = "1";

Tja, ist ersterEintrag denn jetzt als String zu interpretieren oder ist es eine Konstante? Oder wenn es beides sein könnte, was nehme ich dann zuerst.

Ich finde es ja toll, dass eine Sprache Rücksicht auf uns Entwickler nimmt, aber das geht doch ein Stück zu weit. Warum ist es genau an dieser Stelle erlaubt einen String nicht in Anführungszeichen zu setzen? Was unterscheidet dies von allen anderen Anwendungsfällen? Ich würde sagen NICHTS! Ich tippe mal drauf, dass sich schon viele Fehler in Programmen eingeschlichen haben, weil irgendjemand die Konstante ersterEintrag definiert hat und damit alle Arrays kaputt gemacht hat. Wobei? Wenn man konsequent mies programmiert, dann könnte sich das Problem selbst rauskürzen. Egal. Tut mir den Gefallen und verwendet immer Anführungszeichen um eure Strings herum, denn sonst bekommt ihr eines Tages Besuch von mir und bekommt den Hintern versohlt.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

16 Comments

  1. AMEN … ich versuch das seit Monaten irgendwie dem Azubi zu erklären, dieser weigert sich einfach das zu verinnerlichen.
    Ich habe es ihm zwar nun „befohlen“ in dem ich es in die Coding Vorschriften mit aufgenommen habe.
    Aber Sinn der Sache ist es ja nicht, solche elementaren Inhalte auf zu zwingen.

    -Spider

    PS: Die selbe Qual mit dem ?> Tag, an einer Sinn freien Stelle.

    Reply
  2. Ich wusste nicht, dass so etwas überhaupt geht. JavaScript ist ja z.T. ähnlich tolerant.

    Interessant wäre es ja schon hier ein Tool zu schreiben, das solche Fehler erkennt. Die Abstrakte Interpretation bietet hier ja zahlreiche Möglichkeiten. Vielleicht experimentiere ich da mal.

    Grüße
    Tobi

    Reply
  3. Wenn wir hier schon so strikt sind, sollten Zahlen nicht wie im o.g. Beispiel als Strings zugewiesen werden, sondern als String.
    Also:
    $array[‚ersterEintrag‘] = 1;

    Reply
  4. Naja, das stimmt so nicht, was du da schreibst.
    PHP interpretiert ersterEintrag schon als Konstante. Wenn er sie aber nicht findet, dann gibts eine Notice und DANN wird die Konstante zum String…

    Unschön ist es aber trotzdem

    Reply
  5. @Nils: Ab PHP 6 soll E_STRICT in E_ALL enthalten sein (siehe Zeile 480 in http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/php.ini-development?view=markup).

    Davon mal abgesehen, wird laut Dokumentation ein E_NOTICE statt eines E_STRICT geworfen (http://php.net/manual/en/language.types.array.php#language.types.array.foo-bar). Leider werden auch E_NOTICE in vielen PHP-Konfigurationen gefiltert.

    Meist fallen derartige Fehler spätestens beim Build (in den Unit-Tests) der PHP-Anwendung auf. Egal, wie die Entwickler PHP konfiguriert haben, beim Build wird eine sehr restriktive Konfiguration verwendet, wo auch E_NOTICE- und E_STRICT-Fehler auffallen. Und solange das Build nicht fehlerfrei durchläuft, solange kann auch die Anwendung nicht released werden (so zumindest die Theorie).

    Im Zeitalter von OOP sollte man prinzipiell auf die Definition globaler Konstanten verzichten. Sowas kann man wunderbar mittels Klassenkonstanten abbilden. Das hat 2 Vorteile: Selbst wenn ein Entwickler böses tut und obige Array-Anweisung verwendet, kann zumindest keine globale Konstante den Code kaputt machen. Die define()-Anweisung scheint nicht gerade optimal für die Performance einer PHP-Anwendung zu sein. Je mehr man darauf verzichtet, um so mehr tut man Gutes für die gesamte Performance (siehe http://www.andreas-haerter.de/Blog_post-Bessere-Performance-durch-Klassenkonstanten-statt-define.html).

    Reply
  6. So als Anmerkung:
    1. Link kaputt
    2. Nett, dass der Author des Artikels nur Thesen in den Raum wirft ^^
    3. Immerhin gibts ab 5.3 jetzt auch namespace-Konstanten 😉 Künstlich über Klassen für Konstanten Namensräume zu erzeugen klingt irgendwie dreckig.

    Reply
  7. > 1. Link kaputt

    Schade, dass die Blog-Software zwar Links erkennt, aber die schließende Runde Klammer mit dazu zählt. 🙁 Zum Glück gibt es aber noch Menschen, die die Technik des „Mark & Copy & Paste“ mit der Maus beherrschen. 😉

    > 2. Nett, dass der Author des Artikels nur Thesen in den Raum wirft

    Wenn die Betonung pauschal auf „nur“ liegt, stimme ich nicht zu. Was genau wird als These betrachtet (vorausgesetzt, man hat die Links gelesen)?

    > 3. Immerhin gibts ab 5.3 jetzt auch namespace-Konstanten 😉 Künstlich
    > über Klassen für Konstanten Namensräume zu erzeugen klingt irgendwie
    > dreckig.

    Schon ne eigenartige Wortwahl. Aber als „dreckig“ würde ich das nicht bezeichnen. Mal davon abgesehen: Es gibt Business-Anwendungen, die können nicht von heute auf morgen auf PHP 5.3 migriert werden. Da helfen dann Klassenkonstanten mehr als massenhaft define()-Anweisungen. Wer derartigen Code schreibt (eine statische Klasse als Konstanten-Container), ist selbst Schuld. Wo wir schon bei PHP 5.3 sind: Es gibt nen neues Schlüsselwort „const“, was define() ebenfalls vorzuziehen ist.

    Reply
  8. 2. Es wird unkommentiert in den Raum geworfen, dass per ‚define‘ deklarierte Konstanten langsamer sind. Die Erklärung klingt zwar schlüssig, was mir aber fehlt ist zum Beispiel wie sich das bemerkbar macht. Wenn die Differenz unter 10% liegt, nehme ich dafür keinen Designbruch in Kauf. Dies gilt sowohl mit, als auch ohne APC, wobei hier noch zu bemerken ist, dass APC nichtmal standardmässig mitgeliefert wird und deshalb für viele Fälle unerheblich ist (noch 😉 PHP6 kommt bestimmt).

    3. Jep, über das Wort „dreckig“ hab ich auch gegrübelt, entspricht aber dem klassischen „Quick&Dirty“ 😉 Von „massenhaft define()-Anweisungen“ habe ich nicht geredet, Klassenkonstanten haben durchaus ihre Berechtigung, aber das ist eben _nicht_ Konstanten in Namensräume zu verpacken. So als Faustformel hielt für mich immer her: Wenn Die Konstante nur von/für eine Klasse (oder dessen Erben) gebraucht wird, isse ne Klassenkonstante. Globale Variablen sind nunmal irgendwie … global ^^

    == „Wo wir schon bei PHP 5.3 sind: Es gibt nen neues Schlüsselwort “const”, was define() ebenfalls vorzuziehen ist.“

    Das meinte ich doch mit „Namespace-Konstanten“. Und ja, das is vermutlich vorzuziehen. Ja: Es ist wesentlich lesbarer (wunderte mich eh, wieso das jetzt erst kommt). Vielleicht: Performance. Das müsste man erstmal prüfen.

    Nur so als Anekdote. Versuch mal folgendes:

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen