PHP8 array deklariert null im construct

LukaszRT

Grünschnabel
Kann mir bitte jemand etwas erklären. Ärgere mich mal wieder an den PHP8 verärger(neuer)ungen.

Folgendes Beispiel liegt an:
PHP 8.1.7

PHP:
class clientonline
{
    public $my_ip;
    .....
    public $not_protokoll_ip = array();
    ...
 
    function __construct($not_protokoll_ip = array(),$overwrite_ip='',$overwrite_uid = '',$overwrite_nick='')
    {
        $this->not_protokoll_ip = $not_protokoll_ip;
        var_dump($this->not_protokoll_ip);
.......
    }
}

VARDUMP LIEFERT: NULL???? ARRAY deklariert.

PHP7 gehts PHP8
Uncaught TypeError: in_array(): Argument #2 ($haystack) must be of type array, null given in

ja ne, also array ist given in! Steh auf dem Schlauch?

Überhaupt liefert jedes deklarierte Array null, sofern keine key vorhanden ist.
 
Zuletzt bearbeitet:

Yaslaw

alter Rempler
Moderator
In dem Fall wäre es spannend zu sehen, was du dem Konstruktor von aussen überegibst. Wenn dort null kommt, ist es egal was du in der Klasse hast, da $not_protokoll_ip dann auf nul gesetzt wird
PHP:
$obj = new clientonline(); //$not_protokoll_ip müsste ein leeren Array sein
$var = null;
$obj = new clientonline($var); //$not_protokoll_ip müsste null sein, da es vom AUfruf überschrieben wird.
Zudem kannst du bei der Deklaration die Initialisierung (=array()) weglassen, da die Variable im construct eh überschrieben wird.

Wenn null als Argument erlaubt ist und dass dann ein nen leeren Array sein soll, dann setz es entsprechend um
PHP:
$this->not_protokoll_ip = is_null($not_protokoll_ip) ? array() : $not_protokoll_ip;
 

LukaszRT

Grünschnabel
In dem Fall wäre es spannend zu sehen, was du dem Konstruktor von aussen überegibst. Wenn dort null kommt, ist es egal was du in der Klasse hast, da $not_protokoll_ip dann auf nul gesetzt wird
Richtig, wenn er ja null übergibt, dann tütet er null ja ein.

Ich würde mich an der Stelle fragen, warum ich das nicht mehr mit @unterdrücken kann in PHP8.

Beispiel:

PHP:
if(@in_array(...,....))
{
....do....
}
TypeError: in_array(): Argument #2 ($haystack) must be of type array, null given in

das @müsste doch das ganze unterdrücken.
 
Zuletzt bearbeitet:

LukaszRT

Grünschnabel
Klar ist die @Methode allgemein keine saubere Lösung, stimme Dir vollkommen zu. Und dennoch ist das @ ja genau dafür gedacht und nützlich wenn überhaupt nur ein bestimmtes Ergebnis optional erwartet wird. Und nein in PHP8 wird bei mir das @ignoriert.

(Sei es mal darum, dass es an irgend welchen Einstellungen liegen könnte, keine Ahnung!)

if(@in_array(...,....))
{
....do....
}
RESULT: TypeError: in_array(): Argument #2 ($haystack) must be of type array, null given in

Weiteres Problem dass es ein Fatal Error ist. Das ärgert mich ja gewaltig. Da ich ja das @ genau dort absichtlich setze wo ich quasi einen TRY haben will und es nicht wichtig ist. Hier bricht PHP8 das Skript dann einfach ab. Und somit habe ich ein anderes Ergebnis als ich befohlen haben. Das ist echt traurig.

Prinzipiell nervt das nur und nützt keinem. Wenn ich zum Beispiel ein @ setze dann weis ich dass mir der Resultat ja völlig Banane ist. z.B.

@file_put_contents();

Hier setze ich das @da es mir ja vollkommen egal ist, ob die Datei gesetzt wird oder nicht. Ich kann es ja im Anschluss prüfen mit file_exsits. Deshalb ist das @in manchen Fällen wichtig. Man will ja nicht unbedingt deshalb den Ablauf eines Skriptes stoppen, nur weil ein unerwartetes Ergebnis eintrifft.

Wie es aussieht juckt das PHP8 nicht. Find ich einfach ärgerlich. Das ist keine Weiterentwicklung in meinen Augen sondern eine Ableitung von PHP7.

Prinzipiell macht es das Ganze nur aufwändiger. Wenn ich ein String mittels explode in ein array wandel, aber kein delimiter vorhanden ist, und dann prüfe ob ein value im array da ist, kann ich bislang ein @ vorstellen weil das Result ja das selbe ist. Entweder ist der explode ein array und das element vorhanden = true oder nicht vorhanden = false.
Ist der explode ein string da kein delimiter vorhanden dann juckt mich das ja nicht das soweiso ein false kommen müsste wegen des @ Zeichens. Es wird ja quasi versucht die Funktion auszuführen. Und hier haben wir dann doch einen logischen sauberen sinn. Glückt die Funktion nicht, dann ist mein Value ja sowieso nicht vorhanden. Dann muss ich ja auch nicht nach einem value suchen. Das Resultat ist ja das gleiche und bedeutet mein Value ist nicht im Array. Was interessiert mich dann ob die Variable ein Array ist? Das will ich doch gar nicht wissen.

Und as dieser Sicht ist das @ Zeichen schon eine saubere Lösung, da es ja nur etwas versucht durchzuführen, und mit der Erfolg im Code nicht von belangen ist. Letzt endlich möchte ich ja mit dem @ ein Abbruch verhindern. Das ist ja genau die Absicht dahinter. Klar gibt es dafür auch noch andere Wege aber jeder dieser ist ein vielfaches aufwendiger als das @

Folglich müsste das @Symbol nichts anderes wie ein TRY ohne Catch sein.

Auch ein anderes Beispiel zeigt warum das @nützlich ist.

PHP:
$datensatz = @file_get_contents('test.txt');
file_put_contents('test.txt',$datensatz .= ' weiterer Text');

Ich könnte natürlich sagen, ich prüfe erst einmal ob test.txt existiert. Wenn nicht lege ich die an. Aber wozu? PHP schmückt sich doch selbst damit, dass man Variablen Typen nicht deklarieren muss. Also was interessiert mich als Programmierer, die if Abfrage, wenn die Datei doch sowieso nur erweitert und geschrieben wird wie in diesem Fall? Wenn doch test.txt nicht da ist, wird der Daten Satz später doch sowieso zum String gewandelt. Ich spare eine ganze if Abfrage.

Ich kann das natürlich auch in ein TRY setzen. Aber Tatsache ist, dass es für mich in diesem Beispiel überhaupt nicht von belangen ist, ob test.txt nur vorhanden ist oder nicht. Denn wenn nicht, lege ich die so oder so an. Und selbst wenn, überschreibt file_put_contents diese ja sowieso. Und es ist genau so wenig von Belangen ob $datensatz nun Schriftinhalt hat oder nicht. Deswegen wieso soll es eine saubere Lösung sein, hier zu fragen ob test.txt vorhanden ist? Es spielt ja für die Ausführung kein Belangen. Wenn nicht lege die an und erweiterte den String egal ob zuvor ein empty drin ist oder nicht. Nichts anderes sagt der Code. Ob die Datei vorhanden ist interessiert mich ja nicht. Also warum soll man das fragen?

Und deshalb zeigt es warum das @ja sehr wohl aber auch eine saubere Lösung sein kann. Und sie ist für mich auch kein Code smell, da es ja die Lesbarkeit steigert. (Weniger Zeilen). Manche benutzen ja auch

? und : statt if und else

und das @ ist nicht anderes als ein try ohne catch

PHP:
$datensatz = @file_get_contents('test.txt');
file_put_contents('test.txt',$datensatz .= ' weiterer Text');
So jetzt kann ich es interpretieren. Der Code sagt erstelle eine Variable namens Daten Satz. Wenn die Datei existiert fülle diese Variable mit dem Inhalt der Datei. Schreibe die Datei mit Variable und hänge etwas Text an.

Würden wir das @ weg nehmen, dann könnte PHP melden, dass die test.txt nicht vorhanden ist, und sogar falls dies ein fatal error sei, das Skript abbrechen an dieser Stelle, obwohl das für mich keine Rolle spielt. Aus dieser Sicht ist das @ sogar überlebensnotwendig. Da der Trhwon der hier geworfen wird, überhaupt kein Problem darstellt. Generell kann man sagen das @ist nützlich wenn die Erwartung optional ist. In diesem Fall ist die Erwartung aus der text.txt optional.
 
Zuletzt bearbeitet:

basti1012

Erfahrenes Mitglied
Dein Beispiel mit get und put_contenst ist etwas doof.
Ich bin kein PHP Profi , doch wie ich weiß wird die Datei erstellt, wenn es sie nicht gibt.
Gibt es sie doch nutzt man FILE_APPEND
PHP:
file_put_contents('test.txt', ' weiterer Text', FILE_APPEND);
ganz ohne @
Ihr dürft mich gerne korrigieren wenn ich falsch liege.
Und was du da vorgeschrieben hast muss ich mir erst genaue anschauen , es wird bestimmt auch ohne @ gehen.
Mit PHP 8 habe ich mich auch noch gar nicht auseinandergesetzt , werde ich mir jetzt mal anschauen, was es da neues gibt und was rausgeflogen ist
 

Yaslaw

alter Rempler
Moderator
PHP: Operator zur Fehlerkontrolle - Manual
Warnung
Vor PHP 8.0.0 war es möglich, kritische Fehler, die die Skriptausführung beenden, mit dem @-Operator zu deaktivieren. Wenn zum Beispiel @ dem Aufruf einer Funktion vorangestellt wird, die nicht existiert, weil sie nicht verfügbar ist oder falsch eingegeben wurde, würde das Skript ohne Hinweis auf die Ursache abbrechen.

Ich stimme meinen Vorredner zu. Das @ sollte nicht verwendet werden. Und nein, man kann problemlos ohne @ programmieren. Ic h habe es in all meinen Progrmmierungen nie verwendet, weil es einfach unsauber ist. Nach einem @ ist nicht mehr klar, was das Program macht, da unplanmässig einfach Variablen nicht gefüllt, Dateien nicht vorhanden sind etc.
Wenn du sauber mit try and catch arbeiten willst, dann verwende das auch. Fehler sauber abfangen. Dann weiss man im Folgecode auch, was daherkommt.
PHP: Exceptions (Ausnahmen) - Manual
 

Neue Beiträge