在PHP中从空值创建默认对象?

Pau*_*aul 342 php

我将PHP环境升级到PHP 5.4及更高版本后才会看到此错误.错误指向这行代码:

错误:

从空值创建默认对象

码:

$res->success = false;
Run Code Online (Sandbox Code Playgroud)

我首先需要声明我的$res对象吗?

Mic*_*ski 588

对于PHP版本<= 5.3.x,您的新环境可能已启用E_STRICT警告,或者至少已设置为PHP版本> = 5.4.当触发了错误的或者尚未初始化:error_reportingerror_reportingE_WARNING$resNULL

$res = NULL;
$res->success = false; // Warning: Creating default object from empty value
Run Code Online (Sandbox Code Playgroud)

如果$res已经初始化为某个值但不是对象,PHP将报告不同的错误消息:

$res = 33;
$res->success = false; // Warning: Attempt to assign property of non-object
Run Code Online (Sandbox Code Playgroud)

为了符合E_STRICTPHP 5.4之前的标准,或E_WARNINGPHP> = 5.4中的正常错误级别,假设您正在尝试创建通用对象并分配属性success,则需要将其声明$resstdClass全局命名空间中的对象:

$res = new \stdClass();
$res->success = false;
Run Code Online (Sandbox Code Playgroud)

  • 你应该检查对象是否已经存在:`if(!isset($ res))$ res = new stdClass();`.否则,此代码不是"旧PHP"隐式对象创建的等效替代. (34认同)
  • @Tomas我们需要再次这样做吗?mods上次清理了评论帖子,因为它增加了很少的价值.没有"旧PHP"隐式对象创建.这总是一个错误,并且始终发出警告,只是它在5.4中从E_STRICT更改为E_WARNING,所以有些人从未遇到它没有注意到E_STRICT. (6认同)
  • @PeterAlfvin没有定义**在那个特定的运行**!但是在不同的运行中,*在代码*的完全相同的位置,对象可能已经被定义了!这是人们经常思考的错误,这也是我试图强调这一点的原因. (4认同)
  • @tomas哦,好吧,我_think_我明白你的意思.你/迈克尔无法解决这个问题似乎很奇怪.顺便说一下,这种交流让我意识到斜体<粗体<allcaps在"力量"方面,而且allcaps =喊叫和斜体=礼貌强调,大胆处于可接受性可疑的中间地带.:-) (3认同)
  • 迈克尔,即使在5.4中,隐式对象创建始终存在并且仍然存在.而BTW在PHP <5.3中既不是E_STRICT也不是E_WARNING.而BTW,mods已经恢复了评论,我被告知要调低它,这就是我重新发布它的原因. (2认同)

TMS*_*TMS 50

此消息E_STRICT适用于PHP <= 5.3.从PHP 5.4开始,它就被改成了E_WARNING.由于E_WARNING消息很有用,因此您不希望完全禁用它们.

要摆脱此警告,您必须使用以下代码:

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

$res->success = false;
Run Code Online (Sandbox Code Playgroud)

完全等同于替换.它确保了PHP默默地做的事情 - 不幸的是现在有警告 - 隐式对象创建.您应该始终检查对象是否已经存在,除非您完全确定它不存在.迈克尔提供的代码一般不好,因为在某些情况下,对象有时可能已经在代码中的相同位置定义,具体取决于具体情况.

  • @carlosvini,这将为您提供未定义的变量:res。 (2认同)

pir*_*irs 10

只是,

    $res = (object)array("success"=>false); // $res->success = bool(false);
Run Code Online (Sandbox Code Playgroud)

要么

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

    $res = new stdClass();  // old method
Run Code Online (Sandbox Code Playgroud)

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

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

    $res->success = (bool)0; // bool(false)
Run Code Online (Sandbox Code Playgroud)


dan*_*lad 6

如果您有数组并向其中添加对象,请尝试此操作。

$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.
}
Run Code Online (Sandbox Code Playgroud)

这会发送对象数组供以后使用~


kod*_*gha 6

如果将“ @”字符放在该行的开头,则PHP不会在该行显示任何警告/通知。例如:

$unknownVar[$someStringVariable]->totalcall = 10; // shows a warning message that contains: Creating default object from empty value
Run Code Online (Sandbox Code Playgroud)

为防止此行出现此警告,必须在该行的开头放置“ @”字符,如下所示:

@$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
Run Code Online (Sandbox Code Playgroud)

我在开发时使用了这个技巧。我不喜欢禁用所有警告消息,因为如果您不能正确处理警告,那么将来它们将成为一个大错误。

  • @ 确实通过抑制警告来防止警告,只要您有可管理的代码就可以了。但是如果你的代码变得更大并且你遇到了问题,你会以某种方式后悔使用它。您会发现自己正在寻找所有那些“@”以获取您想要取消隐藏的警告,因为它暂时达到了目的,认为您实际上已经解决了问题,而实际上它一直在与您交谈,而您只是不会'不听。 (2认同)
  • 太棒了!不过,请允许我表示不同意,隐藏错误并不能真正解决问题(正如Ramy Nasr所说的那样)。 (2认同)