Standardobjekt aus leerem Wert in PHP erstellen?

362

Ich sehe diesen Fehler erst nach dem Upgrade meiner PHP-Umgebung auf PHP 5.4 und höher. Der Fehler zeigt auf diese Codezeile:

Error:

Standardobjekt aus leerem Wert erstellen

Code:

$res->success = false;

Muss ich zuerst mein $resObjekt deklarieren ?

Paul
quelle
11
Wie / wo initiierst du $res ?
Naveed
1
@NAVEED Dort .
7heo.tk

Antworten:

627

Ihre neue Umgebung kann E_STRICTWarnungen aktiviert inerror_reporting PHP - Versionen <= 5.3.x oder einfach hat error_reportingauf mindestens E_WARNINGmit PHP - Versionen> = 5.4. Dieser Fehler wird ausgelöst, wenn $resist NULLoder noch nicht initialisiert:

$res = NULL;
$res->success = false; // Warning: Creating default object from empty value

PHP meldet eine andere Fehlermeldung, wenn $reses bereits auf einen bestimmten Wert initialisiert wurde, aber kein Objekt ist:

$res = 33;
$res->success = false; // Warning: Attempt to assign property of non-object

Um zu erfüllen E_STRICTStandards vor PHP 5.4 oder der normalen E_WARNINGFehlerebene in PHP> = 5,4, vorausgesetzt , Sie versuchen , ein generisches Objekt zu erstellen und weisen Sie die Eigenschaft success, müssen Sie erklären , $resals ein Objekt der stdClassim globalen Namespace:

$res = new \stdClass();
$res->success = false;
Michael Berkowski
quelle
38
Sie sollten prüfen, ob das Objekt bereits vorhanden ist : if (!isset($res)) $res = new stdClass();. Andernfalls ist dieser Code kein gleichwertiger Ersatz für die implizite Objekterstellung "altes PHP".
TMS
6
@Tomas Müssen wir das nochmal machen? Die Mods haben den Kommentarthread beim letzten Mal bereinigt, weil er wenig Wert hinzufügte. Es gibt keine implizite Objekterstellung für "altes PHP". Es war immer ein Fehler und gab immer eine Warnung aus, nur dass es in 5.4 von E_STRICT in E_WARNING geändert wurde, so dass einige Leute nie darauf gestoßen sind, ohne auf E_STRICT geachtet zu haben.
Michael Berkowski
4
@ PeterAlfvin es wurde in diesem einen Lauf nicht definiert ! In einem anderen Lauf, genau an der gleichen Stelle im Code , ist das Objekt möglicherweise bereits definiert! Dies ist ein Fehler im Denken, den Menschen oft machen, und das ist der Grund, warum ich versuche, dies zu betonen.
TMS
2
Michael, die implizite Objekterstellung war und ist auch in 5.4 immer vorhanden. Und übrigens In PHP <5.3 war es weder E_STRICT noch E_WARNING. Übrigens, Mods haben den Kommentar wiederhergestellt und mir wurde gesagt, ich solle ihn abschwächen, deshalb habe ich ihn erneut gepostet.
TMS
3
@tomas Oh, ok, ich glaube ich verstehe was du meinst. Es scheint seltsam, dass Sie / Michael diesbezüglich nicht zum Abschluss kommen können. Übrigens hat mich dieser Austausch zu der Erkenntnis geführt, dass kursiv <fett <allcaps in Bezug auf "Stärke" ist und dass fett, während allcaps = schreien und kursiv = höflich ist, fett in einem Mittelweg liegt, in dem die Akzeptanz fraglich ist. :-)
Peter Alfvin
57

Diese Nachricht war E_STRICTfür PHP <= 5.3. Seit PHP 5.4 wurde es unglücklicherweise auf geändert E_WARNING. Da E_WARNINGNachrichten nützlich sind, möchten Sie sie nicht vollständig deaktivieren.

