PHP WTF #1

Ohne viel Worte: was kommt bei dem Code raus?

class çåèäßäöü
{
	public static function weird()
	{
		function stuff()
		{
			return 123;
		}
	}
}

echo çåèäßäöü::wEiRd().sTuFf();
echo çåèäßäöü::weird().stuff();

Geballte „weirdness“. Wenn man jemandem so einen Schnippsel vorlegt und ihn laut nachdenken lässt (Bewerbungsgespräch), stellen sich folgende Fragen

  1. Unicode in Klassennamen? Kann das gehen?
  2. Sind Funktionsnamen case sensitive?
  3. Nested Functions?
  4. Warum sind es 2 Calls?

Und nun zu Auflösung:

  1. Das geht! Klassen, Funktionen und Variablen dürfen unicode-Zeichen beinhalten. (Richtigstellung: Wie Fabian per Kommentar angemerkt hat, ist es kein „wirklicher“ unicode, denn die verwendbaren Zeichen beschränken sich auf den regulären Ausdruck
    [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

    Natürlich ist das nicht empfehlenswert, aber prinzipiell möglich)

  2. Auch das haut hin. Funktionen und Variablen sind nicht case sensitive. Klassen dagegen schon. Allerdings sind Funktionen und Variablen nur dann nicht case sensitive, wenn „normale“ Zeichen als Name verwendet werden. Heißt:
    function asd(){}
    AsD(); //geht klar
    
    function äöü(){}
    äÖü(); //Fatal error: Call to undefined function äÖü()
    
  3. Auch hier liegt noch nicht das Problem. Prinzipiell haut das hin…
  4. …, solang man nicht 2 mal die nested Function aufrufen muss, sonst: Fatal error: Cannot redeclare stuff() (previously declared …)
    Weitere korrigierende Darstellung (Dank an Fabian): Defacto handelt es sich nicht um wirkliche nested functions sondern um eine Verkettung, die die „nested function“ global deklariert. Deswegen klappt der Aufruf auch nur einmal ;).
  5. Weitere Posts:

Dieser Beitrag wurde unter php, PHP-WTF, webdev veröffentlicht. Setze ein Lesezeichen auf den Permalink.

8 Antworten auf PHP WTF #1

  1. Fabian sagt:

    Dass Klassen- und Methodennamen Unicode enthalten dürfen, ist allerdings falsch, die zulässigen Zeichen sind beschränkt auf ASCII (bzw. den jeweilig benutzten 8-bit Zeichensatz), siehe hier:

    http://de.php.net/manual/de/language.oop5.basic.php

    Regulärer Ausdruck für Klassennamen: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

    Analog gilt das selbe für Funktions- und Variablennamen

    Und du solltest vielleicht schon dazu schreiben, dass das hier keine nested function ist auch wenn du es so aussehen lässt…

    In çåèäßäöü::wEiRd().sTuFf(); ist der Punkt ein ganz normaler String-Verkettungs-Operator und es wird zunächst weird() aufgerufen, dort stuff() deklariert (dauerhaft im globalen namespace!) und dann stuff aufgerufen.

    1. david sagt:

      Danke für deinen Kommentar. Wenn es dann faktisch auch kein Unicode ist, kann man trotzdem alle möglichen Schandtaten treiben ;)


      <?php
      class ወለያዝያለማተሚያዎእንዲስማማ
      {
      public function __construct()
      {
      echo "test";
      }
      }

      $ወለያዝያለማተሚያዎእንዲስማማ = new ወለያዝያለማተሚያዎእንዲስማማ(); //test

      Deine Richtigstellung mit den „nested functions“, die eigentlich garkeine sind, habe ich eingebaut.

      1. Fabian sagt:

        Okay, so lange die einzelnen Bytes konform sind, geht auch das. Schandtat ist allerdings wirklich das richtige Wort dafür :D

  2. goreSplatter sagt:

    Ha. Die Regex für den Klassennamen beinhaltet auch 0xA0. Was zum whitespace of death Syndrom führt: http://perfect-co.de/2011/02/the-whitespace-of-death/

  3. David sagt:

    Der Beitrag ist zwar nun schon etwas älter, ich möchte aber trotzdem darauf hinweisen, dass die Aussage, dass Variablennamen case-insensitive wären, ebenso falsch ist. Klassen hingegen sind NICHT case-sensitive! Gerade getestet mit PHP 5.4.7:


    class foo {

    public $bar = 'foobar';

    }

    $foo = new Foo;
    var_dump($foo->bar, $foo->BAR);

    Das Ergebnis:

    Notice: Undefined property: foo::$BAR
    string(9) "foobar" NULL

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert