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
- Unicode in Klassennamen? Kann das gehen?
- Sind Funktionsnamen case sensitive?
- Nested Functions?
- Warum sind es 2 Calls?
Und nun zu Auflösung:
- 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)
- 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 äÖü()
- Auch hier liegt noch nicht das Problem. Prinzipiell haut das hin…
- …, solang man nicht 2 mal die
nested Functionaufrufen 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 ;).
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.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.
Okay, so lange die einzelnen Bytes konform sind, geht auch das. Schandtat ist allerdings wirklich das richtige Wort dafür :D
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/
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