Membuat objek default dari nilai kosong di PHP?

362

Saya melihat kesalahan ini hanya setelah memutakhirkan lingkungan PHP saya menjadi PHP 5.4 dan selanjutnya. Kesalahan menunjuk ke baris kode ini:

Kesalahan:

Membuat objek default dari nilai kosong

Kode:

$res->success = false;

Apakah saya pertama-tama harus mendeklarasikan $resobjek saya ?

Paul
sumber
11
Bagaimana / Di mana Anda memulai $res ?
Naveed
1
@DITEMUKAN Di sana .
7heo.tk

Jawaban:

627

Lingkungan baru Anda mungkin mengaktifkanE_STRICT peringatan untuk untuk versi PHP <= 5.3.x, atau cukup setel setidaknya dengan versi PHP> = 5.4. Kesalahan itu dipicu ketika sedang atau belum diinisialisasi:error_reportingerror_reportingE_WARNING$resNULL

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

PHP akan melaporkan pesan kesalahan yang berbeda jika $ressudah diinisialisasi ke beberapa nilai tetapi bukan objek:

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

Untuk mematuhi E_STRICTstandar sebelum PHP 5.4, atau E_WARNINGtingkat kesalahan normal dalam PHP> = 5.4, dengan asumsi Anda mencoba membuat objek generik dan menetapkan properti success, Anda perlu mendeklarasikan $ressebagai objek stdClassdi dalam namespace global:

$res = new \stdClass();
$res->success = false;
Michael Berkowski
sumber
38
Anda shoud memeriksa apakah objek tersebut sudah ada: if (!isset($res)) $res = new stdClass();. Jika tidak, kode ini bukan pengganti yang setara untuk pembuatan objek implisit "PHP lama".
TMS
6
@ Thomas Apakah kita perlu melakukan ini lagi? Mod membersihkan thread komentar terakhir karena menambah sedikit nilai. Tidak ada pembuatan objek implisit "PHP lama". Itu selalu merupakan kesalahan dan selalu mengeluarkan peringatan, hanya saja itu diubah dari E_STRICT ke E_WARNING di 5.4, jadi beberapa orang tidak pernah menjumpainya tidak memperhatikan E_STRICT.
Michael Berkowski
4
@PeterAlfvin itu tidak didefinisikan dalam satu menjalankan tertentu ! Tetapi dalam proses yang berbeda, pada tempat yang sama persis dalam kode , objek mungkin sudah ditentukan! Ini adalah kesalahan dalam berpikir orang sering membuat dan itulah alasan saya mencoba untuk menekankan itu.
TMS
2
Michael, penciptaan objek implisit selalu dan masih ada bahkan dalam 5.4. Dan BTW Dalam PHP <5.3 itu bukan E_STRICT atau E_WARNING. Dan BTW, mod telah memulihkan komentar dan saya diberitahu untuk menurunkannya, itu sebabnya saya mempostingnya kembali.
TMS
3
@ Thomas Oh, ok, saya rasa saya mengerti maksud Anda. Tampaknya aneh bahwa Anda / Michael tidak bisa menutup ini. BTW, pertukaran ini telah membuat saya menyadari bahwa huruf miring <bold <allcaps dalam hal "kekuatan" dan bahwa sementara allcaps = berteriak dan huruf miring = politeEmphasis, berani berada di jalan tengah di mana penerimaan dapat dipertanyakan. :-)
Peter Alfvin
57

Pesan ini E_STRICTditujukan untuk PHP <= 5.3. Sejak PHP 5.4, sayangnya diubah menjadi E_WARNING. Karena E_WARNINGpesan berguna, Anda tidak ingin menonaktifkannya sama sekali.

Untuk menghilangkan peringatan ini, Anda harus menggunakan kode ini:

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

$res->success = false;

Ini adalah penggantian yang sepenuhnya setara . Ini memastikan hal yang persis sama yang dilakukan oleh PHP secara diam-diam - sayangnya dengan peringatan sekarang - pembuatan objek implisit. Anda harus selalu memeriksa apakah objek sudah ada, kecuali Anda benar-benar yakin itu tidak ada. Kode yang disediakan oleh Michael secara umum tidak bagus, karena dalam beberapa konteks objek kadang-kadang mungkin sudah didefinisikan di tempat yang sama dalam kode, tergantung pada keadaan.

