PHP'de boş değerden varsayılan nesne mi oluşturuyorsunuz?


362

Ben sadece PHP ortamımı PHP 5.4 ve ötesine yükselttikten sonra bu hatayı görüyorum. Hata şu kod satırını gösterir:

Hata:

Boş değerden varsayılan nesne oluşturma

Kod:

$res->success = false;

Önce nesnesimi beyan etmem gerekir $resmi?


11
Nasıl / Nereye başlıyorsunuz $res ?
Naveed

1
@NAVEED Orada .
7heo.tk

Yanıtlar:


627

Yeni ortamınızda, <= 5.3.x PHP sürümleri için E_STRICTuyarılar etkinleştirilmişerror_reporting olabilir veya error_reportingen azından E_WARNINGPHP => 5.4 sürümleriyle ayarlanmış olabilir . O zaman hata tetiklenir $resolduğu NULLveya henüz başlatılmadı:

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

PHP $reszaten bir değere başlatılmışsa ancak bir nesne değilse farklı bir hata mesajı verecektir :

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

Genel bir nesne oluşturmaya ve özelliği atamaya çalıştığınızı varsayarsak E_STRICT, PHP 5.4'ten önceki standartlara veya E_WARNINGPHP> = 5.4'teki normal hata düzeyine uymak için , genel ad alanında bir nesne olarak successbildirmeniz gerekir :$resstdClass

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

38
Sen nesne zaten var olup olmadığını kontrol shoud: if (!isset($res)) $res = new stdClass();. Aksi takdirde, bu kod "eski PHP" örtük nesne oluşturma yerine eşdeğer bir alternatif değildir.
TMS

6
@Tomas Bunu tekrar yapmamız gerekiyor mu? Mods, çok az değer kattığı için yorum dizisini son kez temizledi. "Eski PHP" örtük nesne oluşturma işlemi yoktur. Her zaman bir hataydı ve her zaman bir uyarı yayınladı, sadece 5.4'te E_STRICT'den E_WARNING'e değiştirildi, bu yüzden bazı insanlar E_STRICT'e dikkat etmediği için hiç karşılaşmadı.
Michael Berkowski

4
@PeterAlfvin belirli bir koşuda tanımlanmadı ! Ancak farklı çalıştırmada, koddaki aynı yerde , nesne zaten tanımlanmış olabilir! İnsanların sık sık yaptıkları düşünmede hata budur ve bunu vurgulamaya çalışmamın nedeni budur.
TMS

2
Michael, örtük nesne yaratımı her zaman 5.4'te bile mevcuttu ve hala mevcut. Ve BTW PHP <5.3'te ne E_STRICT ne de E_WARNING değildi. Ve BTW, modlar yorumu geri yükledi ve bunu tonlamam söylendi, bu yüzden tekrar gönderdim.
TMS

3
Ah @tomas, tamam, ben düşünüyorum ne demek istediğini olsun. Senin / Michael'ın bu konuda kapanamaması tuhaf görünüyor. BTW, bu mübadele beni "güç" açısından italik <kalın <allcaps olduğunu ve allcaps = bağırarak ve italics = politeEmphasis olsa da, kalın yazı tipinin kabul edilebilirliğin sorgulanabilir olduğu orta bir yerde olduğunu anlamamı sağladı. :-)
Peter Alfvin

57

Bu ileti E_STRICTPHP <= 5.3 için yapılmıştır. PHP 5.4'ten beri şanssız olarak değiştirildi E_WARNING. Yana E_WARNINGmesajlar faydalıdır, bunları tamamıyla devre dışı bırakmak istemiyoruz.

Bu uyarıdan kurtulmak için şu kodu kullanmalısınız:

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

$res->success = false;

Bu tamamen eşdeğer bir alternatiftir . PHP'nin sessizce yaptığı şeyi - şimdi uyarı ile talihsiz bir şekilde - örtük nesne oluşturma ile tam olarak aynı şeyi garanti eder. Kesinlikle olmadığından emin değilseniz, nesnenin zaten var olup olmadığını her zaman kontrol etmelisiniz. Michael tarafından sağlanan kod genel olarak iyi değildir, çünkü bazı bağlamlarda nesne, koşullara bağlı olarak bazen kodda aynı yerde zaten tanımlanmış olabilir.


