পিএইচপি পদ্ধতিতে শৃঙ্খলাবদ্ধ?


170

আমি পিএইচপি 5 ব্যবহার করছি এবং আমি অবজেক্ট-ভিত্তিক পদ্ধতির একটি নতুন বৈশিষ্ট্য পেয়েছি যার নাম 'মেথড চেইনিং'। এটা ঠিক কি? আমি কীভাবে এটি বাস্তবায়ন করব?


1
আমি সর্বাধিক বলব যদি এই সমস্ত প্রশ্নের জবাবদিহি সম্পর্কিত প্রযুক্তি সম্পর্কে না হয় তবে এটি কীভাবে অর্জন করা যায় সে সম্পর্কে এটি বিশেষভাবে।
ক্রিস্টোফার সল-স্টোরগার্ড

@ ক্রিস্টোফার ওপি সহজেই জানতে পারত যে এই প্রশ্নগুলি থেকে এটি কীভাবে অর্জন করা হয়।
গর্ডন

2
ছাড়াও @Kristoffer, অনুসন্ধানের জন্য Google এ পদ্ধতি chaining পিএইচপি ওপি একটি প্রদত্ত যেত টিউটোরিয়াল দ্বারা Salathe প্রথম ফলে। আমি সহজ প্রশ্নের উত্তর দিতে কিছু মনে করি না, তবে কিছু লোক খুব অলস হয়।
গর্ডন

6
আমি আপনার দর্শনের জন্য জমা দিচ্ছি, সিদ্ধান্ত গাছের শৃঙ্খলাবদ্ধ করার চূড়ান্ত পদ্ধতি
rdlowrey

উত্তর:


333

এটি বরং সহজ সরল, আপনার কাছে এমন এক ধারাবাহিক মিউটর পদ্ধতি রয়েছে যা সমস্ত আসল (বা অন্যান্য) অবজেক্টগুলিকে ফেরত দেয়, এইভাবে আপনি ফিরে আসা অবজেক্টে কলিং পদ্ধতিগুলি রাখতে পারবেন।

<?php
class fakeString
{
    private $str;
    function __construct()
    {
        $this->str = "";
    }

    function addA()
    {
        $this->str .= "a";
        return $this;
    }

    function addB()
    {
        $this->str .= "b";
        return $this;
    }

    function getStr()
    {
        return $this->str;
    }
}


$a = new fakeString();


echo $a->addA()->addB()->getStr();

এই ফলাফল "আব"

এটি অনলাইন চেষ্টা করুন!


10
এটিকে মাঝে মাঝে সাবলীল ইন্টারফেস হিসাবেও উল্লেখ করা হয়
নীতেশ চন্দ্র

