PHP में रिक्त मान से डिफ़ॉल्ट ऑब्जेक्ट बनाना?


362

मैं अपने PHP वातावरण को PHP 5.4 और उसके बाद के उन्नयन के बाद ही इस त्रुटि को देखता हूं। त्रुटि कोड की इस लाइन को इंगित करती है:

त्रुटि:

रिक्त मान से डिफ़ॉल्ट ऑब्जेक्ट बनाना

कोड:

$res->success = false;

क्या मुझे पहली बार अपनी $resवस्तु घोषित करने की आवश्यकता है ?


11
आप कैसे / कहाँ आरंभ कर रहे हैं $res ?
नौ

जवाबों:


627

आपके नए वातावरण में PHP संस्करणों के लिए सक्षमE_STRICT चेतावनी हो सकती है <= 5.3.x, या बस कम से कम PHP संस्करण> = 5.4 के साथ सेट करें । उस त्रुटि को ट्रिगर किया गया है जब अभी तक आरंभीकृत है या नहीं:error_reportingerror_reportingE_WARNING$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, या E_WARNINGPHP> = 5.4 में सामान्य त्रुटि स्तर से पहले मानकों का पालन करने के लिए , यह मानते हुए कि आप एक सामान्य ऑब्जेक्ट बनाने और संपत्ति को असाइन करने का प्रयास कर रहे हैं success, आपको वैश्विक नामस्थान में $resऑब्जेक्ट के रूप में घोषित करने की आवश्यकता है stdClass:

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

38
आप जाँच करें कि क्या वस्तु पहले से मौजूद है if (!isset($res)) $res = new stdClass();:। अन्यथा, यह कोड "पुरानी PHP" अंतर्निहित वस्तु निर्माण के लिए एक समान प्रतिस्थापन नहीं है।
टीएमएस

6
@ टॉमा क्या हमें फिर से ऐसा करने की आवश्यकता है? Mods ने पिछली बार कमेंट थ्रेड को साफ़ किया क्योंकि इसमें बहुत कम मूल्य मिला। कोई "पुरानी PHP" अंतर्निहित वस्तु निर्माण नहीं है। यह हमेशा एक त्रुटि थी और हमेशा एक चेतावनी जारी की, बस यह E_STRICT से E_WARNING में 5.4 में बदल दिया गया था, इसलिए कुछ लोगों ने कभी भी इसका सामना नहीं किया E_STRICT पर ध्यान नहीं दिया।
माइकल बर्कोव्स्की

4
@PeterAlfvin यह उस एक विशेष रन में परिभाषित नहीं किया गया था ! लेकिन अलग-अलग रन में, कोड में सटीक एक ही स्थान पर , वस्तु पहले से ही परिभाषित हो सकती है! यह सोचने में गलती है कि लोग अक्सर बनाते हैं और यही कारण है कि मैं उस पर जोर देने की कोशिश करता हूं।
TMS

2
माइकल, अंतर्निहित वस्तु निर्माण हमेशा था और अभी भी 5.4 में मौजूद है। और PHP में BTW <5.3 यह न तो E_STRICT था और न ही E_WARNING था। और बीटीडब्लू, मॉड्स ने टिप्पणी को बहाल कर दिया है और मुझे बताया गया है कि इसे नीचे टोन करें, इसीलिए मैंने इसे फिर से पोस्ट किया।
TMS

3
@tomas ओह, ठीक है, मुझे लगता है कि मुझे वही मिलता है जो आपका मतलब है। यह अजीब लगता है कि आप / माइकल इस पर बंद नहीं हो सकते। BTW, इस एक्सचेंज ने मुझे महसूस किया है कि इटैलिक्स <बोल्ड <"ताकत" के मामले में allcaps और यह है कि जबकि allcaps = चिल्ला और italics = politeEmphasis, बोल्ड एक मध्य मैदान में है जहां स्वीकार्यता संदिग्ध है। :-)
पीटर अल्फविन

57

यह संदेश E_STRICTPHP <= 5.3 के लिए है। PHP 5.4 के बाद से, यह अनलक्लीली बदल गया था E_WARNING। चूंकि E_WARNINGसंदेश उपयोगी हैं, आप उन्हें पूरी तरह से अक्षम नहीं करना चाहते हैं।

इस चेतावनी से छुटकारा पाने के लिए, आपको इस कोड का उपयोग करना होगा:

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

$res->success = false;

यह पूरी तरह से समकक्ष प्रतिस्थापन है । यह ठीक उसी चीज का आश्वासन देता है जो PHP चुपचाप कर रहा है - अब चेतावनी के साथ दुर्भाग्यपूर्ण - अंतर्निहित वस्तु निर्माण। आपको हमेशा यह देखना चाहिए कि क्या वस्तु पहले से मौजूद है, जब तक कि आप पूरी तरह से सुनिश्चित नहीं हैं कि यह नहीं है। माइकल द्वारा प्रदान किया गया कोड सामान्य रूप से अच्छा नहीं है, क्योंकि कुछ संदर्भों में ऑब्जेक्ट को कभी-कभी परिस्थितियों के आधार पर कोड में एक ही स्थान पर पहले से ही परिभाषित किया जा सकता है।


