2011-01-26 18 views
5

तोड़कर वहां अपने निर्माता के भीतर ऑब्जेक्ट निर्माण को रोकने के लिए एक तरीका है, ताकि:निर्माता

$object = new Foo(); 
echo $object; // outputs: NULL 
+0

[एनएलएल वापस करने के लिए PHP कन्स्ट्रक्टर का संभावित डुप्लिकेट] (http://stackoverflow.com/questions/2214724/php-constructor-to-return-a-null) –

उत्तर

13

नहीं, संभव नहीं; new कीवर्ड हमेशा निर्दिष्ट वर्ग का एक उदाहरण देता है, इससे कोई फर्क नहीं पड़ता कि आप कन्स्ट्रक्टर से वापस लौटने का प्रयास करते हैं। ऐसा इसलिए है क्योंकि जब तक आपके कन्स्ट्रक्टर को बुलाया जाता है, तो PHP पहले से ही नई ऑब्जेक्ट के लिए स्मृति आवंटित कर चुका है। दूसरे शब्दों में, ऑब्जेक्ट उस बिंदु पर पहले से मौजूद है (अन्यथा, कोई ऑब्जेक्ट नहीं है जिस पर कन्स्ट्रक्टर को कॉल करना है)।

आप त्रुटियों को बढ़ा सकते हैं या इसके बजाय निर्माता से अपवाद फेंक सकते हैं, और तदनुसार उनको संभाल सकते हैं।

class Foo { 
    public function __construct() { 
     throw new Exception('Could not finish constructing'); 
    } 
} 

try { 
    $object = new Foo(); 
} catch (Exception $e) { 
    echo $e->getMessage(); 
} 
+3

@ गॉर्डन: हाँ, मैंने इसे गलत तरीके से गलत किया, धन्यवाद; यह 'नया' कीवर्ड है जो वास्तव में उदाहरण बनाता है; यह इस ऑब्जेक्ट के आवंटन के दौरान है कि PHP मौजूद है तो '__construct()' कॉल करता है। – BoltClock

2

, बस एक अपवाद फेंक:

throw new Exception('thou shalt not be born!'); 
+0

यह ऑब्जेक्ट को होने से नहीं रोक देगा बनाया था। –

+0

अहह! अजीब होने के लिए +1 !! – Tivie

1

आप अपने लिए वस्तु निर्माण करने के लिए एक कारखाने को लागू कर सकते हैं। यदि आप PHP 5.3.0+ का उपयोग कर रहे हैं तो आपके पास लेट स्टेटिक बाध्यकारी नामक एक सुविधा तक पहुंच होगी जो इसे आसान बनाता है।

<?php 
class MyObject 
{ 
    protected $loadSuccess = false; 

    protected function __construct ($foo, $bar, $baz) 
    { 
     // Just a random 50/50 success probability. Put real logic for testing success here 
     $this -> loadSuccess = (mt_rand (0, 99) > 49); 
    } 

    static public function factory ($foo, $bar, $baz) 
    { 
     $objClass = get_called_class(); 
     $obj = new $objClass ($foo, $bar, $baz); 
     if ($obj -> loadSuccess) 
     { 
      return ($obj); 
     } 
    } 
} 

class MySubClass extends MyObject 
{ 
    protected function __construct ($foo, $bar, $baz) 
    { 
     parent::__construct ($foo, $bar, $baz); 
     if ($this -> loadSuccess) 
     { 
      echo ('Hello, I\'m a ' . get_called_class() . '<br>'); 
     } 
    } 
} 

class MySubSubClass extends MySubClass 
{ 
    protected function __construct ($foo, $bar, $baz) 
    { 
     parent::__construct ($foo, $bar, $baz); 
     if ($this -> loadSuccess) 
     { 
      echo ($foo * $bar * $baz . '<br>'); 
     } 
    } 
} 

$o1 = MyObject::factory (1, 2, 3); // Base class 
$o2 = MySubClass::factory (4, 5, 6); // Child class 
$o3 = MySubSubClass::factory(7, 8, 9); // Descendent class 

var_dump ($o1); 
var_dump ($o2); 
var_dump ($o3); 
?> 

आप PHP के संस्करण का उपयोग कर रहे हैं, तो पहले 5.3.0 करने के लिए तो बातें थोड़ा और देर से स्थिर बंधन और get_called_class के रूप में जटिल हो() उपलब्ध नहीं हैं। हालांकि, PHP 5 प्रतिबिंब का समर्थन करता है और आप इसे देर से स्थिर बाध्यकारी अनुकरण करने के लिए उपयोग कर सकते हैं। वैकल्पिक रूप से आप एक अलग फैक्ट्री क्लास को कार्यान्वित कर सकते हैं और यह तर्क दे सकते हैं कि आप किस प्रकार की ऑब्जेक्ट को प्रारंभ करना चाहते हैं।

एक और तरीका यह है कि यदि आपका असफल हो जाता है और इसे कैच ब्लॉक से संभालता है तो एक अपवाद फेंकने के लिए एक और तरीका है। हालांकि यदि आप इसे बहुत कुछ कर रहे हैं तो यह विधि बालों वाली हो सकती है और वास्तव में केवल तब उपयोग किया जाना चाहिए जब आप आम तौर पर ऑब्जेक्ट सृजन को सफल होने की अपेक्षा करते हैं (दूसरे शब्दों में, यदि निर्माण विफलता असाधारण परिस्थिति है)।

कारखाने दृष्टिकोण अतिरिक्त लाभ, उदाहरण के लिए यह वस्तुओं है कि पहले से बनाई गई है और अगर आप एक ही वस्तु दो बार बनाने का प्रयास यह बस आप एक संदर्भ पहले से ही प्रारंभ वस्तु पारित करने के बजाय होगा की एक कैश पकड़ सकता है एक नया निर्माण यह ऑब्जेक्ट सृजन में अंतर्निहित स्मृति और प्रसंस्करण ओवरहेड को समाप्त करता है, विशेष रूप से यदि निर्माण में एक जटिल एसक्यूएल क्वेरी

0

यदि आप किसी ऑब्जेक्ट को कुछ स्थितियों के आधार पर तत्काल से रोकने की कोशिश कर रहे हैं, तो क्यों नहीं बनाते हैं इससे पहले कि आप PHP new पर भी हिट करें और कक्षा को तुरंत चालू करें?

मैं क्या मतलब है, अपने उदाहरण में कहते हैं:

$object = new Foo(); 
echo $object; // outputs: NULL 

आप इसे एक समारोह है कि आप के लिए मान्यता काम करता है या सिर्फ बस एक बयान करता है, तो अगर आप केवल करने वाले वर्ग एक बार का दृष्टांत कर रहे हैं में लपेट कर सकता है ।

इस तरह

:

if(conditions_to_meet){ 
    $object = new Foo(); 
} 
else $object = NULL; 

यदि आप तो है कि कई बार का दृष्टांत एक समारोह में लपेट और अपने वर्ग के लिए पैरामीटर भेजने की जरूरत है।

उम्मीद है कि इससे मदद मिलती है।