2
@carlosvini, Bu sana verecek Undefined variable: res.
Pacerier

1
@Pacerier Haklısınız, yapabileceğiniz en iyi şey: $ res = isset ($ res)? $ res: yeni stdClass (); - çok ayık olduğu için 6 ay önce E_NOTICE özelliğini etkinleştirmememin nedeni buydu.
carlosvini

13

basitçe,

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

Veya sınıfları aşağıdakilerle başlatabilirsiniz:

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

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

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

ve değerleri şununla doldur:

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

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

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

Daha fazla bilgi: https://www.php.net/manual/en/language.types.object.php#language.types.object.casting


new stdClass () neden "eski" bir yöntem olarak kabul edilir? Diğerleri bir şekilde daha mı iyi?
Aaron

Onun sadece eski php versiyonu
pirs

benim durumumda benim $this->route->uri = new stdClass();için çalışmıyor, hala uyarı var. Not: $this->routemevcut.
Meloman

Belki bu php yeni sürümleri ile uyumlu değil? Hangi sürümü kullandınız?
pirs

6

"@" Karakterini satırın başına koyarsanız, PHP bu satır için herhangi bir uyarı / uyarı göstermez. Örneğin:

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

Bu satır için bu uyarıyı önlemek için satırın "@" karakterini şöyle başlatmanız gerekir:

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

Bu hileyi gelişirken kullanıyorum. Uyarıları doğru işlemezseniz, tüm uyarı mesajlarını devre dışı bırakmayı sevmem, o zaman gelecekte büyük bir hata haline gelecektir.


1
@, uyarıları engelleyerek uyarıları önler, yönetilebilir kodunuz olduğu sürece iyi görünür. Ancak kodunuz daha büyük bir şeye dönüşürse ve bir sorunla karşılaşırsanız, bunu bir şekilde pişman olacaksınız. Kendinizi gizlemek istediğiniz bir uyarı için tüm bu "@" 'yi ararken bulacaksınız, çünkü geçici olarak gerçekte sizinle konuştuğunda sorunu çözdüğünüzü düşünerek amacına hizmet etti ve sadece Dinle.
Vincent Edward Gedaria Binua

Zaten biliyorum. Bu kısa ve hızlı bir cevap. Bunun için birçok çözüm var.
kodmanyagha

2
müthiş! Kibarca katılmıyorum, hatayı gizlemek sorunu gerçekten düzeltmiyor (Ramy Nasr'ın da söylediği gibi).
Vincent Edward Gedaria Binua

Bu geçici çözüm php 7.2'de benim için tek çalışma.
Meloman

3

Diziniz varsa ve buna nesne eklerseniz bunu deneyin.

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

Bu , daha sonra kullanılmak üzere ARRAY of Objects gönderir ~!


1
TEŞEKKÜR EDERİM!!!! Bu işin yapılmasına yardımcı olan şey budur. PHP'nin her bir öğenin ne olduğunu adım adım anlatmam gerekiyordu. Tembel lol kodlamamı hatırlattığınız için teşekkürler.
yanike

2

Bunu dene:

ini_set('error_reporting', E_STRICT);

1
Teşekkürler. bu, nusoap gibi üçüncü taraf kitaplıkları kullanırken tam kaynağı kullanmaktır ve kaynağı değiştirmek istemez / değiştiremez. Bu durumda, diğer kaynak dosyaları gerekmeden hemen önce error_reporting'i E_STRICT seviyesine değiştirebilirsiniz .
mtoloo

Her ne kadar ben sadece bu sorunu çözmek için nusoap üstüne ekledi.
badweasel

11
Ha? Buradaki kod E_STRICT, iletilerin önemli hatalar için bastırılması da dahil olmak üzere hatalar dışındaki tüm hata raporlarını devre dışı bırakır . Bu özel uyarıyı çözmek için makul bir öneri değildir ve dahası, neredeyse hiç yapmak istemediğiniz bir şeydir. Neden 5 kişi bunu onayladı, hiçbir fikrim yok.
Mark Amery

1
Bu çok kötü! ini_set('error_reporting', -1);hata ayıklama sırasında kullanın , ancak her zamanki gibi yukarıdakileri kullanmayın.
Kzqai

Peki, bunu gizleyerek bir sorunu çözüyor musun? Kodunuzun beklendiği gibi çalışacağından emin
değilsiniz

1

Benzer bir sorunum vardı ve bu sorunu çözüyor gibi görünüyor. Sadece $ res nesnesini bir sınıfa başlatmanız gerekir. Burada sınıf adının test olduğunu varsayalım.

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

1

Bu, PHP 7'de karşılaştığım bir uyarı, bunu düzeltmek için kullanmadan önce değişkeni başlatmak

$myObj=new \stdClass();

Bir kez intialize ettikten sonra nesneler için kullanabilirsiniz

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

0

Bu sorun, başlatılmamış bir nesne örneğine atadığınız için oluşur. Örneğin:

Senin durumun:

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

Çözüm:

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

"Kullanıcı" sınıfının var olduğunu düşünmüyor musunuz? hangi olmayabilir ve şimdi farklı bir hata üretecek?
Christopher Thomas

1
Aslında ben bir hata var Kullanıcı nesnesinin bir örneğini oluşturmadı. Ama bir örnek oluşturduktan sonra. İşe yaradı .. OOPs konsepti ile ilgili genel bir sorun :)
Bastin Robin