17
@ নীটেশ যা ভুল। সাবলীল ইন্টারফেসগুলি তাদের প্রাথমিক প্রক্রিয়া হিসাবে মেথড চেইনিং ব্যবহার করে তবে এটি একই নয় । পদ্ধতিতে শৃঙ্খলাবদ্ধভাবে কেবল হোস্ট অবজেক্টটি ফিরিয়ে দেয়, যখন ফ্লুয়েন্ট ইন্টারফেসটি ডিএসএল তৈরির উদ্দেশ্যে হয় । প্রাক্তন: $foo->setBar(1)->setBaz(2)বনাম $table->select()->from('foo')->where('bar = 1')->order('ASC)। পরেরটি একাধিক বস্তু বিস্তৃত হয়।
গর্ডন

3
পাবলিক ফাংশন __to স্ট্রিং () {রিটার্ন $ এই-> স্ট্রিং; You're যদি আপনি ইতিমধ্যে চেইনটি প্রতিধ্বনি করে থাকেন তবে এর জন্য শেষ পদ্ধতি "getStr ()" লাগবে না।
tfont

6
@ টফন্ট সত্য, তবে তারপরে আমরা যাদু পদ্ধতিগুলি প্রবর্তন করছি। একবারে একটি ধারণা যথেষ্ট হওয়া উচিত।
ক্রিস্টোফার সল-স্টোরগার্ড

3
পিএইচপি 5.4 যেহেতু এটি এক লাইনের প্রতিটি কিছুর পক্ষেও সম্ভব :$a = (new fakeString())->addA()->addB()->getStr();
ফিলজেন

48

মূলত, আপনি একটি জিনিস গ্রহণ:

$obj = new ObjectWithChainableMethods();

এমন একটি পদ্ধতি কল করুন যা কার্যকরভাবে return $this;শেষের দিকে একটি করে:

$obj->doSomething();

যেহেতু এটি একই বস্তুটি, বা বরং একই বস্তুর রেফারেন্স দেয়, আপনি একই শ্রেণীর পদ্ধতিগুলি রিটার্ন মান থেকে দূরে রাখতে পারেন, যেমন:

$obj->doSomething()->doSomethingElse();

সত্যিই, এটি। দুটি গুরুত্বপূর্ণ বিষয়:

  1. আপনি নোট হিসাবে, এটি শুধুমাত্র পিএইচপি 5। এটি পিএইচপি 4 এ সঠিকভাবে কাজ করবে না কারণ এটি মান অনুসারে বস্তুগুলি ফিরিয়ে দেয় এবং এর অর্থ আপনি কোনও অবজেক্টের বিভিন্ন অনুলিপিগুলিতে পদ্ধতিগুলি কল করছেন যা আপনার কোডটি ভেঙে দেবে।

  2. আবার, আপনাকে আপনার শৃঙ্খলাবদ্ধ পদ্ধতিতে অবজেক্টটি ফিরিয়ে দিতে হবে:

    public function doSomething() {
        // Do stuff
        return $this;
    }
    
    public function doSomethingElse() {
        // Do more stuff
        return $this;
    }

আপনি return &$thisপিএইচপি 4 এ করতে পারেন ?
অ্যালেক্স

@ অ্যালেক্স: এখনই পরীক্ষার জন্য আমার কাছে পিএইচপি 4 নেই, তবে আমি নিশ্চিত না sure
BoltClock

4
আমিও তাই ভাবিনি, তবে এটি ঠিক কাজ করা উচিত ? সম্ভবত পিএইচপি 4 যদি পিএইচপি 4-ইশ না হত।
অ্যালেক্স


28

এই কোড ব্যবহার করে দেখুন:

<?php
class DBManager
{
    private $selectables = array();
    private $table;
    private $whereClause;
    private $limit;

    public function select() {
        $this->selectables = func_get_args();
        return $this;
    }

    public function from($table) {
        $this->table = $table;
        return $this;
    }

    public function where($where) {
        $this->whereClause = $where;
        return $this;
    }

    public function limit($limit) {
        $this->limit = $limit;
        return $this;
    }

    public function result() {
        $query[] = "SELECT";
        // if the selectables array is empty, select all
        if (empty($this->selectables)) {
            $query[] = "*";  
        }
        // else select according to selectables
        else {
            $query[] = join(', ', $this->selectables);
        }

        $query[] = "FROM";
        $query[] = $this->table;

        if (!empty($this->whereClause)) {
            $query[] = "WHERE";
            $query[] = $this->whereClause;
        }

        if (!empty($this->limit)) {
            $query[] = "LIMIT";
            $query[] = $this->limit;
        }

        return join(' ', $query);
    }
}

// Now to use the class and see how METHOD CHAINING works
// let us instantiate the class DBManager
$testOne = new DBManager();
$testOne->select()->from('users');
echo $testOne->result();
// OR
echo $testOne->select()->from('users')->result();
// both displays: 'SELECT * FROM users'

$testTwo = new DBManager();
$testTwo->select()->from('posts')->where('id > 200')->limit(10);
echo $testTwo->result();
// this displays: 'SELECT * FROM posts WHERE id > 200 LIMIT 10'

$testThree = new DBManager();
$testThree->select(
    'firstname',
    'email',
    'country',
    'city'
)->from('users')->where('id = 2399');
echo $testThree->result();
// this will display:
// 'SELECT firstname, email, country, city FROM users WHERE id = 2399'

?>

1
এটাকেই আমি একটি ভাল ব্যাখ্যা বলি ... শৃঙ্খলাবদ্ধ পদ্ধতিগুলি সর্বদা আমাকে গুজবুব দেয়!
MYNE

আমি কীভাবে চিহ্নিত করব (পদ্ধতির অভ্যন্তরে) শৃঙ্খলে প্রথম এবং শেষ উপাদানগুলি (কল)। কারণ কখনও কখনও এটি এখন ক্রিয়ায় কার্যকর হওয়া অপারেশনগুলির একটি তালিকা, তবে সমস্ত উপাদান সংগ্রহের পরে এমন কিছু করা উচিত। এখানে একটি এসকিউএল কোয়েরি কার্যকর করার মতো - তবে সতর্ক থাকুন, আপনি একটি অবজেক্টে একাধিক চেইন কল করতে পারেন! প্রতিটি মধ্যে মজাদার এবং শেষ।
অ্যান্ডিস

12

পদ্ধতিতে শৃঙ্খলার অর্থ আপনি পদ্ধতি কলগুলি চেইন করতে পারেন:

$object->method1()->method2()->method3()

এর অর্থ হ'ল মেথড 1 () এর কোনও অবজেক্ট ফিরিয়ে দেওয়া দরকার এবং মেথড 2 () মেথড 1 () এর ফলাফল দেওয়া হয়। মেথড 2 () তারপরে রিটার্ন মানটি মেথিট 3 () এ পাস করে।

ভাল নিবন্ধ: http://www.talkphp.com/advanced-php-programming/1163-php5- স্মৃতিচর্চা- html


5
ব্যাখ্যাটি কিছুটা বন্ধ। ফেরতের মানগুলি চারপাশে পাস হয় না। পদ্ধতিগুলি কেবল হোস্ট অবজেক্টকে ফিরিয়ে দেয়।
গর্ডন

@ গর্ডন ওয়েল, হোস্ট অবজেক্টটি ফিরে আসেনি। যে কোনও বস্তু ফেরত এবং শৃঙ্খলিত করা যেতে পারে।
অ্যালেক্সন

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

বাহ, আমি বুঝতে পারি যে আমি প্রায় 8 বছরের পুরানো পোস্টে মন্তব্য করছি .. তবে আপনার যে লিঙ্কটি রয়েছে তা অন্য কোনও ওয়েবসাইটে পুনঃনির্দেশিত করছে। শুধু এফআই।
উইলবিলার

11

স্থির পদ্ধতিতে শৃঙ্খলার জন্য আরেকটি উপায়:

class Maker 
{
    private static $result      = null;
    private static $delimiter   = '.';
    private static $data        = [];

    public static function words($words)
    {
        if( !empty($words) && count($words) )
        {
            foreach ($words as $w)
            {
                self::$data[] = $w;
            }
        }        
        return new static;
    }

    public static function concate($delimiter)
    {
        self::$delimiter = $delimiter;
        foreach (self::$data as $d)
        {
            self::$result .= $d.$delimiter;
        }
        return new static;
    }

    public static function get()
    {
        return rtrim(self::$result, self::$delimiter);
    }    
}

কল করা হচ্ছে

echo Maker::words(['foo', 'bob', 'bar'])->concate('-')->get();

echo "<br />";

echo Maker::words(['foo', 'bob', 'bar'])->concate('>')->get();

6

কোডের 49 টি লাইন রয়েছে যা আপনাকে এই জাতীয় অ্যারেগুলিতে পদ্ধতিগুলি চেইন করতে দেয়:

$fruits = new Arr(array("lemon", "orange", "banana", "apple"));
$fruits->change_key_case(CASE_UPPER)->filter()->walk(function($value,$key) {
     echo $key.': '.$value."\r\n";
});

এই নিবন্ধটি দেখুন যা আপনাকে দেখায় যে কীভাবে পিএইচপি-র সমস্ত সত্তর অ্যারে_ ফাংশনগুলি চেইন করতে হয়।

http://domexception.blogspot.fi/2013/08/php-magic-methods-and-arrayobject.html


5
এটি কোনও সম্ভাব্য উত্তরের সাথে একটি ওয়েবপৃষ্ঠায় লিঙ্ক হিসাবে সত্যই উত্তর নয়।
অবজ্ঞাত

-1

আপনি যদি জাভাস্ক্রিপ্টের মতো পদ্ধতিতে শৃঙ্খলা বোঝাতে চান (বা কিছু লোকেরা jQuery মনে রাখে), তবে কেন কেবল এমন একটি লাইব্রেরি নেওয়া উচিত নয় যা সেই দেবকে নিয়ে আসে। পিএইচপি অভিজ্ঞতা? উদাহরণস্বরূপ অতিরিক্ত - https://dsheiko.github.io/extras/ এটি একটি জাভাস্ক্রিপ্ট এবং আন্ডারস্কোর পদ্ধতি সহ পিএইচপি প্রকারগুলি প্রসারিত করে এবং শৃঙ্খলা সরবরাহ করে:

আপনি একটি নির্দিষ্ট ধরণের চেইন করতে পারেন:

<?php
use \Dsheiko\Extras\Arrays;
// Chain of calls
$res = Arrays::chain([1, 2, 3])
    ->map(function($num){ return $num + 1; })
    ->filter(function($num){ return $num > 1; })
    ->reduce(function($carry, $num){ return $carry + $num; }, 0)
    ->value();

অথবা

<?php
use \Dsheiko\Extras\Strings;
$res = Strings::from( " 12345 " )
            ->replace("/1/", "5")
            ->replace("/2/", "5")
            ->trim()
            ->substr(1, 3)
            ->get();
echo $res; // "534"

বিকল্পভাবে আপনি বহুরূপী যেতে পারেন:

<?php
use \Dsheiko\Extras\Any;

$res = Any::chain(new \ArrayObject([1,2,3]))
    ->toArray() // value is [1,2,3]
    ->map(function($num){ return [ "num" => $num ]; })
    // value is [[ "num" => 1, ..]]
    ->reduce(function($carry, $arr){
        $carry .= $arr["num"];
        return $carry;

    }, "") // value is "123"
    ->replace("/2/", "") // value is "13"
    ->then(function($value){
      if (empty($value)) {
        throw new \Exception("Empty value");
      }
      return $value;
    })
    ->value();
echo $res; // "13"

এটি সত্যই প্রশ্নের উত্তর দেয় না ("পদ্ধতিতে শৃঙ্খলা কী?")) এছাড়াও মূল প্রশ্নটি 8 বছরের পুরানো এবং এরই মধ্যে বেশ কয়েকটি আরও ভাল উত্তর পেয়েছে
GordonM

-1

নীচে আমার মডেল যা ডাটাবেসে আইডি দ্বারা সন্ধান করতে সক্ষম। ($ ডেটা) পদ্ধতিটি সম্পর্কের জন্য আমার অতিরিক্ত পরামিতি তাই আমি return এটি ফিরিয়ে দিই যা নিজেই এটি object আমার নিয়ামকটিতে আমি এটি চেইন করতে সক্ষম।

class JobModel implements JobInterface{

        protected $job;

        public function __construct(Model $job){
            $this->job = $job;
        }

        public function find($id){
            return $this->job->find($id);
        }

        public function with($data=[]){
            $this->job = $this->job->with($params);
            return $this;
        }
}

class JobController{
    protected $job;

    public function __construct(JobModel $job){
        $this->job = $job;
    }

    public function index(){
        // chaining must be in order
        $this->job->with(['data'])->find(1);
    }
}

আপনি কি ব্যাখ্যা করতে পারেন এটি কি করে?
ichimaru

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