TMS
sumber
2
@carlosvini, Ini akan memberimu Undefined variable: res.
Pacerier
1
@Pacerier Anda benar, hal terbaik yang dapat Anda lakukan adalah: $ res = isset ($ res)? $ res: stdClass baru (); - yang merupakan alasan saya tidak mengaktifkan E_NOTICE 6 bulan lalu, karena terlalu bertele-tele.
carlosvini
13

Secara sederhana,

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

Atau Anda dapat membuat instance kelas dengan:

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

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

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

dan isi nilai dengan:

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

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

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

Info lebih lanjut: https://www.php.net/manual/en/language.types.object.php#language.types.object.casting

pir
sumber
mengapa stdClass baru () dianggap sebagai metode "lama"? Apakah yang lain entah bagaimana lebih baik?
Aaron
Ini hanya dari versi php lama
pir
dalam kasus saya $this->route->uri = new stdClass();tidak bekerja untuk saya, saya masih punya peringatan. Catatan: $this->routeada.
Meloman
Mungkin ini tidak kompatibel dengan versi php baru? Versi mana yang Anda gunakan?
pir
6

Jika Anda memasukkan karakter "@" di awal baris maka PHP tidak menampilkan peringatan / pemberitahuan untuk baris ini. Sebagai contoh:

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

Untuk mencegah peringatan ini untuk baris ini, Anda harus meletakkan karakter "@" di awal baris seperti ini:

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

Saya menggunakan trik ini saat berkembang. Saya tidak suka menonaktifkan semua pesan peringatan karena jika Anda tidak menangani peringatan dengan benar maka mereka akan menjadi kesalahan besar di masa depan.

kodmanyagha
sumber
1
@ tidak mencegah peringatan dengan menekannya, terlihat baik selama Anda memiliki kode yang dapat dikelola. Tetapi jika kode Anda tumbuh menjadi sesuatu yang lebih besar dan Anda mengalami masalah, entah bagaimana Anda akan menyesal menggunakan ini. Anda akan menemukan diri Anda mencari semua "@" itu untuk peringatan yang ingin Anda sembunyikan karena untuk sementara ia telah melayani tujuannya dengan berpikir bahwa Anda telah benar-benar memperbaiki masalah ketika pada kenyataannya itu telah berbicara kepada Anda dan Anda hanya tidak akan t mendengarkan.
Vincent Edward Gedaria Binua
Saya sudah tahu. Ini jawaban singkat dan cepat. Ada banyak solusi untuk ini.
kodmanyagha
2
luar biasa! Bolehkah saya dengan sopan memohon untuk tidak setuju, menyembunyikan kesalahan tidak benar-benar memperbaiki masalah (seperti yang juga dikatakan oleh Ramy Nasr).
Vincent Edward Gedaria Binua
Solusi ini adalah satu-satunya pekerjaan bagi saya di php 7.2.
Meloman
3

Coba ini jika Anda memiliki larik dan tambahkan objek ke dalamnya.

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

Ini mengirimkan ARRAY of Objects untuk digunakan nanti ~!

Daniel Adenew
sumber
1
TERIMA KASIH!!!! Inilah yang membantu menyelesaikan pekerjaan. Saya perlu memberi tahu PHP langkah-demi-langkah apa setiap elemen itu. Terima kasih telah mengingatkan saya untuk tidak kode lol malas.
yanike
2

Coba ini:

ini_set('error_reporting', E_STRICT);
Irfan
sumber
1
Terima kasih. ini digunakan penuh ketika Anda menggunakan perpustakaan pihak ketiga seperti nusoap dan tidak ingin / tidak bisa mengubah sumber. Dalam hal ini Anda dapat mengubah error_reporting ke level E_STRICT sesaat sebelum membutuhkan file sumber lainnya.
mtoloo
Meskipun saya baru saja menambahkan ini ke bagian atas nusoap untuk memperbaiki masalah saya.
badweasel
11
Hah? Kode di sini menonaktifkan semua pelaporan E_STRICTkesalahan kecuali kesalahan, termasuk menekan pesan untuk kesalahan fatal. Itu bukan saran yang masuk akal untuk menyelesaikan peringatan khusus ini, dan terlebih lagi adalah sesuatu yang hampir tidak pernah ingin Anda lakukan. Mengapa 5 orang memilih ini, saya tidak tahu.
Mark Amery
1
Ini sangat buruk! gunakan ini_set('error_reporting', -1);saat debugging, tetapi jangan gunakan hal di atas, seperti sebelumnya.
Kzqai
Oke, jadi Anda memperbaiki masalah dengan menyembunyikan yang ini? Tidak yakin kode Anda akan berfungsi seperti yang diharapkan ...
pir
1

