PHP में, क्या आप किसी ऑब्जेक्ट को इंस्टेंट कर सकते हैं और उसी लाइन पर एक विधि कह सकते हैं?


126

मैं क्या करना चाहूंगा कुछ इस तरह है:

$method_result = new Obj()->method();

करने के बजाय:

$obj = new Obj();
$method_result = $obj->method();

परिणाम वास्तव में मेरे विशिष्ट मामले में मेरे लिए मायने नहीं रखता। लेकिन, क्या ऐसा करने का कोई तरीका है?


4
btw, यदि आप 5.4 का उपयोग नहीं कर रहे हैं (जो कि आप शायद नहीं हैं), तो आप एक सहायक फ़ंक्शन को परिभाषित कर सकते हैं, जो केवल चेन सामान पर एक वस्तु देता है ... फ़ंक्शन ($ obj) {$ $ obj के साथ; } (लार्वल से चाल को उठाया: पी) .. तो आप (नई
ओब्ज

BTW, यदि आप अपने आप को अक्सर ऐसा करते हुए पाते हैं, तो इसके लायक है कि my_methodक्या इसके बजाय घोषित किया जाना चाहिए static
टूलमेकरसेव

जवाबों:


166

आपके द्वारा मांगी गई सुविधा PHP 5.4 से उपलब्ध है। यहाँ PHP 5.4 में नई सुविधाओं की सूची दी गई है:

http://php.net/manual/en/migration54.new-features.php

और नई सुविधाओं की सूची से प्रासंगिक हिस्सा:

तात्कालिकता पर वर्ग के सदस्य का उपयोग जोड़ा गया है, उदाहरण के लिए (नया फू) -> बार ()।


9
ध्यान दें कि इसका मतलब यह भी है कि (new Foo)->propertyयदि आप चाहते हैं तो आप कर सकते हैं ।
dave1010

1
ध्यान दें कि आप अभी तक इस तरह से संपत्ति नहीं दे सकते हैं। (नया फू) -> संपत्ति = 'संपत्ति';
CMCDragonkai

7
@CMCDragonkai तार्किक रूप से समझ में आता है; ऑब्जेक्ट केवल कथन की अवधि के लिए मौजूद है (new Foo)->property- आप जो मूल्य संग्रहीत कर रहे हैं वह कहीं नहीं जाना है क्योंकि ऑब्जेक्ट अब मौजूद नहीं होगा क्योंकि यह कहीं भी संग्रहीत नहीं है।
thomasrutter

1
@CMCDragonkai आप इसी को फोन करके गुण इस तरह से प्रदान कर सकते हैं setters , तुम सब करने की जरूरत है जोड़ने के लिए है return $thisअपने setters करने के लिए। यह आपको चेन सेटर करने की भी अनुमति देगा।
iloo

मेरा एक सवाल है। क्या किसी वस्तु को एक अलग लाइन पर घोषित करने और किसी वस्तु को पुन: उपयोग करने में सक्षम होने के अलावा एक चर में सहेजने का कोई लाभ है?
टायलर स्वार्टजेनबर्ग

37

आप वह नहीं कर सकते जो आप पूछ रहे हैं; लेकिन आप "धोखा" दे सकते हैं, इस तथ्य का उपयोग करते हुए कि, PHP में, आपके पास एक फ़ंक्शन हो सकता है जिसका एक वर्ग के समान नाम है; वे नाम संघर्ष नहीं करेंगे।

इसलिए, यदि आपने इस तरह से एक वर्ग घोषित किया है:

class Test {
    public function __construct($param) {
        $this->_var = $param;
    }
    public function myMethod() {
        return $this->_var * 2;
    }
    protected $_var;
}

आप तब एक फ़ंक्शन की घोषणा कर सकते हैं जो उस वर्ग का एक उदाहरण देता है - और कक्षा के समान नाम है:

function Test($param) {
    return new Test($param);
}

और अब, एक-लाइनर का उपयोग करना संभव हो गया है, जैसे कि आपने पूछा - केवल एक चीज है जिसे आप फ़ंक्शन कह रहे हैं, इस प्रकार:

$a = Test(10)->myMethod();
var_dump($a);

और यह काम करता है: यहाँ, मुझे मिल रहा है:

int 20

आउटपुट के रूप में।


और, बेहतर है, आप अपने फ़ंक्शन पर कुछ phpdoc डाल सकते हैं:

/**
 * @return Test
 */
function Test($param) {
    return new Test($param);
}

इस तरह, आपके पास अपने आईडीई में संकेत भी होंगे - कम से कम, ग्रहण पीडीटी 2.x के साथ; देखें:



संपादित करें 2010-11-30: जानकारी के लिए, कुछ दिनों पहले एक नया RFC प्रस्तुत किया गया है, जो इस सुविधा को PHP के भविष्य के संस्करणों में से एक में जोड़ने का प्रस्ताव करता है।

देखें: टिप्पणियों के लिए अनुरोध: इंस्टेंस और विधि कॉल / संपत्ति का उपयोग

तो, शायद इन चीजों को करना PHP 5.4 या किसी अन्य भविष्य के संस्करण में संभव होगा:

(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]

19

पहचान समारोह को परिभाषित करके आप इसे अधिक सार्वभौमिक रूप से कर सकते हैं:

function identity($x) {
    return $x;
}

identity(new Obj)->method();

इस तरह आपको प्रत्येक वर्ग के लिए एक फ़ंक्शन को परिभाषित करने की आवश्यकता नहीं है।


10
अच्छा समाधान क्योंकि यह इस सीमा की मूर्खता पर जोर देता है :)
ओले


