438

I see this error only after upgrading my PHP environment to PHP 5.4 and beyond. The error points to this line of code:

Error:

Creating default object from empty value

Code:

$res->success = false;

Do I first need to declare my $res object?

3
  • 12
    How/Where are you initiating $res ?
    – Naveed
    Commented Jan 17, 2012 at 19:45
  • 1
    @NAVEED There.
    – 7heo.tk
    Commented Jul 8, 2016 at 10:00
  • I had this but it was because the visibility of the property on my parent object was private. Commented Nov 1, 2022 at 15:29

18 Answers 18

752

Your new environment may have E_STRICT warnings enabled in error_reporting for PHP versions <= 5.3.x, or simply have error_reporting set to at least E_WARNING with PHP versions >= 5.4. That error is triggered when $res is NULL or not yet initialized:

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

PHP will report a different error message if $res is already initialized to some value but is not an object:

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

In order to comply with E_STRICT standards prior to PHP 5.4, or the normal E_WARNING error level in PHP >= 5.4, assuming you are trying to create a generic object and assign the property success, you need to declare $res as an object of stdClass in the global namespace:

$res = new \stdClass();
$res->success = false;
15
  • 48
    You shoud check whether the object already exists: if (!isset($res)) $res = new stdClass();. Otherwise, this code is not an equivalent replacement for the "old PHP" implicit object creation.
    – Tomas
    Commented Nov 23, 2013 at 15:44
  • 6
    @Tomas Do we need to do this again? The mods cleaned up the comment thread last time because it added little of value. There is no "old PHP" implicit object creation. It was always an error and always issued a warning, just that it was changed from E_STRICT to E_WARNING in 5.4, so some people never encountered it not having paid attention to E_STRICT. Commented Nov 23, 2013 at 15:51
  • 5
    @PeterAlfvin it was not defined in that one particular run! But in different run, at the exact same place in the code, the object might be already defined! This is mistake in thinking people often make and that's the reason I try to emphasize that.
    – Tomas
    Commented Nov 23, 2013 at 16:10
  • 2
    Michael, the implicit object creation always was and is still present even in 5.4. And BTW In PHP < 5.3 it was neither E_STRICT nor E_WARNING. And BTW, mods have restored the comment and I was told to tone it down, that's why I re-posted it.
    – Tomas
    Commented Nov 23, 2013 at 16:13
  • 3
    @tomas Oh, ok, I think I get what you mean. It seems odd that you/Michael can't get to closure on this. BTW, this exchange has led me to realize that italics<bold<allcaps in terms of "strength" and that while allcaps=shouting and italics=politeEmphasis, bold is in a middle ground where the acceptability is questionable. :-) Commented Nov 23, 2013 at 16:19
68

This message has been E_STRICT for PHP <= 5.3. Since PHP 5.4, it was unluckilly changed to E_WARNING. Since E_WARNING messages are useful, you don't want to disable them completely.

To get rid of this warning, you must use this code:

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

$res->success = false;

This is fully equivalent replacement. It assures exactly the same thing which PHP is silently doing - unfortunatelly with warning now - implicit object creation. You should always check if the object already exists, unless you are absolutely sure that it doesn't. The code provided by Michael is no good in general, because in some contexts the object might sometimes be already defined at the same place in code, depending on circumstances.

2
  • 2
    @carlosvini, This will give you Undefined variable: res.
    – Pacerier
    Commented Jan 26, 2015 at 12:49
  • 1
    @Pacerier You are right, the best you can do is: $res = isset($res) ? $res : new stdClass(); -- which was the reason i didn't have E_NOTICE enabled 6 months ago, since it's too damn verbose.
    – carlosvini
    Commented Jan 26, 2015 at 13:48
19

Simply,

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

Or you could instantiate classes with:

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

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

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

and fill values with:

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

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

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

More infos: https://www.php.net/manual/en/language.types.object.php#language.types.object.casting

4
  • 1
    why is new stdClass() considered an "old" method? Are the others somehow better?
    – Aaron
    Commented Mar 25, 2017 at 0:03
  • Its simply from old php version
    – pirs
    Commented Apr 1, 2017 at 0:36
  • in my case $this->route->uri = new stdClass(); is not working for me, I still have the warning. Note : $this->route is existing.
    – Meloman
    Commented Jan 3, 2020 at 7:15
  • Maybe this is not compatible with new versions of php ? Which version you used ?
    – pirs
    Commented Jan 12, 2020 at 10:43
8

If you put "@" character begin of the line then PHP doesn't show any warning/notice for this line. For example:

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

For preventing this warning for this line you must put "@" character begin of the line like this:

@$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

I'm using this trick when developing. I don't like disable all warning messages becouse if you don't handle warnings correctly then they will become a big error in future.

4
  • 3
    @ does prevent warnings by suppressing it, looks ok for as long as you have manageable code. But if your code grows into something bigger and you ran into an issue, you'll somehow regret using this. You'll find yourself looking for all those "@" for a warning you'd want to unhide because temporarily it has served its purpose thinking that you have actually fixed the issue when in reality it has been talking to you and you just wouldn't listen. Commented Jul 29, 2017 at 8:59
  • I know already. This is short and fast answer. There are lots of solution for this. Commented Jul 29, 2017 at 10:48
  • 3
    awesome! May I politely beg to disagree though, hiding the error is not really fixing the problem (as what Ramy Nasr commented as well). Commented Jul 29, 2017 at 11:16
  • This workaround is the only workin for me on php 7.2.
    – Meloman
    Commented Jan 3, 2020 at 7:15
