পিএইচপি-তে, আপনি কোনও অবজেক্ট ইনস্ট্যান্ট করে একই লাইনে কোনও পদ্ধতিতে কল করতে পারেন?


126

আমি যা করতে চাই তা হ'ল এইরকম:

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

পরিবর্তে করণীয়:

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

ফলাফলটি আমার নির্দিষ্ট ক্ষেত্রে আসলে আমার কাছে আসে না। তবে, এটি করার কোনও উপায় আছে?


4
বিটিডব্লিউ, আপনি যদি 5.4 ব্যবহার করেন না (যা আপনি সম্ভবত নন), আপনি একটি সহায়ক ফাংশন সংজ্ঞায়িত করতে পারেন যা কেবল কোনও বস্তুকে চেইন স্টাফগুলিতে ফিরিয়ে দেয় ... ($ Obj) {return $ اعتراض সহ ফাংশন; } (
লারাভেল থেকে ট্রিকটি তুলেছেন

BTW, যদি আপনি নিজেকে খুঁজে এই প্রায়ই করছেন, তার মূল্য বিবেচনায় কিনা my_methodপরিবর্তে ঘোষণা করা হবে static
নির্মাতা স্টিভ

উত্তর:


166

আপনি যে বৈশিষ্ট্যটির জন্য জিজ্ঞাসা করেছেন তা পিএইচপি 5.4 থেকে পাওয়া যায়। এখানে পিএইচপি 5.4-তে নতুন বৈশিষ্ট্যগুলির তালিকা রয়েছে:

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

এবং নতুন বৈশিষ্ট্য তালিকা থেকে প্রাসঙ্গিক অংশ:

ইনস্ট্যান্টেশনে ক্লাস সদস্যের অ্যাক্সেস যুক্ত করা হয়েছে, যেমন (নতুন ফু) -> বার ()।


9
নোট করুন যে এর অর্থ হ'ল আপনি চাইলে করতে (new Foo)->propertyপারেন।
dave1010

1
মনে রাখবেন আপনি এখনও এইভাবে সম্পত্তি বরাদ্দ করতে পারবেন না। (নতুন ফু) -> সম্পত্তি = 'সম্পত্তি';
সিএমসিডিগ্রাগনকাই

7
@CMCDragonkai যুক্তিযুক্তভাবে এটি বোঝার জন্য; কেবলমাত্র বিবৃতিটির সময়কালের জন্য অবজেক্টটি বিদ্যমান রয়েছে (new Foo)->property- আপনি যে মানটি সংরক্ষণ করছেন তার আর কোথাও নেই কারণ অবজেক্টটির পরে আর কোনও অস্তিত্ব থাকবে না কারণ এটি কোথাও সঞ্চিত নয়।
থোমাসরুটটার

1
@CMCDragonkai আপনি সংশ্লিষ্ট কল করে বৈশিষ্ট্য এই ভাবে ধার্য করতে পারেন setters , সমস্ত আপনাকে যা করতে হবে যোগ হয় return $thisআপনার setters করতে। এটি আপনাকে চেইন সেটটারগুলিতেও অনুমতি দেবে।
iloo

আমার একটা প্রশ্ন আছে. পৃথক লাইনে অবজেক্টটি ঘোষণার মাধ্যমে এবং কোনও ভেরিয়েবলে সংরক্ষণ করার কোনও উপকার আছে কি না, বস্তুটির পুনরায় ব্যবহার করতে সক্ষম হওয়া ছাড়া?
টাইলার স্বার্টজেনবার্গ

37

আপনি যা জিজ্ঞাসা করছেন তা করতে পারবেন না; তবে আপনি "প্রতারণা" করতে পারেন, এই সত্যটি ব্যবহার করে যে পিএইচপি-তে আপনার একটি ফাংশন থাকতে পারে যা ক্লাসের মতো একই নাম রয়েছে; এই নামগুলি বিরোধ করবে না।

সুতরাং, যদি আপনি এটির মতো কোনও শ্রেণি ঘোষণা করেন:

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

এইভাবে, আপনার আইডিইতে ইঙ্গিত থাকবে - কমপক্ষে, গ্রহন পিডিটি ২.x সহ; চিত্রনাট্য দেখুন:



2010-10-30 সম্পাদনা করুন: কেবল তথ্যের জন্য, একটি নতুন আরএফসি জমা দেওয়া হয়েছে, কিছু দিন আগে, পিএইচপি-র ভবিষ্যতের সংস্করণগুলির মধ্যে এই বৈশিষ্ট্যটি যুক্ত করার প্রস্তাব দেয়।

দেখুন: মন্তব্যগুলির জন্য অনুরোধ: তাত্ক্ষণিক এবং পদ্ধতি কল / সম্পত্তি অ্যাক্সেস

সুতরাং, সম্ভবত এই জাতীয় জিনিসগুলি করা 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

না, এটি সম্ভব নয়।
এর যে কোনও পদ্ধতিতে কল করার আগে আপনাকে উদাহরণটি ভেরিয়েবলের কাছে বরাদ্দ করতে হবে।

আপনি যদি সত্যিই এটি করতে না চান তবে আপনি রোপস্টাহর পরামর্শ অনুসারে একটি কারখানা ব্যবহার করতে পারেন:

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

4
পিমের উত্তর সঠিক is অন্যথায় আপনি স্ট্যাটিক ফাংশন ব্যবহার করতে পারে আপনি বস্তুর একটি দৃষ্টান্ত তৈরি করতে চান না হলে
মার্ক

এটি ব্যবহার করে, আমরা public static functionপরিবর্তে ব্যবহার করতে বাধ্য public function। স্ট্যাটিক ব্যবহার করার পরামর্শ দেওয়া হয়?
ichimaru

6

আপনি অবজেক্টটি উত্পাদন করতে একটি স্থির কারখানার পদ্ধতি ব্যবহার করতে পারেন:

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

3
আলাদা কারখানার দরকার নেই; একই ক্লাসে একটি স্ট্যাটিক পদ্ধতি একই জিনিস সম্পাদন করবে।
ব্রিলিয়ান্ড

3

আমিও, তারিখগুলিকে অন্য ফর্ম্যাটে রূপান্তর করার জন্য একক অভিব্যক্তির অংশ হিসাবে এটি সম্পাদন করার জন্য একটি লাইনার সন্ধান করছিলাম। আমি কোডের একক লাইনে এটি করতে পছন্দ করি কারণ এটি একটি একক লজিকাল অপারেশন। সুতরাং এটি সামান্য ক্রিপ্টিক, তবে এটি আপনাকে একক লাইনের মধ্যে তারিখ অবজেক্ট ইনস্ট্যান্ট করতে এবং ব্যবহার করতে দেয়:

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

এক-লাইনের তারিখের স্ট্রিংকে এক ফর্ম্যাট থেকে অন্য রূপরে রূপান্তর করার উপায় হ'ল কোডের ওও অংশগুলি পরিচালনা করতে সহায়ক ফাংশন ব্যবহার করা:

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

সুতরাং, আপনি আপনার শীর্ষ স্তরের শ্রেণীর ভিতরে "নতুন" কমান্ড তৈরি করতে পিএইচপিটিকে বোকা বানাতে পারেন (বা সত্যই যে কোনও শ্রেণি) এবং আপনার অন্তর্ভুক্ত কমান্ডটি __call () ফাংশনটিতে রাখতে চেয়েছিলেন যা আপনি জিজ্ঞাসা করেছেন তা অন্তর্ভুক্ত করতে পারেন। অবশ্যই, আপনি সম্ভবত এটি পরীক্ষা করতে চান যে এটি "নতুন" কমান্ড যা __call () কমান্ডে প্রেরণ করা হয়েছিল এবং (অবশ্যই) আপনার অন্যান্য কমান্ডও থাকতে পারে কারণ এটি __call () কীভাবে কাজ করে।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.