Was fehlt dir an PHP?
PHP bietet oft neue Releases mit neuen Features. Nicht immer sind es große Features, aber ab und zu erblicken wir erfreut Funktionen, die das Programmieren vereinfachen bzw. vorher selbst geschriebene Funktionen überflüssig machen. Doch einige Features wünscht man sich schon lange, und es gibt sie einfach nicht. Welches genau diese gewünschten Features sind möchte ich hier sammeln, vielleicht liest es ja jemand aus dem PHP-Team mit und schlägt es für eine Umsetzung vor.
Da ich auch nach minutenlangem Überlegen nichts gefunden habe was mit an der Sprache fehlt, möchte ich hier die Überlegungen von Florian Heinze vorstellen.
—————————————————–
Eine kleine Funktion die das Vorhandensein einer Variablen oder eines Array-Elements prüft, und dann entweder die Variable zurückliefert oder NULL.
$var = isset($foo) ? $foo : null;
vereinfachen zu
$var = ifset($foo);
Die beiden folgenden Zeilen sind nicht equivalent und tun nicht das was gewünscht ist:
$var = $foo ?: null; $var = isset($foo) ?: null;
—————————————————–
Nachträglich Getter+Setter für ein Klassen-Attribut erstellen, ohne die aufrufenden Befehle zu ändern. In C# funktioniert das so:
private string _name; public string Name { get { return this._name; } set { this._name = value.ToLowerCase(); } }
—————————————————–
Die vorhandene Funktion array_merge_recursive fügt Arrays nicht so zusammen wie man es manchmal benötigt, beispielsweise für Konfigurationsdateien, wo man eine Hauptkonfiguration hat und dann je nach Umgebung eine weitere Konfiguration dazulädt, wobei die spezielleren Einstellungen die Standardwerte überschreiben sollen. Bei array_merge_recursive werden Arrays zwar zusammengeführt, aber die Werte im selben Array werden nicht überschrieben, sondern angehängt.
<?php $ar1 = array("width" => 10, "color" => array("favorite" => "red")); $ar2 = array("color" => array("favorite" => "green")); $result = array_merge_recursive($ar1, $ar2);
wird zu
array( "width" => 10, "color" => array( "favorite" => array("red", "green") ) )
gewünscht ist aber in diesem Fall
array( "width" => 10, "color" => array( "favorite" => "green" ) )
—————————————————–
Die größte Heldentat um PHP sicherer zu machen wäre für htmlspecialchars() und htmlentities() kürzere Versionen anzubieten. Diese beiden so wichtigen Funktionen sind ja sowas von zu lang und hässlich in HTML-Views das sie keiner verwenden mag 😉 Besser wäre ein schlichtes kurzes esc()!
—————————————————–
Über was seid ihr so gestolpert in den letzten Jahren, was fehlt, was ist stark verbesserungswürdig, wofür müßt ihr andauernd Helferfunktionen bereitstellen, was eigentlich die Sprache bereits mitliefern sollte?
Worüber ich mich freuen würde, wäre sowas:
function foo()
{
return array(„foo“ => „bar“, „baz“ => „foo“);
}
$myvar = foo()[„baz“];
David Müller
13 Dez 10 at 09:45
@David: das wird mit einer der nächsten großen Versionen wohl kommen (5.4?). Siehe http://schlueters.de/blog/archives/138-Features-in-PHP-trunk-Array-dereferencing.html
Michael Kliewe
13 Dez 10 at 09:48
Weltklasse! Danke für die Info.
David Müller
13 Dez 10 at 09:50
mir fehlt enorm das überladen von funktionen
__constuct(int x, int y)
__contruct(Point p)
…..
ein gigantisches problem ist die fehlende Typisierung, ab der spl 3.0, php 5.3.4 sind diese jedoch als hint möglich?
tim
13 Dez 10 at 09:54
1) Dass mal aufgeräumt wird: Funktionen alle einheitlich mit oder ohne Unterstrichen (strpos/str_pad), needle und haystack überall in der gleichen Reihenfolge.
2) Optionale type hints für bool, int usw, die dann auch Exceptions werfen.
3) Optionale Angabe des Rückgabetyps von Funktionen, die dann ebenfalls Exceptions werfen.
4) Vielleicht noch ne schnellere Array-Notation: $myArray = [„Foo“ : „Bar“, „Key“ : „Value“];
Daniel
13 Dez 10 at 10:02
Ich bin klar dafür dass Type-Hints zum Zwang werden und Variablen-Typen nicht einfach so überschrieben werden können. Klar, wäre dann ein anderes PHP, aber einfach besser/schöner zu programmieren… und dies sollte der Standard sein. natürlich konfigurierbar wie man es lieber hat.
Array-Deferencing will ich auch!
Georges Jentgen
13 Dez 10 at 10:28
Wie bereits einige vor mir angemerkt haben, wäre ich für Type Hints ebenfalls sehr dankbar. Ob es allerdings zum Zwang werden muss, halte ich für fraglich. Lediglich sollte auch bei primitiven Datentypen diese Möglichkeit (optional) gegeben werden.
Zudem halte ich auch eine Funktion, wie die im Artikel beschriebene Variante „ifset()“ für absolut sinnvoll! Immer wieder stoße ich leider auf dieses Problem. Eine eigene Funktion hierfür zu schreiben ist m.E. nicht möglich, da ja bereits beim Funktionsaufruf der entsprechende Key nicht existiert und somit die Übergabe undefined ist (ich lasse mich aber gerne eines besseren belehren, falls das doch irgendwie möglich sein sollte).
Zudem fände ich noch schön hier einen default-Wert optional angeben zu können, falls die Variable nicht gesetzt ist. Beispielsweise so:
ifset($array[‚key‘], false);
Entweder wird hier der entsprechende Wert ausgeliefert oder eben false, als default-Wert, wenn der Schlüssel in $array nicht existiert.
Bereits angesprochen wurde auch das Überladen von Methoden. Um dies zu ermöglichen muss man in PHP leider viel zu große Umwege gehen, ohne letztendlich ein wirkliches Überladen erreichen zu können. Dank des fehlenden Type Hinting Zwangs sind Funktionsaufrufe mit verschiedenen Parameter-Typen zwar gut möglich, allerdings führt das eben oftmals zu sehr großen Umwegen und einem erhöhten Fehlerrisiko. Ein klares Überladen von Methoden wäre also enorm hilfreich.
Tim | not-null.de
13 Dez 10 at 10:48
Auf Array-Deferencing hab ich schon mit Version 5.3 gehofft. Wäre Prima wenn das mit der nächsten Version kommt.
Ansonsten hätte gern, dass switch etwas zurückgeben kann.
bsp.:
$ret = switch ($action) {
case 1: return 1;
case 2: return 2;
default: return false;
}
Eric
13 Dez 10 at 11:07
Auch wenn ich es nicht bekommen werde*: „finally“ hätte ich sehr gerne auch in PHP gehabt.
*: http://wiki.php.net/todo/backlog
(sehr alter feature request): http://bugs.php.net/bug.php?id=32100 )
Edo
13 Dez 10 at 11:30
Ich hätte gerne eine funktion á la
function del_element_in_array($element, $array)
{
if(in_array($element, $array))
{
$result = search_array($element, $array);
unset($array[$result])
}
}
Der Funktionsname sollte dann natürlich kürzer sein. Hier ist er nur zum besserem Verständnis so lang.
Allerdings denke ich dadurch das PHP nicht Typsicher ist und man die Parameter im Methodenkopf schon vordefinieren kann, dass überladen von Methoden überflüssig ist. Man müsste Tatsächlich erst Grundlegende Dinge ändern um das Überladen möglich zu machen. Aber dann ist PHP eben nicht mehr PHP sondern mehr und mehr ein Abklatsch von Java. Es sind eben Dinge wie das nicht vorhanden sein der Typsicherheit, die die Sprache so einfach und beliebt machen. Das sollte man nicht ändern.
José Stiller
13 Dez 10 at 12:08
1: Überladen von Klassen Methoden
2: Innere Klassen und Anonyme Innere Klassen
new BspClass() {
public function __construct() {
}
}
3: Type Hints für primitive Datentypen
Oliver
13 Dez 10 at 12:09
[…] wenn ich Artikel wie „Was fehlt dir an PHP?“ (hier vom PHP Gangsta) lese und die Kommentare dazu, frag ich mich: Warum nicht gleich Java nehmen? Was spricht gegen […]
Was spricht gegen Java? « Rudi's PHP Labor
13 Dez 10 at 13:03
Ich wünsche mir von PHP vor allem zwei Dinge: Mehr Konsistenz und eine komplett objektorientierte Library.
Danilo
13 Dez 10 at 13:05
Also ich weiß nicht. Die meisten genannten Sachen kann man sich doch gut selbst schreiben. Und statt Kürze ist in einer Sprache wohl eher die Selbstdokumentation wichtig. PHP hat nun nicht die konsistenteste Benamung, aber htmlspecialchars() sagt auf jeden Fall mehr über seine Funktion aus, als esc(). Und wie gesagt – wer das braucht schreibt sich halt nen Wrapper. Zum erstgenannten Punkt genauso:
function ifset (& $var) {
return (isset($var ? $var : null));
}
nikosch
13 Dez 10 at 13:07
PS: Mein Wunsch: Umstellung (meinetwegen konfigurierbar) aller Funktionen, die bisher Errors erzeugen, auf Exceptions.
nikosch
13 Dez 10 at 13:11
Ich schließe mich David Müller an. genau das habe ich auch schon oft gebraucht. Außerdem würde ich mir wünschen Funktionen und Methoden wie in C/C++ überladen zu können.
Michael
13 Dez 10 at 13:15
Die strikte Typisierung von skalaren Methoden/Funktions-Parametern ist schön und gut, aber solange es keine generelle PHP-Extension dafür gibt, ist sie nur Overhead, da die Typisierung im PHP-Code überprüft werden müsste. Sebastian Bergmann hat dazu was in seinem Blog geschrieben: http://sebastian-bergmann.de/archives/900-Scalar-Type-Hints-in-PHP-5.3.99.html
Bzgl. des Array Dereferencing kann ich mich an eine Diskussion ereinnern, bei der gemeint wurde, dass das eher zu unschönen/ineffizienten Code führen wird:
echo $obj->getPerson()[„first_name“] . “ “ . $obj->getPerson()[„last_name“];
Das ist mit Objekten ebenso möglich und da besteht das gleiche „Problem“, denn es führt dazu, dass getPerson() doppelt bzw. mehrfach ausgeführt wird, was nicht sehr effizient und schön ist.
@Georges Jentgen: Ein „Zwang“ von typensicherer Variablen wird es wohl nie kommen, da das ein zu herber Eingriff in bestehende Anwendungen wäre. Man könnte nicht mehr Upgraden ohne die eigene Anwendung umbauen zu müssen. Eine Möglichkeit wäre da, die Typisierung optional zu machen, also dass man die z.B. per INI-Konfiguration aktiviert, dann aber wirklich für den kompletten Code gilt.
@David Müller: Das Überladen von Methoden klappt nur, wenn PHP deren Signaturen eindeutig kennt, das kann es aber nur, wenn alle Parameter strikt typisiert sind und das wird so schnell nicht kommen. Ich weiß auch nicht, in wiefern die Pseudo-Typisierung in PHP 5.4 das könnte.
@nikosch: Ich hoffe, ich habe deinen Kommentar richtig verstanden, aber dass man bei PHP von Warnings etc. auf Exceptions umstellt ist wohl eher unwahrscheinlich, da so der Ablauf innerhalb der Anwendung komplett anders gehandelt werden müsste. Wo bisher nur eine Warning kommt, die die Anwendung nicht stört, würde nun eine Exception geworfen werden, die du explit fangen und behandeln musst.
Arvid Bergelmir
13 Dez 10 at 14:01
Die ErrorException kann da auch Abhilfe schaffen: http://www.d-mueller.de/blog/php-errors-zu-exceptions-konvertieren/
David Müller
13 Dez 10 at 14:28
@Danilo: Zu Punkt 2: Das habe ich die Tage mal in Java gesehen, dass das dort möglich ist, aber irgendwie habe ich den Sinn dahinter noch nicht ganz verstanden. Zwar ist es grob nichts anderes als die Lambda-Funktionen, aber Klassen möchte ich zentral für die generelle Nutzung zur Verfügung stellen und nicht immer direkt eine Instanz davon erzeugen.
Arvid Bergelmir
13 Dez 10 at 14:36
@Arvid: Was ich meine ist eher etwas in Richtung Python, wo praktisch alles aus Objekten besteht. Was aber schwierig umzusetzen ist, da PHP im Gegensatz zu Python nicht so schön modular aufgebaut ist (Stichwort Namespace). Aber ein gutes Beispiel für mehr Objektorientierung ist mysqli – solche objektorientierten Alternativen sollten überall bereitgestellt werden wo es Sinn macht.
Mit Objektorientierung habe ich allerdings auch gemeint, dass bei Fehler Exceptions (Objekte) geworfen werden, anstatt normalen Errors, wie es von Nikosch schon erwähnt wurde.
Danilo
13 Dez 10 at 14:44
Ich würde mir wünschen, dass ich selber bestimmen kann (php.ini) welches Zeichen Namespaces voneinander abtrennt. Der Backslash ist sehr umständlich! Zudem würde ich mich über ein bisschen mehr standardmäßige Objekte freuen, also eine Zusammenfassung/Erweiterung/etc. einiger Funktionen. Aber ich finde PHP auch so Klasse, auch ohne diese Wünsche, aber man sollte sich schließlich nie zufrieden geben mit dem was man hat.
Paloran
13 Dez 10 at 17:20
@nikosch:
Danke für deinen Beitrag. Die von dir geschriebene ifset Funktion, hat allerdings einen kleinen Fehler. Ich denke du meintest es so:
function ifset (&$var) {
return (isset($var) ? $var : null);
}
Meiner Meinung nach ist dies aber so nicht unbedingt ausreichend (wie auch bereits oben im Artikel schon kurz angedeutet). Folgender Aufruf würde beispielsweise zu einer Warning führen:
$obj = new stdClass();
$obj->foo = ‚123‘;
ifset($obj->foo->bar);
Das Problem ist klar: ‚Attempt to modify property of non-object in …‘. Da der Funktionsaufruf den Parameter $var byRef enthält, wird eine Manipulation der Variable „vermutet“, die eben mit dieser Warning beantwortet wird.
Die Funktion isset() würde sich auf dieses Konstrukt allerdings ohne Warning anwenden lassen! Sollte das womöglich dann für eine Funktion ifset nicht ebenfalls so gelten? Ich kann mir zumindest Anwendungsgebiete vorstellen, in denen soetwas vorkommen kann (auch bei anderen Fällen gibt es ähnliche „Probleme“). Mit der von dir präsentierten Lösung, wäre der Aufruf also nicht ohne Warning möglich, da schon der Funktionsaufruf selber die Warning enthält und man somit gar keine eigene Funktion schreiben kann, die besagtes Problem vollständig löst.
Wiederum lasse ich mich aber gerne eines besseren belehren 😉
Tim | not-null.de
13 Dez 10 at 17:28
@Tim: Da gehst du aber einen Schritt weiter. Ich würde niemals auf die Idee kommen, isset() auf syntaktisch unsinnige Dinge wie $foo->bar wenn $foo ein skalarer Wert ist anzuwenden… bin gerade echt erstaunt dass das überhaupt möglich ist.
Mich würde mal interessieren, in was für einem Anwendungsfall das wirklich nötig ist, das wirkt sehr unsauber auf mich.
Fabian
13 Dez 10 at 19:20
was mir gerade eben noch einfiel, eine einheitliche Benennung der Standardfunktionen (evtl. mit Namespaces) würde mich sehr erfreuen!
Paloran
13 Dez 10 at 20:04
@Tim: Ja, dein Einwand ist richtig. Wenn müsste das ein „Konstrukt“ und keine Funktion sein (also wie empty(), isset() etc.) sonst hat man trotzdem die blöden Fehler-Meldungen.
Super fände ich auch noch noch ein filled()-Konstrukt als Gegenstück für empty(). Denn das oft verwendete ! empty() mit seiner doppelten Verneinung kommt dem menschlichen Gehirn absolut nicht entgegen.
Florian Heinze
13 Dez 10 at 20:07
@Fabian: Der Aufruf von $foo->bar, bei dem $foo ein skalarer Wert ist, ist noch nicht einmal mehr so unwahrscheinlich, denn in der PHP Internals Mailingliste wird aktuell über das Autoboxing (http://wiki.php.net/rfc/autoboxing) diskutiert. Dabei werden skalare Werte magisch in Objekte umgewandelt, sobald man auf ihnen Methoden o.ä. aufruft.
Arvid Bergelmir
14 Dez 10 at 08:02
– Type Hints für Skalare (meinetwegen über INI, aber dann mit Exceptions)
– Überladen von Methoden
– Rückgabewert in der Methodendeklaration
– bessere DOM-Unterstützung (erinner mich da an großes Gewürge mit UTF-8)
– needle/haystack – Reihenfolge !!! (Da muss ich jedes mal in den Code Hint kucken)
Wenn das alles realisiert ist, kann man dann auch über eine strikte Typisierung sprechen, a la:
int $x = 10;
RennerChristian
14 Dez 10 at 09:53
@Fabian:
Syntaktisch unsinnig/fehlerhaft ist das wohl eher nicht. Immerhin kann das Konstrukt ja erst einmal vorkommen, wenn bar wiederum ein Objekt ist.
Von der Logik her muss ein solcher Fall natürlich erstmal irgendwo vorkommen, was wohl nicht oft passieren dürfte. Aber im grunde denke ich schon, dass soetwas passieren kann und dann auch korrekt behandelt werden sollte. Dass es unsauber sein dürfte, brauchen wir hier ja nicht zu disktuieren. Dennoch ist eine solche Funktion eben kein Sprachkonstrukt und wird somit auch nicht in allen Fällen das korrekte Ergebnis liefern oder Warnings / Errors generieren. Um eine solche Funktion korrekt in allen Fällen nutzen zu können, ist also ein Sprachkonstrukr nötig, finde ich.
Tim | not-null.de
14 Dez 10 at 10:19
@tim
Das Überladen von Methoden funktioniert doch über die optionalen Parameter.
In Deinem Fall müsste dann dann etwa so aussehen:
__constuct([mixed] xOrPoint, [int] y = null)
und dann im Konstruktor entsprechend unterscheiden.
Mir wäre spontan keine Programmiersprache bekannt, die sowohl Methodenüberladung, als auch optionale Parameter erlaubt.
Für eine schwach typisierte Sprache wie PHP ist Dein Wunsch ohnehin problematisch umzusetzen, nehme ich an.
Kim
14 Dez 10 at 16:19
@Oliver
Typehints kannst Du mit der SPL bewerkstelligen. Da gibt es SPL-Integer, -Doubles usw. Allerdings wird es schwierig, dies nachträglich einem Projekt anzueignen. Für neue zu schaffende Projekte ist es aber eine Option. Ich persönlich würde damit aber nicht oder nur in gut isolierten Codeteilen arbeiten wollen.
Kim
14 Dez 10 at 16:23
@Kim
In C++ wäre das möglich:
void SetVar(int*);
void SetVar(int*, char*, int number=1);
Allerdings gibt es auch hier die Einschränkung, dass sich die Methode in einem Parameter vor dem Default-Parameter unterscheiden müssen. Folgendes würde also nicht gehen:
void SetVar(int*, int number=1);
Michael
14 Dez 10 at 16:27
@Oliver:
Aber die SplInt-Objekte etc. sind bisher noch Zukunftsmusik?
http://de.php.net/manual/en/intro.spl-types.php
Als Typehints würden sie ja aber erst wirklich Sinn ergeben, wenn z.B. ein skalarer Int automatisch gecastet oder zumindest erkannt werden würde (also evtl. das oben genannte Autoboxing, @Arvid)?
Florian Heinze
14 Dez 10 at 19:39
@Kim:
Natürlich lässt sich das Ganze mit den optionalen Parametern bewerkstelligen, keine Frage. Ein „sauberes“ Überladen wäre mir oft allerdings trotzdem lieber. Immerhin muss ich so in Methoden immer auf sämtliche Fälle prüfen, anstatt mehrere Methoden schreiben zu können, die jeweils exakt nur das machen, wofür sie ausgelegt sind. Die Beispielmethode von dir ist da ja noch relativ einfach, aber bei komplizierteren Konstrukten wird das ganze sehr schnell fehleranfällig und unübersichtlich.
Zudem ließen sich innerhalb der IDE oder im PHPDoc die verschiedenen Methodenaufrufe besser darstellen lassen. Das stört mich oft schon ziemlich.
Dass die schwache Typisierung hier ein grundlegendes Problem ist, ist klar. Deshalb war einer meiner weiteren Wünsche ja auch, dass zumindest ein (optionales) Typehinting eingeführt werden sollte. Eine Überladung würde ich dann nur da gestatten, wo die Typisierung korrekt angewendet wurde. Dann würde dies wiederum kein Problem machen und ältere PHP-Scripte (ohne Typehinting) würden auch weiterhin funktionieren.
Tim | not-null.de
15 Dez 10 at 11:14
Puh, langsam wird das Threading hier unübersichtlich.
@Arvid Bergelmir:
– Falsche Klammer, richtig erkannt, danke.
– Bei Warnings macht das natürlich keinen Sinn, aber Fatale Fehler sind schon wirklich ärgerlich, wenn sie nicht einmal einen zentralen Abbruch der Anwendung erlauben. Was auch die Antwort auf den Vorschlag „PHP-Errors zu Exceptions konvertieren“ wäre.
@Tim
Also ifset($obj->foo->bar); würde ich wohl so nie verwenden. Zugegeben, man trifft auf Situationen, wo mal ein Objekt nicht gesetzt ist, aber so eine Syntax enthält mir persönlich etwas zu viel FooBar-Magie.
nikosch
15 Dez 10 at 16:34
Seit PHP 5.3 ist der ternäre Operator doch erweitert worden.
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.
Bedeutet doch Quasi, dass dieser Schnipsel genau das macht?
$var = $foo ?: null;
Oder versteh ich da was falsch?
denkweite
16 Dez 10 at 15:01
@denkweite: Wenn es $foo nicht gibt, wird zwar $var auf null gesetzt, aber es gibt auch ein Warning, das soll verhindert werden. Deshalb eigentlich der Einsatz von isset(). Dann geht aber der ternäre Operator nicht mehr.
Michael Kliewe
16 Dez 10 at 17:45
Obwohl es eigentlich logisch wäre, funktioniert folgendes nicht (self::x beinhaltet einen String [Name einer Klasse]):
{self::x}::y
Außerdem Stichwort TypeHinting:
function x/**Macht…*/(
string|array $y/**Nützt …*/,
[$z/**Benötigt…*/],
validator_callback($a/**Ist …*/)
) {
try{
[IRGENEIN CODE]
return array|string $a /** Gibt … zurück */
} catch(Exception $e) {
[FEHLER]
}
}
Soll bewirken:
– $y kann string oder array sein.
– Wenn der Funktion nur zwei Argumente übergeben werden, werden diese in den Parametern $y und $a gespeichert und $z wird nicht null, sondern bleibt unbefüllt.
– validator_callback() gibt den (modifizierten) Wert von $a zurück. Bei unmöglichem Parameterinhalt wirft a validator_callback() eine Exception (für das Abfangen müsste man sich noch etwas nettes überlegen). Auch Lambda ist selbstverständlich erlaubt. Dadurch kann eine stärkere Trennung zwischen Parameterüberprüfung, die nicht mit dem aktuellen TypeHinting-Konzept möglich ist, und dem wirklichen Funktionsinhalt möglich. Bei return ist das Ganze ja auch möglich:
return callback($a);
Warum muss ich dann bei Parametern folgenden Umweg gehen? Das ist ja auch für Documentationen etc. leichter nachzuverfolgen:
$a = validator_callback($a);
– Für Dokumentationen (PHP müsste nicht umgeschrieben werden – die Beispiele auf div. Seiten jedoch abgeändert): In Moment wird häufig PHPDoc verwendet. Hierbei muss ich jedoch Funktionsname, Variablenname etc. immer doppelt genannt werden. Somit wäre es ja nett, die Dokumentation gleich inline in den Funktionskopf zu coden. Wie bei PHODoc soll /** (zwei Sterne!) die Dokumentation von einem einfachen Kommentar abgrenzen.
– Mit array|string sollten andere Kompontente (über Reflection) bzw. Dokumentationssoftware auf den Rückgabewerttyp schließen können. Im Fehlerfall (falscher Typ) sollte ein auf diese Fehlerart spezialisiertes Exceptionkind geworfen werden. Natürlich wäre auch weglassen (kein bestimmter Typ, „mixed“, somit auch mit jetztigem PHP kompatibel) möglich.
Mit allemdem wäre eine einfache, in die Funktion eingegliederte Dokumentation und eine klare Trennung zwischen Parameter(validierung), Code, Rückgabe(validierung) und Fehlerverarbeitung möglich.
Mehrere Stringoperationen werden oft sehr schlecht lesbar:
print(md5(nl2br(htmlspecialchars()), true))
Klar: zwischenspeichern in Variablen, aber das trifft nicht den Kern der Sache und sieht ja auch nicht besonders schön aus, den Variablennamen unendlich oft schreiben zu müssen:
$x = irgendetwas1(„xyz“, $a);
$x = irgendetwas2($x);
$x = irgendetwas8($x, $y);
$x = irgendetwas3($x);
$x = irgendetwas5($x, true);
$x = irgendetwas4($x, IRG4_ORDER | IRG4_CAPTURE);
Ich JavaScript gibt es eine himmlische Lösung dafür – in PHP würde das so aussehen:
$x = „xyz“->irgendetwas1($a)->irgendetwas2()->…->…->…;
Also:
Wird dem „->“-Operator als 1 Operand ein String bzw. eine stringbeinhaltende Variable übergeben, soll der String automatisch in eine äquivalente Objektalrepräsentation umgewandelt werden. Dieses „Stringobjekt“ sollte die Funktionen aus http://at2.php.net/manual/de/ref.strings.php als Methoden haben, nur die Subjektparameter sollten in den Methodendeklarationen weggelassen werden, dieser Wert wird ja aus $this gewonnen. Ähnliches wäre auch für andere Typen denkbar.
fridojet
19 Dez 10 at 11:47
@Michael Kliewe: Spräche etwas gegen (Unterschiede zu $x=isset($y)?$y:null gäbe es nur bei Objekten mit [G/S]ettern, oder? – aber [G/S]etterobjekte werden ja nicht dein [Haupt]einsatzgebiet sein):
$x = @$y;
Eben wegen dem (G/S)etterproblem wäre ich dafür, bei künfigen Versionen folgendes zu erlauben – ähnliches ist sogar in der „Kriechtiersprache“ SQL möglich:
$x = ? $y : null;
Wie das weglassen vom 2. Teil möglich ist, so auch beim 1. Teil: Er sollte ergänzt werden auf:
$x = isset($y) ? $y : null;
Vielleicht sollte man auch das weglassen des 3. Teils erlauben, da ja im 3. Teil eh meistens null steht:
$x = ? $y :;
Sollte ergänzt werden zu:
$x = isset($y) ? $y : null;
Intressant würde es dann noch mit dem „@“- und „<<="-Operator (macht zwar keinen Sinn, aber sieht äußert gestört [PERL-artig ;-)] aus und wäre dann sogar PHPToken-kompilierbar):
$x<<=?@$y:;
lg.
fridojet
19 Dez 10 at 12:16
$x<<=?@$y:; wäre dann noch durch $x<<=?@$y:|x; zu toppen.
fridojet
19 Dez 10 at 12:19
@nikosch und alle anderen die lieber Exceptions statt Fehlermeldungen wünschen: das kann man mit „set_error_handler“ erreichen.
Hier mehr dazu: http://phplabor.wordpress.com/2010/12/23/in-php-nur-noch-exceptions-statt-fehlermeldungen/
Rudi
23 Dez 10 at 08:28
Eine weitere interessante Diskussion über wünschenswerte Features in PHP (vom 17. Dezember):
http://programmers.stackexchange.com/questions/27564/what-features-would-you-like-to-have-in-php
Michael Kliewe
2 Jan 11 at 00:53
Da ich heute ein Problem mit der Arraynotation hatte, musste ich wieder an den einen Kommentar hier denken. Ich bin definitiv auch für eine Notation in der Form:
[„foo“ => „bar“, „omnomnom“]
oder
[„foo“: „bar“, „omnomnom“]
1. Schneller getippt.
2. Lesbarer, besonders bei mehrdimensionalen Arrays…
@Michael Natürlich funktioniert der ternäre Operator mit isset:
$var = isset($foo) ?: null; //hier bin ich mir nicht ganz sicher, könnte sein dass klammern nötig sind
$var = (isset($foo) && $foo) ?: null;
😉
Z4ppy
30 Mrz 11 at 19:13
@Z4ppy:
Ja das ternäre Konstrukt sollte funktionieren, aber es schreibt nicht das in $var was man meistens möchte:
Denn so hat man in $var im ende einen boolean mit dem wert „true“ oder ein NULL. Ich hätte aber gerne das der Wert $foo im Ende in $var landet 😉
Florian Heinze
30 Mrz 11 at 19:33
Stimmt, das geht nicht :S
Z4ppy
30 Mrz 11 at 21:24
Spricht eigentlich irgendetwas gegen optionale type-hints für nicht-skalare Klassenvariablen?
Das wäre hilfreich als Doku und für die IDEs, die dann sofort die richtigen Methoden vorschlagen können.
Dr Ix
20 Mai 11 at 14:30
Habe inzwischen eine Lösung für eine Userland Funktion für das ifset-Problem gefunden:
function ifset(&$value)
{
if(isset($value)) return $value;
}
ifset($_REQUEST[‚foo‘]);
ifset($foo);
ifset($bar[‚foo‘]);
Alle Variablen sind nicht gesetzt und es kommt, dank der Übergabe per Referenz (&), zu keinen Notices. Diese verhalten, das Referenzen diese Notices unterdrücken, war mir bisher nicht bekannt.
Details dazu von mir: http://php-consulting.de/blog/2011/ifset-oder-ifsetor-ohne-notice-fehlermeldung
Florian Heinze
27 Sep 11 at 11:28