Saya memiliki masalah yang sama dan ini tampaknya menyelesaikan masalah. Anda hanya perlu menginisialisasi objek $ res ke sebuah kelas. Misalkan di sini nama kelasnya adalah tes.

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

Ini adalah peringatan yang saya hadapi di PHP 7, perbaikan yang mudah untuk ini adalah dengan menginisialisasi variabel sebelum menggunakannya

$myObj=new \stdClass();

Setelah Anda menginternalisasi itu maka Anda dapat menggunakannya untuk objek

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

Masalah ini disebabkan karena Anda menugaskan ke instance objek yang tidak dimulai. Untuk misalnya:

Kasus Anda:

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

Larutan:

$user = new User;
$user->email = '[email protected]';
Bastin Robin
sumber
tidakkah Anda berasumsi bahwa kelas "Pengguna" ada? yang mana mungkin tidak dan sekarang akan menghasilkan kesalahan yang berbeda?
Christopher Thomas
1
Sebenarnya saya tidak membuat turunan dari objek Pengguna jadi saya mendapat kesalahan. Tapi setelah membuat sebuah instance. Berhasil .. ini masalah umum dengan konsep OOP :)
Bastin Robin
6
baik, sebenarnya masalah sebenarnya adalah bahwa contoh Anda mengasumsikan kelas pengguna didefinisikan, ini bukan masalah generik dari orientasi objek, ini merupakan persyaratan utama;)
Christopher Thomas
1
Saya lebih suka meletakkan "stdClass" generik menggantikan premis yang menyiratkan "Pengguna".
TechNyquist
0

Cara mudah untuk mendapatkan kesalahan ini adalah dengan mengetik (a) di bawah ini, artinya mengetik (b)

(Sebuah) $this->my->variable

(b) $this->my_variable

Sepele, tetapi sangat mudah diabaikan dan sulit dikenali jika Anda tidak mencarinya.

Tannin
sumber
Bagaimana ini terkait dengan pertanyaan awal? Tidak ada campur aduk antara _dan->
Nico Haase
0

Anda mungkin perlu memeriksa apakah variabel dideklarasikan dan memiliki tipe yang benar.

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;

Lihat kelas anonim PHP .

Anton Pelykh
sumber
0

Saya punya masalah yang sama ketika mencoba menambahkan variabel ke objek yang dikembalikan dari API. Saya iterasi melalui data dengan loop foreach.

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

Ini melemparkan "Membuat objek default dari nilai kosong" Pengecualian di Laravel.

Saya memperbaikinya dengan perubahan yang sangat kecil.

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

Dengan hanya membuat $ data referensi.

Saya harap itu membantu seseorang dan itu mengganggu saya!

Andy
sumber
0
  1. Pertama-tama Anda harus membuat objek $ res = new \ stdClass ();

  2. kemudian tetapkan objek dengan kunci dan nilai thay $ res-> success = false;

Sukron Ma'mun
sumber
(Saya tidak mengerti thay.) Di mana Anda ingin jeda baris setelah beberapa konten, tambahkan dua spasi kosong ke konten garis yang terlihat sebelum jeda.
greybeard
-1

tidak Anda tidak .. itu akan membuatnya ketika Anda menambahkan nilai keberhasilan ke objek. kelas default diwarisi jika Anda tidak menentukan satu.

Silvertiger
sumber
4
Meskipun itu akan mengembalikan pesan standar Ketat ... itu hanya praktik yang baik untuk membuat objek secara manual terlebih dahulu, dan sementara PHP relatif toleran terhadap praktik pengkodean yang buruk, Anda tidak boleh mengabaikan melakukan sesuatu dengan benar.
Mark Baker
4
mengerti, saya hanya menjawab pertanyaan dengan ya atau tidak sederhana, tidak mendefinisikan atau mempertahankan praktik terbaik :)
Silvertiger
-1

Coba gunakan:

$user = (object) null;
Fischer Tirado
sumber
2
Secara umum, jawaban akan jauh lebih membantu jika mereka menyertakan penjelasan tentang apa yang dimaksudkan untuk dilakukan oleh kode, dan mengapa hal itu menyelesaikan masalah tanpa memperkenalkan orang lain.
lucascaro
-12

Saya menempatkan yang berikut ini di bagian atas file PHP yang bermasalah dan kesalahan tidak lagi ditampilkan:

error_reporting(E_ERROR | E_PARSE);
Doug
sumber