Создание объекта по умолчанию из пустого значения в PHP?

279

Я вижу эту ошибку только после обновления моей PHP-среды до PHP 5.4 и выше. Ошибка указывает на эту строку кода:

Ошибка:

Создание объекта по умолчанию из пустого значения

код:

$res->success = false;

Должен ли я сначала объявить объект $res?

  • 10
    Как / Где вы инициируете $res ?
  • 1
    @ NAVEED Там .
Теги:

13 ответов

530
Лучший ответ

В вашей новой среде могут быть E_STRICT предупреждения E_STRICT в error_reporting для версий PHP <= 5.3.x, или просто для error_reporting должно быть установлено значение по крайней мере E_WARNING с версиями PHP> = 5.4. Эта ошибка возникает, когда $res равно NULL или еще не инициализировано:

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

PHP сообщит другое сообщение об ошибке, если $res уже инициализировано каким-либо значением, но не является объектом:

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

Чтобы соответствовать стандартам E_STRICT до PHP 5.4 или нормальному E_WARNING ошибок E_WARNING в PHP> = 5.4, при условии, что вы пытаетесь создать универсальный объект и назначить свойство success, вам необходимо объявить $res как объект stdClass в глобальном пространстве имен:

$res = new \stdClass();
$res->success = false;
  • 0
    @ Томас Конечно, вам может понадобиться проверить, но это не имеет отношения к вопросу. Это о том, как правильно создать экземпляр stdClass . Разработчик обязан убедиться, что существующий объект или скаляр не будут перезаписаны, если переменная уже существует.
  • 31
    Вы должны проверить, существует ли объект уже: if (!isset($res)) $res = new stdClass(); , В противном случае этот код не является эквивалентной заменой неявного создания объекта «старый PHP».
Показать ещё 13 комментариев
40

Это сообщение было E_STRICT для PHP <= 5.3. Начиная с PHP 5.4, это было неоправданно изменено на E_WARNING. Поскольку сообщения E_WARNING полезны, вы не хотите полностью их отключать.

Чтобы избавиться от этого предупреждения, вы должны использовать этот код:

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

$res->success = false;

Это полностью эквивалентная замена. Он обеспечивает точно то же самое, что PHP делает незаметно - к сожалению, с предупреждением теперь - неявное создание объекта. Вы всегда должны проверить, существует ли объект, если вы не уверены, что он этого не делает. Код, предоставленный Майклом, вообще не хорош, поскольку в некоторых контекстах объект иногда может быть определен в одном и том же месте в коде, в зависимости от обстоятельств.

  • 1
    @carlosvini, это даст вам Undefined variable: res .
  • 0
    @Pacerier Вы правы, лучшее, что вы можете сделать, это: $ res = isset ($ res)? $ res: new stdClass (); - по этой причине у меня не было E_NOTICE 6 месяцев назад, потому что он слишком чертовски многословен.
Показать ещё 1 комментарий
9

Просто,

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

или

    $res = (object)array(); // object(stdClass)

    $res = new stdClass();  // old method

и

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

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

    $res->success = (bool)0; // bool(false)
  • 0
    почему новый stdClass () считается "старым" методом? Остальные как-то лучше?
  • 0
    Это просто из старой версии PHP
4

Попробуйте следующее:

ini_set('error_reporting', E_STRICT);
  • 1
    Благодарю. это полное использование, когда вы используете сторонние библиотеки, такие как nusoap, и не хотите / не можете изменить источник. В этом случае вы можете изменить error_reporting на уровень E_STRICT непосредственно перед тем, как требовать другие исходные файлы.
  • 0
    Хотя я только что добавил это в начало nusoap, чтобы исправить мою проблему.
Показать ещё 2 комментария
3

Если вы поместите символ "@" в начале строки, тогда PHP не будет показывать никаких предупреждений/уведомлений для этой строки. Например:

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

Для предотвращения этого предупреждения для этой строки вы должны поместить символ "@" в строку следующим образом:

@$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 default value is 0.
$unknownVar[$someStringVariable]->totalcall += 10; // you don't need to @ character anymore.
echo $unknownVar[$someStringVariable]->totalcall; // 20

Я использую этот трюк при разработке. Мне не нравится отключать все предупреждающие сообщения, потому что если вы не будете правильно обрабатывать предупреждения, они станут большой ошибкой в ​​будущем.

  • 1
    @ предотвращает предупреждения, подавляя их, выглядит нормально, пока у вас есть управляемый код. Но если ваш код вырастет во что-то большее, и вы столкнулись с проблемой, вы будете сожалеть об этом. Вы обнаружите, что ищете все эти «@» для предупреждения, которое вы хотели бы показать, потому что временно оно выполнило свою задачу, думая, что вы на самом деле решили проблему, когда на самом деле он говорил с вами, и вы просто не захотели послушай
  • 0
    Я уже знаю. Это короткий и быстрый ответ. Есть много решений для этого.
Показать ещё 1 комментарий
2

Попробуйте это, если у вас есть массив и добавьте к нему объекты.

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

Это отправляет ARRAY из объектов для дальнейшего использования ~!

1

Простым способом получить эту ошибку является тип (a) ниже, что означает тип (b)

(a) $this->my->variable

(b) $this->my_variable

Тривиальный, но очень легко упускаемый и трудно различимый, если вы его не ищете.

  • 0
    Как это связано с первоначальным вопросом? Между _ и ->
0

Попробуйте использовать:

$user = (object) null;
  • 1
    Как правило, ответы гораздо полезнее, если они включают в себя объяснение того, для чего предназначен код, и почему это решает проблему, не представляя других.
0

У меня была похожая проблема, и это, кажется, решило проблему. Вам просто нужно инициализировать объект $ res для класса. Предположим, что здесь имя класса test.

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

Вам может потребоваться проверить, объявлена ​​ли переменная и имеет правильный тип.

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;

См. Анонимные классы PHP.

0

Эта проблема вызвана тем, что вы назначаете экземпляр объекта, который не инициирован. Например,

Ваш случай:

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

Решение:

$user = new User;
$user->email = '[email protected]';
  • 0
    Вы не предполагаете, что класс "Пользователь" существует? что это может не так, и теперь он будет генерировать другую ошибку?
  • 1
    На самом деле я не создал экземпляр объекта User, поэтому я получил ошибку. Но после создания экземпляра. Это сработало .. это общая проблема с концепцией ООП :)
Показать ещё 3 комментария
-2

нет, вы этого не сделаете.. он создаст его, когда вы добавите значение успеха объекту. Класс по умолчанию наследуется, если вы его не укажете.

  • 4
    Хотя он будет возвращать сообщение о строгих стандартах ... сначала рекомендуется создать объект вручную, и хотя PHP относительно терпимо относится к неаккуратной практике кодирования, вы не должны игнорировать правильные действия.
  • 4
    понял, я просто отвечал на вопрос простым да или нет, не определяя и не защищая лучшие практики :)
-11

Я поставил следующее в верхней части файла PHP с ошибкой, и ошибка больше не отображалась:

error_reporting(E_ERROR | E_PARSE);
  • 9
    Сокрытие ошибки не устраняет проблему.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню