PHPで空の値からデフォルトオブジェクトを作成しますか?


362

PHP環境をPHP 5.4以降にアップグレードした後にのみ、このエラーが表示されます。エラーは次のコード行を指しています。

エラー:

空の値からデフォルトオブジェクトを作成する

コード:

$res->success = false;

最初に$resオブジェクトを宣言する必要がありますか?


11
どのように/どこから始め$res ますか?
2012年

1
@NAVEED あります。
7heo.tk

回答:


627

新しい環境では、PHPバージョン<= 5.3.xでE_STRICT警告が有効になっているerror_reportingerror_reporting、少なくともE_WARNINGPHPバージョン> = 5.4で警告が設定されている可能性があります。そのエラーは、$resNULLまだ初期化されていない場合にトリガーされます。

$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_STRICTPHP 5.4より前の標準、またはPHPの通常のE_WARNINGエラーレベル> = 5.4 に準拠するには、汎用オブジェクトを作成してプロパティを割り当てようとしていると想定して、グローバルネームスペースでのオブジェクトとしてsuccess宣言する必要があります。$resstdClass

$res = new \stdClass();
$res->success = false;

38
オブジェクトが既に存在するかどうかを確認する必要があります:if (!isset($res)) $res = new stdClass();。それ以外の場合、このコードは「古いPHP」の暗黙的なオブジェクト作成に代わるものではありません。
TMS

6
@Tomasこれをもう一度行う必要がありますか?modはほとんど価値がないため、前回コメントスレッドをクリーンアップしました。「古いPHP」の暗黙的なオブジェクト作成はありません。これは常にエラーであり、警告を発行していましたが、5.4でE_STRICTからE_WARNINGに変更されただけなので、E_STRICTに注意を払っていなかったことに遭遇したことはありません。
マイケル・バーコウスキー

4
@PeterAlfvinそれはその特定の実行で定義されていませんでした!しかし、別の実行では、コード内のまったく同じ場所で、オブジェクトはすでに定義されている可能性があります。これは人がよく考える誤解であり、それを強調したいのはこのためです。
TMS

2
Michael、暗黙的なオブジェクトの作成は5.4でも常に存在し、まだ存在しています。ところで、PHP <5.3では、E_STRICTでもE_WARNINGでもありませんでした。ところで、改造はコメントを元に戻し、私はそれを引き下げるように言われました、それで私はそれを再投稿しました。
TMS

3
@tomasああ、そうか、私あなたの言っていることがわかると思う。あなた/マイケルがこれで閉鎖に到達できないのは奇妙に思えます。ところで、この交換により、「強さ」に関してイタリック体<bold <allcapsがあり、allcaps = shoutingとitalics = politeEmphasisの間、太字は許容範囲が疑わしいところにあることがわかりました。:-)
Peter Alfvin 2013年

57

このメッセージはE_STRICT、PHP 5.3以降用です。PHP 5.4以降、残念ながらに変更されましたE_WARNINGE_WARNINGメッセージは便利なので、完全に無効にする必要はありません。

この警告を取り除くには、次のコードを使用する必要があります。

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

$res->success = false;

これは完全に同等の置き換えです。これは、PHPが静かに行っていることとまったく同じことを保証します-現在は警告なしで不愉快に-暗黙的なオブジェクトの作成。存在しないことが確実でない限り、オブジェクトがすでに存在するかどうかを常に確認する必要があります。Michaelが提供するコードは、状況によっては、オブジェクトがコード内の同じ場所ですでに定義されている場合があるため、一般的には良くありません。


2
@carlosvini、これはあなたに与えるでしょうUndefined variable: res
Pacerier、2015年

1
@Pacerierあなたは正しい、あなたができる最善のことは:$ res = isset($ res)?$ res:新しいstdClass(); -冗長すぎるため、6か月前にE_NOTICEを有効にしなかったのはそのためです。
カルロスビニ2015年

13

単に、

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

または、次のようにしてクラスをインスタンス化することもできます。

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

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

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

値を入力してください:

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

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

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

詳細情報:https : //www.php.net/manual/en/language.types.object.php#language.types.object.casting


new stdClass()が「古い」メソッドと見なされるのはなぜですか?他の人はどういうわけか良いですか?
アーロン

単純に古いphpバージョンから
pirs

私の場合$this->route->uri = new stdClass();、うまくいかない場合でも、警告が表示されます。注:$this->routeは存在します。
Meloman

多分これは新しいバージョンのphpと互換性がありませんか?どのバージョンを使用しましたか?
1

6

「@」文字を行の先頭に置くと、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's default value is 0.
$unknownVar[$someStringVariable]->totalcall += 10; // you don't need to @ character anymore.
echo $unknownVar[$someStringVariable]->totalcall; // 20

私は開発時にこのトリックを使用しています。警告を正しく処理しないとすべての警告メッセージを無効にしたくないので、今後大きなエラーになります。


1
@は警告を抑制して抑制しますが、管理可能なコードがある限り問題ありません。しかし、コードが大きくなって問題に遭遇した場合、どういうわけかこれを使用することを後悔します。非表示にしたくない警告のすべての「@」を探していることに気づくでしょう。一時的にそれが実際に問題を修正したと考えていたため、一時的にそれが目的を果たし、実際にそれがあなたに話していただけで、聞いて。
Vincent Edward Gedaria Binua 2017