16

नहीं, यह संभव नहीं है।
इससे पहले कि आप किसी भी तरीके को कॉल कर सकें, आपको उदाहरण को एक चर में निर्दिष्ट करना होगा।

यदि आप वास्तव में ऐसा नहीं करना चाहते हैं तो आप एक कारखाने का उपयोग कर सकते हैं जैसा कि ropstah बताता है:

class ObjFactory{
  public static function newObj(){
      return new Obj();
  }
}
ObjFactory::newObj()->method();

4
पिम का जवाब सही है। वैकल्पिक रूप से आप स्थैतिक कार्यों का उपयोग कर सकते हैं यदि आप ऑब्जेक्ट का एक उदाहरण बनाना नहीं चाहते हैं
मार्क

इसका उपयोग करते हुए, हम public static functionइसके बजाय उपयोग करने के लिए मजबूर हैं public function। स्थैतिक का उपयोग करने की सिफारिश की जाती है?
इचिमारू

6

आप एक स्थिर फैक्ट्री विधि का उपयोग कर वस्तु का उत्पादन कर सकते हैं:

ObjectFactory::NewObj()->method();

3
एक अलग कारखाने के लिए कोई ज़रूरत नहीं है; एक ही कक्षा में एक स्थिर विधि एक ही बात को पूरा करेगी।
ब्रिलियनड

3

मैं भी, एक प्रारूप से दूसरे प्रारूप में तारीखों को परिवर्तित करने के लिए एक एकल अभिव्यक्ति के भाग के रूप में इसे पूरा करने के लिए एक-लाइनर की तलाश में था। मुझे कोड की एक पंक्ति में ऐसा करना पसंद है क्योंकि यह एक एकल तार्किक ऑपरेशन है। तो, यह थोड़ा गूढ़ है, लेकिन यह आपको एक ही लाइन के भीतर डेट ऑब्जेक्ट का तुरंत उपयोग और उपयोग करने देता है:

$newDateString = ($d = new DateTime('2011-08-30') ? $d->format('F d, Y') : '');

एक तार को एक प्रारूप से दूसरे स्वरूप में परिवर्तित करने का एक और तरीका कोड के OO भागों को प्रबंधित करने के लिए एक सहायक फ़ंक्शन का उपयोग करना है:

function convertDate($oldDateString,$newDateFormatString) {
    $d = new DateTime($oldDateString);
    return $d->format($newDateFormatString);
}

$myNewDate = convertDate($myOldDate,'F d, Y');

मुझे लगता है कि वस्तु उन्मुख दृष्टिकोण शांत और आवश्यक है, लेकिन यह कभी-कभी थकाऊ हो सकता है, सरल ऑपरेशन को पूरा करने के लिए कई चरणों की आवश्यकता होती है।


0

मैं देख रहा हूं कि यह काफी पुराना है क्योंकि प्रश्न यहां हैं लेकिन यहां कुछ ऐसा है जो मुझे लगता है कि उल्लेख किया जाना चाहिए:

विशेष वर्ग विधि जिसे "__call ()" कहा जाता है, का उपयोग किसी कक्षा के अंदर नई वस्तुओं को बनाने के लिए किया जा सकता है। आप इसे इस तरह उपयोग करते हैं:

<?php
class test
{

function __call($func,$args)
{
    echo "I am here - $func\n";
}

}

    $a = new test();
    $a->new( "My new class" );
?>

आउटपुट होना चाहिए:

I am here - new

इस प्रकार, आप PHP को अपने शीर्ष स्तर वर्ग (या वास्तव में किसी भी वर्ग) के अंदर एक "नया" कमांड बनाने में मूर्ख बना सकते हैं और अपने शामिल किए गए आदेश को __call () फ़ंक्शन में उस वर्ग को शामिल करने के लिए रख सकते हैं जिसे आपने पूछा है। बेशक, आप शायद $ फंक का परीक्षण करना चाहेंगे यह सुनिश्चित करने के लिए कि यह एक "नया" कमांड है जिसे __call () कमांड और (निश्चित रूप से) को भेजा गया था, आपके पास अन्य कमांड भी हो सकते हैं क्योंकि __call () कैसे काम करता है।


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