Um diese Warnung zu entfernen, müssen Sie diesen Code verwenden:

if (!isset($res)) 
    $res = new stdClass();

$res->success = false;

Dies ist ein völlig gleichwertiger Ersatz . Es stellt genau das sicher, was PHP stillschweigend tut - leider mit Warnung jetzt - implizite Objekterstellung. Sie sollten immer überprüfen, ob das Objekt bereits vorhanden ist, es sei denn, Sie sind sich absolut sicher, dass dies nicht der Fall ist. Der von Michael bereitgestellte Code ist im Allgemeinen nicht gut, da das Objekt in einigen Kontexten je nach den Umständen manchmal bereits an derselben Stelle im Code definiert ist.

TMS
quelle
2
@ Carlosvini, das wird dir geben Undefined variable: res.
Pacerier
1
@Pacerier Sie haben Recht, das Beste, was Sie tun können, ist: $ res = isset ($ res)? $ res: new stdClass (); - Aus diesem Grund hatte ich E_NOTICE vor 6 Monaten nicht aktiviert, da es zu ausführlich ist.
Carlosvini
13

Einfach,

    $res = (object)array("success"=>false); // $res->success = bool(false);

Oder Sie können Klassen instanziieren mit:

    $res = (object)array(); // object(stdClass) -> recommended

    $res = (object)[];      // object(stdClass) -> works too

    $res = new \stdClass(); // object(stdClass) -> old method

und fülle Werte mit:

    $res->success = !!0;     // bool(false)

    $res->success = false;   // bool(false)

    $res->success = (bool)0; // bool(false)

Weitere Informationen: https://www.php.net/manual/en/language.types.object.php#language.types.object.casting

pirs
quelle
Warum wird new stdClass () als "alte" Methode angesehen? Sind die anderen irgendwie besser?
Aaron
Es ist einfach aus der alten PHP-Version
Pirs
in meinem Fall $this->route->uri = new stdClass();funktioniert nicht für mich, ich habe immer noch die Warnung. Hinweis: $this->routeist vorhanden.
Meloman
Vielleicht ist dies nicht kompatibel mit neuen Versionen von PHP? Welche Version hast du benutzt?
Pirs
6

Wenn Sie den Zeilenanfang "@" in die Zeile setzen, zeigt PHP keine Warnung / Benachrichtigung für diese Zeile an. Zum Beispiel:

$unknownVar[$someStringVariable]->totalcall = 10; // shows a warning message that contains: Creating default object from empty value

Um diese Warnung für diese Zeile zu verhindern, müssen Sie den Zeilenanfang wie folgt in die Zeile einfügen:

@$unknownVar[$someStringVariable]->totalcall += 10; // no problem. created a stdClass object that name is $unknownVar[$someStringVariable] and created a properti that name is totalcall, and it's default value is 0.
$unknownVar[$someStringVariable]->totalcall += 10; // you don't need to @ character anymore.
echo $unknownVar[$someStringVariable]->totalcall; // 20

Ich benutze diesen Trick bei der Entwicklung. Ich mag es nicht, alle Warnmeldungen zu deaktivieren, denn wenn Sie Warnungen nicht richtig behandeln, werden sie in Zukunft zu einem großen Fehler.

Kodmanyagha
quelle
1
@ verhindert Warnungen, indem es unterdrückt wird. Es sieht in Ordnung aus, solange Sie über verwaltbaren Code verfügen. Aber wenn Ihr Code zu etwas Größerem wird und Sie auf ein Problem stoßen, werden Sie es irgendwie bereuen, dies verwendet zu haben. Sie werden nach all den "@" suchen, um eine Warnung zu erhalten, die Sie einblenden möchten, da sie vorübergehend ihren Zweck erfüllt hat und denkt, dass Sie das Problem tatsächlich behoben haben, obwohl es in Wirklichkeit mit Ihnen gesprochen hat und Sie es einfach nicht tun würden. t hör zu.
Vincent Edward Gedaria Binua
Ich weiß schon. Dies ist eine kurze und schnelle Antwort. Dafür gibt es viele Lösungen.
Kodmanyagha
2
genial! Darf ich höflich darum bitten, nicht zuzustimmen, das Verstecken des Fehlers behebt das Problem nicht wirklich (wie auch Ramy Nasr kommentierte).
Vincent Edward Gedaria Binua
Diese Problemumgehung ist die einzige Lösung für mich in PHP 7.2.
Meloman
3