私はすでに知っている。これは短くて速い答えです。これには多くの解決策があります。
kodmanyagha

2
驚くばかり!ただし、同意しないようにお願いしてもかまいません。エラーを非表示にしても問題が解決するわけではありません(Ramy Nasrもコメントしています)。
Vincent Edward Gedaria Binua 2017

この回避策は、php 7.2で私にとって唯一の回避策です。
Meloman

3

配列があり、それにオブジェクトを追加する場合は、これを試してください。

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

これは、後で使用するためにオブジェクトの配列を送信します〜!


1
ありがとうございました!!!!これは仕事を成し遂げるのを助けたものです。PHPに各要素が何であるかを段階的に伝える必要がありました。怠惰な笑をコーディングしないように思い出させてくれてありがとう。
yanike

2

これを試して:

ini_set('error_reporting', E_STRICT);

1
ありがとう。これは、nusoapなどのサードパーティのライブラリを使用していて、ソースを変更したくない、または変更できない場合に使用されます。その場合、他のソースファイルを要求する直前にerror_reportingをE_STRICTレベルに変更できます。
mtoloo 2013

これをnusoapの上部に追加して問題を解決しましたが。
badweasel 2014

11
えっ?ここのコードはE_STRICT、致命的なエラーのメッセージの抑制を含む、エラーを除くすべてのエラー報告を無効にします。これは、この特定の警告を解決するための妥当な提案ではありません。さらに、あなたがしたくないことはほとんどありません。なぜ5人がこれに賛成したのか、私には手掛かりがありません。
マークアメリー2014

1
これはひどいです!使用ini_set('error_reporting', -1);デバッグ中に、しかし、これまでのように、上記使用しないでください。
Kzqai

わかりましたので、これを非表示にして問題を修正しますか?コードが期待どおりに動作するかどうかわからない...
1

1

同様の問題があり、これで問題が解決したようです。$ resオブジェクトをクラスに初期化するだけです。ここでクラス名がtestであるとします。

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

1

これは私がPHP 7で直面した警告です。これを簡単に修正するには、使用する前に変数を初期化します

$myObj=new \stdClass();

初期化したら、オブジェクトに使用できます

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

0

この問題は、開始されていないオブジェクトのインスタンスに割り当てているために発生します。たとえば:

あなたの場合:

$user->email = 'exy@gmail.com';

解決:

$user = new User;
$user->email = 'exy@gmail.com';

クラス「ユーザー」が存在すると想定していませんか?それはできないかもしれませんが、今は別のエラーを生成しますか?
クリストファートーマス

1
実際にはUserオブジェクトのインスタンスを作成しなかったため、エラーが発生しました。しかし、インスタンスを作成した後。それは機能しました.. OOPsコンセプトの一般的な問題です:)
Bastin Robin

6
実際のところ、実際の問題は、ユーザークラスが定義されているユーザークラスを想定していることです。これは、オブジェクト指向の一般的な問題ではなく、その重要な要件です。)
Christopher Thomas

1
私はむしろ、「ユーザー」を意味する前提を置き換える一般的な「stdClass」を使用したいと思います。
TechNyquist

0

このエラーを取得する簡単な方法は、以下の(a)を入力すること、つまり(b)を入力することです

(a) $this->my->variable

(b) $this->my_variable

ささいなことですが、見過ごされがちで、探していなければ見つけにくいものです。


これは元の質問とどのように関連していますか?そこにはミックスアップの間にはなかった_->
ニコハーゼ

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

APIから返されたオブジェクトに変数を追加しようとしたときに、同様の問題が発生しました。私はforeachループでデータを反復処理していました。

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

これにより、Laravelで「空の値からのデフォルトオブジェクトの作成」例外がスローされました。

非常に小さな変更で修正しました。

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

$ dataを参照にするだけです。

それが誰かを助けてくれることを願っています。


0
  1. まず、オブジェクトを作成する必要があると思います$ res = new \ stdClass();

  2. 次に、オブジェクトにキーと値を割り当てます。$ res-> success = false;


(わかりませんthay。)一部のコンテンツの後に改行を入れたい場合は、改行する前に、表示されている行のコンテンツに2つの空白スペースを追加します。
greybeard

-1

オブジェクトに成功値を追加すると作成されます。指定しない場合、デフォルトのクラスが継承されます。


4
厳密な標準メッセージが返されますが、最初にオブジェクトを手動で作成することは単に良い習慣であり、PHPはお粗末なコーディング慣行に比較的寛容ですが、正しく行うことを無視してはなりません。
Mark Ba​​ker

4
わかりました、私は単純に「はい」または「いいえ」で質問に答えていて、ベストプラクティスを定義または守っていません:)
Silvertiger

-1

使ってみてください:

$user = (object) null;

2
一般的に、回答にコードの目的、および他の人を紹介することなく問題を解決する理由の説明が含まれている場合、回答ははるかに役立ちます。
lucascaro

-12

次のコードをエラーのあるPHPファイルの先頭に追加したところ、エラーは表示されなくなりました。

error_reporting(E_ERROR | E_PARSE);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.