6

Try this if you have array and add objects to it.

$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.
}

This sends ARRAY of Objects for later use~!

1
  • 1
    THANK YOU!!!! This is what helped get the job done. I needed to tell PHP step-by-step what each element was. Thanks for reminding me not to code lazy lol.
    – yanike
    Commented Jun 11, 2020 at 18:59
4

In PHP 7 anonymous objects can be created this way:

$res = new class {
    public $success = false;
};

https://www.php.net/manual/en/language.oop5.anonymous.php http://sandbox.onlinephpfunctions.com/code/ab774707a8219c0f35bdba49cc84228b580b52ee

3

Starting from PHP 7 you can use a null coalescing operator to create a object when the variable is null.

$res = $res ?? new \stdClass();
$res->success = false;
2
  1. First think you should create object $res = new \stdClass();

  2. then assign object with key and value $res->success = false;

1
  • (I don't understand thay.) Where you want a line break after some contents, append two blank spaces to the visible contents of the line before the break-to-be.
    – greybeard
    Commented Apr 28, 2020 at 9:20
1

Try this:

ini_set('error_reporting', E_STRICT);
5
  • 1
    Thanks. this is use full when you are using third-party libraries such as nusoap and don't want / can't change the source. In that case you can change error_reporting to E_STRICT level just before requiring other source files.
    – mtoloo
    Commented Dec 23, 2013 at 16:20
  • Although I just added this to the top of nusoap to fix my problem.
    – badweasel
    Commented Aug 19, 2014 at 20:25
  • 11
    Huh? The code here disables all error reporting except E_STRICT errors, including suppressing messages for fatal errors. That's not a reasonable suggestion to solve this particular warning, and what's more is something you pretty much never ever want to do. Why 5 people upvoted this, I have no clue.
    – Mark Amery
    Commented Sep 29, 2014 at 23:37
  • 1
    This is super bad! use ini_set('error_reporting', -1); while debugging, but don't use the above, like ever.
    – Kzqai
    Commented Dec 30, 2016 at 21:42
  • Ok, so you fix a problem by hiding this one ? Not sure your code will work as expected...
    – pirs
    Commented Jan 12, 2020 at 10:46
1

I had similar problem and this seem to solve the problem. You just need to initialize the $res object to a class . Suppose here the class name is test.

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

A simple way to get this error is to type (a) below, meaning to type (b)

(a) $this->my->variable

(b) $this->my_variable

Trivial, but very easily overlooked and hard to spot if you are not looking for it.

1
  • 1
    How is this related to the original question? There was no mix-up between _ and ->
    – Nico Haase
    Commented Nov 9, 2018 at 6:41
0

You may need to check if variable declared and has correct type.

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;

See PHP anonymous classes.

0

Try using:

$user = (object) null;
1
  • 2
    Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others.
    – lucascaro
    Commented Nov 9, 2018 at 6:45
0

I had a similar problem while trying to add a variable to an object returned from an API. I was iterating through the data with a foreach loop.

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

This threw the "Creating default object from empty value" Exception in Laravel.

I fixed it with a very small change.

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

By simply making $data a reference.

I hope that helps somebody a it was annoying the hell out of me!

0

This is a warning which I faced in PHP 7, the easy fix to this is by initializing the variable before using it

$myObj=new \stdClass();

Once you have intialized it then you can use it for objects

 $myObj->mesg ="Welcome back - ".$c_user;
-1

no you do not .. it will create it when you add the success value to the object.the default class is inherited if you do not specify one.

2
  • 4
    Though it will return the Strict standards message... it is simply good practise to create the object manually first, and while PHP is relatively tolerant of shoddy coding practise, you shouldn't ignore doing things correctly.
    – Mark Baker
    Commented Jan 17, 2012 at 19:49
  • 4
    understood, i was just answering the question with a simple yes or no, not defining or defending best practices :) Commented Jan 17, 2012 at 19:54
-1

This problem is caused because your are assigning to an instance of object which is not initiated. For eg:

Your case:

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

Solution:

$user = new User;
$user->email = '[email protected]';
4
  • aren't you assuming that the class "User" exists? which it may not and now it'll generate a different error? Commented Nov 6, 2014 at 11:44
  • 1
    Actually i did not created an instance of the User object so i got an error. But after creating an instance. It worked.. its a generic problem with OOPs concept :) Commented Nov 7, 2014 at 4:34
  • 6
    well, actually the real problem is that your example assumes the user class to be defined, this isn't a generic problem of object orientation, its a key requirement ;) Commented Nov 7, 2014 at 8:00
  • 1
    I'd rather put a generic "stdClass" replacing the premise implying "User". Commented Feb 9, 2018 at 14:11
-12

I put the following at the top of the faulting PHP file and the error was no longer display:

error_reporting(E_ERROR | E_PARSE);
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.