2
@carlosvini, यह आपको देगा Undefined variable: res
पचेरियर

1
@Pacerier आप सही हैं, सबसे अच्छा आप जो कर सकते हैं: $ res = isset ($ res)? $ res: नया stdClass (); - यही कारण था कि मैंने 6 महीने पहले E_NOTICE को सक्षम नहीं किया था, क्योंकि यह बहुत खराब है।
कार्लोविनी

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


नया stdClass () को "पुराना" तरीका क्यों माना जाता है? क्या अन्य किसी तरह बेहतर हैं?
आरोन

इसके पुराने php संस्करण से
pirs

मेरे मामले में मेरे $this->route->uri = new stdClass();लिए काम नहीं कर रहा है, मेरे पास अभी भी चेतावनी है। नोट: $this->routeमौजूदा है।
मेलमन

शायद यह php के नए संस्करणों के साथ संगत नहीं है? आपने कौन सा संस्करण इस्तेमाल किया?
पीर

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
@ इसे दबाने से चेतावनियों को रोकता है, ठीक है जब तक आपके पास प्रबंधनीय कोड है। लेकिन अगर आपका कोड कुछ बड़ा हो जाता है और आप किसी समस्या में भाग जाते हैं, तो आपको किसी तरह इसका उपयोग करने पर पछतावा होगा। आप अपने आप को उन सभी "@" के लिए देख रहे होंगे, जिन्हें आप चेतावनी देना चाहते हैं, क्योंकि अस्थायी रूप से इसने अपने उद्देश्य को यह सोचकर परोसा है कि आपने वास्तव में इस मुद्दे को ठीक कर दिया है जब वास्तव में यह आपसे बात कर रहा है और आप बस ' टी सुनो।
विन्सेंट एडवर्ड गडरिया बिनुआ

मैं पहले ही जानता हूँ। यह छोटा और तेज उत्तर है। इसके लिए बहुत सारे समाधान हैं।
कोद्मनिघ

2
बहुत बढ़िया! मैं विनम्रता से असहमत हो सकता हूं, हालांकि त्रुटि को छिपाना वास्तव में समस्या को ठीक नहीं कर रहा है (जैसा कि रामी नस्र ने भी टिप्पणी की थी)।
विंसेंट एडवर्ड गडरिया बिनुआ

यह वर्कअराउंड मेरे लिए केवल 7.2 php पर काम करने वाला है।
मेलमन

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

यह भेजता ARRAY की वस्तुओं बाद में उपयोग के लिए ~!


धन्यवाद!!!! यह वही है जो काम करने में मदद करता है। मुझे PHP को चरण-दर-चरण बताने की आवश्यकता थी कि प्रत्येक तत्व क्या था। मुझे आलसी कोड नहीं याद दिलाने के लिए धन्यवाद।
यानिके

2

इसे इस्तेमाल करे:

ini_set('error_reporting', E_STRICT);

1
धन्यवाद। जब आप थर्ड-पार्टी लाइब्रेरीज़ जैसे कि nusoap का उपयोग कर रहे हों, तो इसका पूरा उपयोग किया जाता है और स्रोत को नहीं बदला जा सकता है। उस स्थिति में आप अन्य स्रोत फ़ाइलों की आवश्यकता से पहले error_reporting को E_STRICT स्तर पर बदल सकते हैं ।
मटोलू

हालाँकि मैंने अपनी समस्या को ठीक करने के लिए इसे केवल nusoap के शीर्ष पर जोड़ा।
badweasel

11
है ना? यहां कोड E_STRICTत्रुटियों को छोड़कर सभी त्रुटि रिपोर्टिंग को निष्क्रिय कर देता है , जिसमें घातक त्रुटियों के लिए संदेशों को दबाने भी शामिल है। यह इस विशेष चेतावनी को हल करने के लिए एक उचित सुझाव नहीं है, और जो कुछ है वह बहुत सुंदर है जो आप कभी नहीं करना चाहते हैं। 5 लोगों ने इसे क्यों उकसाया, मुझे कोई सुराग नहीं है।
मार्क अमेरी सिप

1
यह सुपर खराब है! ini_set('error_reporting', -1);डिबगिंग करते समय उपयोग करें , लेकिन ऊपर का उपयोग न करें, जैसे कभी।
काज़काई

ठीक है, तो आप इसे छिपाकर एक समस्या को ठीक करते हैं? यकीन नहीं होगा कि आपका कोड उम्मीद के
मुताबिक

1

मुझे भी इसी तरह की समस्या थी और यह समस्या का समाधान लगता है। आपको बस एक वर्ग में $ res ऑब्जेक्ट को इनिशियलाइज़ करने की आवश्यकता है। मान लीजिए कि यहां क्लास का नाम टेस्ट है।

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();