Versuchen Sie dies, wenn Sie ein Array haben und fügen Sie Objekte hinzu.

$product_details = array();

foreach ($products_in_store as $key => $objects) {
  $product_details[$key] = new stdClass(); //the magic
  $product_details[$key]->product_id = $objects->id; 
   //see new object member created on the fly without warning.
}

Dies sendet ARRAY of Objects zur späteren Verwendung ~!

Daniel Adenew
quelle
VIELEN DANK!!!! Dies hat dazu beigetragen, die Arbeit zu erledigen. Ich musste PHP Schritt für Schritt mitteilen, was jedes Element war. Vielen Dank, dass Sie mich daran erinnert haben, Lazy Lol nicht zu codieren.
Yanike
2

Versuche dies:

ini_set('error_reporting', E_STRICT);
Irfan
quelle
1
Vielen Dank. Dies ist voll verwendbar, wenn Sie Bibliotheken von Drittanbietern wie nusoap verwenden und die Quelle nicht ändern möchten / können. In diesem Fall können Sie error_reporting auf E_STRICT ändern, bevor Sie andere Quelldateien benötigen.
Mtoloo
Obwohl ich dies gerade oben in nusoap hinzugefügt habe, um mein Problem zu beheben.
Badweasel
11
Huh? Der Code hier deaktiviert alle Fehlerberichte mit Ausnahme von E_STRICTFehlern, einschließlich der Unterdrückung von Meldungen für schwerwiegende Fehler. Das ist kein vernünftiger Vorschlag, um diese spezielle Warnung zu lösen, und außerdem möchten Sie so gut wie nie etwas tun. Warum 5 Leute dies positiv bewertet haben, weiß ich nicht.
Mark Amery
1
Das ist super schlecht! Verwenden Sie es ini_set('error_reporting', -1);beim Debuggen, aber verwenden Sie es nicht wie immer.
Kzqai
Ok, Sie beheben ein Problem, indem Sie dieses verstecken? Ich
bin
1

Ich hatte ein ähnliches Problem und dies scheint das Problem zu lösen. Sie müssen nur das $ res-Objekt für eine Klasse initialisieren. Angenommen, hier lautet der Klassenname test.

class test
{
   //You can keep the class empty or declare your success variable here
}
$res = new test();
$res->success = false;
Kevin Stephen Biswas
quelle
1

Dies ist eine Warnung, mit der ich in PHP 7 konfrontiert war. Die einfache Lösung besteht darin, die Variable vor der Verwendung zu initialisieren

$myObj=new \stdClass();

Sobald Sie es initialisiert haben, können Sie es für Objekte verwenden

 $myObj->mesg ="Welcome back - ".$c_user;
Ayan Bhattacharjee
quelle
0

Dieses Problem wird verursacht, weil Sie einer Instanz eines Objekts zuweisen, das nicht initiiert wurde. Zum Beispiel:

Dein Fall:

$user->email = '[email protected]';

Lösung:

$user = new User;
$user->email = '[email protected]';
Bastin Robin
quelle
Gehen Sie nicht davon aus, dass die Klasse "Benutzer" existiert? was kann es nicht und jetzt wird es einen anderen Fehler erzeugen?
Christopher Thomas
1
Eigentlich habe ich keine Instanz des User-Objekts erstellt, also habe ich einen Fehler bekommen. Aber nach dem Erstellen einer Instanz. Es hat funktioniert .. es ist ein generisches Problem mit OOPs Konzept :)
Bastin Robin
6
Nun, eigentlich ist das eigentliche Problem, dass Ihr Beispiel davon ausgeht, dass die Benutzerklasse definiert werden soll. Dies ist kein generisches Problem der Objektorientierung, sondern eine wichtige Voraussetzung;)
Christopher Thomas
1
Ich würde lieber eine generische "stdClass" setzen, die die Prämisse ersetzt, die "Benutzer" impliziert.
TechNyquist
0

Eine einfache Möglichkeit, diesen Fehler zu erhalten, besteht darin, (a) unten einzugeben, dh (b) einzugeben.

(ein) $this->my->variable

(b) $this->my_variable

Trivial, aber sehr leicht zu übersehen und schwer zu erkennen, wenn Sie nicht danach suchen.

Tannin
quelle
Wie hängt das mit der ursprünglichen Frage zusammen? Es gab keine Verwechslung zwischen _und->
Nico Haase
0

Möglicherweise müssen Sie überprüfen, ob die Variable deklariert ist und den richtigen Typ hat.

if (!isset($res) || !is_object($res)) {
    $res = new \stdClass();
    // With php7 you also can create an object in several ways.
    // Object that implements some interface.
    $res = new class implements MyInterface {};
    // Object that extends some object.
    $res = new class extends MyClass {};
} 

$res->success = true;

Siehe anonyme PHP-Klassen .

Anton Pelykh
quelle
0

Ich hatte ein ähnliches Problem beim Versuch, einem von einer API zurückgegebenen Objekt eine Variable hinzuzufügen. Ich habe die Daten mit einer foreach-Schleife durchlaufen.

foreach ( $results as $data ) {
    $data->direction = 0;
}

Dies löste die Ausnahme "Standardobjekt aus leerem Wert erstellen" in Laravel aus.

Ich habe es mit einer sehr kleinen Änderung behoben.

foreach ( $results as &$data ) {
    $data->direction = 0;
}

Indem Sie einfach $ data zu einer Referenz machen.

Ich hoffe das hilft jemandem und es hat mich verdammt geärgert!

Andy
quelle
0
  1. Denken Sie zuerst, Sie sollten das Objekt $ res = new \ stdClass () erstellen.

  2. dann Objekt mit Schlüssel und Wert zuweisen, dass $ res-> success = false;

Sukron Ma'mun
quelle
(Ich verstehe nicht thay.) Wenn Sie nach einigen Inhalten einen Zeilenumbruch wünschen, fügen Sie vor dem zukünftigen Zeilenumbruch zwei Leerzeichen an den sichtbaren Inhalt der Zeile an.
Graubart
-1

Nein, das tun Sie nicht. Es wird erstellt, wenn Sie dem Objekt den Erfolgswert hinzufügen. Die Standardklasse wird vererbt, wenn Sie keine angeben.

Silvertiger
quelle
4
Obwohl die Meldung "Strikte Standards" zurückgegeben wird, empfiehlt es sich, das Objekt zuerst manuell zu erstellen. PHP ist zwar relativ tolerant gegenüber schlechten Codierungspraktiken, Sie sollten es jedoch nicht ignorieren, die Dinge richtig zu machen.
Mark Baker
4
Ich habe die Frage nur mit einem einfachen Ja oder Nein beantwortet und keine Best Practices definiert oder verteidigt :)
Silvertiger
-1

Versuchen Sie es mit:

$user = (object) null;
Fischer Tirado
quelle
2
Im Allgemeinen sind Antworten viel hilfreicher, wenn sie eine Erklärung enthalten, was der Code tun soll und warum dies das Problem löst, ohne andere einzuführen.
Lucascaro
-12

Ich habe Folgendes oben in die fehlerhafte PHP-Datei eingefügt und der Fehler wurde nicht mehr angezeigt:

error_reporting(E_ERROR | E_PARSE);
Doug
quelle