6
aslında, asıl sorun, örneğinizin tanımlanacak kullanıcı sınıfını varsaymasıdır, bu nesne yöneliminin genel bir sorunu değildir, temel bir gereksinimdir;)
Christopher Thomas

1
Ben yerine "Kullanıcı" ima öncül yerine genel bir "stdClass" koymak istiyorum.
TechNyquist

0

Bu hatayı almanın basit bir yolu, aşağıdaki (a) türünü, yani (b) türünü yazmaktır

(A) $this->my->variable

(B) $this->my_variable

Önemsiz, ama çok kolay gözden kaçan ve eğer aramıyorsanız bulmak zor.


Bu orijinal soru ile nasıl ilişkilidir? Arasında var-karıştırmak hayır edildi _ve->
Nico Haase

0

Değişkenin bildirildiğini ve doğru türde olup olmadığını kontrol etmeniz gerekebilir.

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 anonim sınıflarına bakın .


0

Bir API döndürülen bir nesneye bir değişken eklemek çalışırken benzer bir sorun vardı. Bir foreach döngüsü ile veri üzerinden yineleme yapıyordum.

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

Bu, Laravel'de "Boş değerden varsayılan nesne oluşturma" Özel Durumunu attı.

Çok küçük bir değişiklikle düzelttim.

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

Sadece $ data bir referans yapmak.

Umarım bu birine yardım eder, bu beni cehenneme sataştırdı!


0
  1. İlk önce $ res = new \ stdClass ();

  2. sonra anahtar ve değeri thay $ res-> success = false olan bir nesne atayın;


(Anlamıyorum thay.) Bazı içeriklerden sonra satır sonu olmasını istediğinizde, aradan önce satırın görünür içeriğine iki boşluk ekleyin.
greybeard

-1

hayır yapmazsınız .. nesneye başarı değerini eklediğinizde bunu oluşturur. bir tane belirtmezseniz varsayılan sınıf devralınır.


4
Sıkı standartlar mesajını döndürecek olsa da ... önce nesneyi manuel olarak oluşturmak iyi bir uygulamadır ve PHP kalitesiz kodlama uygulamasına nispeten toleranslı olsa da, işleri doğru yapmayı görmezden gelmemelisiniz.
Mark Baker

4
Anladım, sadece basit bir evet ya da hayır ile soruya cevap veriyordum, en iyi uygulamaları tanımlamıyor ya da savunmuyordum :)
Silvertiger

-1

Kullanmayı deneyin:

$user = (object) null;

2
Genellikle, kodun ne yapması gerektiği ve başkalarını tanıtmadan sorunu neden çözdüğüne dair bir açıklama içeriyorsa, cevaplar çok daha yararlıdır.
lucascaro

-12

Hatalı PHP dosyasının üstüne aşağıdaki koymak ve hata artık görüntülenmedi:

error_reporting(E_ERROR | E_PARSE);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.