एक बार जब आप इसे intialized कर लेते हैं तो आप इसे वस्तुओं के लिए उपयोग कर सकते हैं

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

0

यह समस्या इसलिए होती है क्योंकि आपके द्वारा ऑब्जेक्ट का एक उदाहरण दिया जा रहा है जो आरंभ नहीं हुआ है। उदाहरण के लिए:

आपका मुकदमा:

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

समाधान:

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

क्या आप यह नहीं मान रहे हैं कि वर्ग "उपयोगकर्ता" मौजूद है? यह नहीं हो सकता है और अब यह एक अलग त्रुटि उत्पन्न करेगा?
क्रिस्टोफर थॉमस

1
वास्तव में मैंने उपयोगकर्ता ऑब्जेक्ट का एक उदाहरण नहीं बनाया था, इसलिए मुझे एक त्रुटि मिली। लेकिन एक उदाहरण बनाने के बाद। यह काम किया .. OOPs अवधारणा के साथ इसकी एक सामान्य समस्या :)
बैस्टिन रॉबिन

6
ठीक है, वास्तव में वास्तविक समस्या यह है कि आपका उदाहरण उपयोगकर्ता वर्ग को परिभाषित करने के लिए मानता है, यह वस्तु अभिविन्यास की एक सामान्य समस्या नहीं है, इसकी प्रमुख आवश्यकता है;)
क्रिस्टोफर थॉमस

1
मैं इसके बजाय एक सामान्य "stdClass" लगाता हूँ जो "उपयोगकर्ता" को आधार बना रहा है।
TechNyquist

0

इस त्रुटि को प्राप्त करने का एक सरल तरीका है (ए) नीचे, टाइप करने के लिए (बी)

(ए) $this->my->variable

(ख) $this->my_variable

तुच्छ, लेकिन बहुत आसानी से अनदेखी और अगर आप इसके लिए नहीं देख रहे हैं तो मुश्किल से हाजिर।


यह मूल प्रश्न से कैसे संबंधित है? के बीच कोई मिश्रण-अप नहीं हुआ _और->
Nico Haase

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

एक एपीआई से लौटाए गए ऑब्जेक्ट में एक वैरिएबल जोड़ने की कोशिश करते समय मुझे इसी तरह की समस्या थी। मैं फोर्क लूप वाले डेटा के माध्यम से पुनरावृत्ति कर रहा था।

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

इसने "लारवेल में अपवाद को खाली मान से डिफ़ॉल्ट ऑब्जेक्ट बनाना" कहा।

मैंने इसे बहुत छोटे बदलाव के साथ तय किया।

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

केवल $ डेटा को एक संदर्भ बनाकर।

मुझे आशा है कि यह किसी को मदद करता है यह मेरे से बाहर नरक को परेशान कर रहा था!


0
  1. पहले सोचें कि आपको ऑब्जेक्ट $ res = new \ stdClass () बनाना चाहिए;

  2. फिर कुंजी और मूल्य के साथ ऑब्जेक्ट असाइन करें $ res-> सफलता = गलत;


(मुझे समझ में नहीं आता है thay।) जहां आप कुछ सामग्रियों के बाद एक लाइन ब्रेक चाहते हैं, ब्रेक-टू-होने से पहले लाइन के दृश्य सामग्री में दो रिक्त स्थान संलग्न करें।
ग्रेबर्ड

-1

नहीं, आप नहीं करते हैं। यह तब बनाएंगे जब आप सफलता के मूल्य को ऑब्जेक्ट में जोड़ देंगे। यदि आप एक निर्दिष्ट नहीं करते हैं तो डिफ़ॉल्ट वर्ग को विरासत में मिला है।


4
हालांकि यह सख्त मानकों के संदेश को लौटाएगा ... यह ऑब्जेक्ट को मैन्युअल रूप से पहले बनाने के लिए बस अच्छा अभ्यास है, और जबकि PHP अपेक्षाकृत कमोड कोडिंग अभ्यास के प्रति सहनशील है, आपको चीजों को सही तरीके से अनदेखा नहीं करना चाहिए।
मार्क बेकर

4
समझा गया, मैं सिर्फ एक सरल हां या नहीं के साथ सवाल का जवाब दे रहा था, सर्वोत्तम प्रथाओं को परिभाषित या बचाव नहीं कर रहा :) :)
Silvertiger

-1

प्रयोग करके देखें:

$user = (object) null;

2
आम तौर पर, उत्तर बहुत अधिक सहायक होते हैं यदि वे एक स्पष्टीकरण शामिल करते हैं कि कोड क्या करने का इरादा है, और क्यों वह दूसरों को पेश किए बिना समस्या को हल करता है।
lucascaro

-12

मैंने फॉल्टिंग PHP फ़ाइल के शीर्ष पर निम्नलिखित को रखा और त्रुटि अब प्रदर्शित नहीं हुई:

error_reporting(E_ERROR | E_PARSE);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.