web-dev-qa-db-ja.com

PHPメソッドの連鎖?

私はPHP 5を使用していますが、「メソッドチェーン」と呼ばれるオブジェクト指向アプローチの新機能を聞いたことがあります。正確には何ですか?どうすれば実装できますか?

153
Sanjay Khatri

かなりシンプルで、一連の ミューテーターメソッド があり、すべてが元の(または他の)オブジェクトを返すため、返されたオブジェクトでメソッドを呼び出し続けることができます。

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

これは「ab」を出力します

オンラインで試してみてください!

基本的に、オブジェクトを受け取ります:

$obj = new ObjectWithChainableMethods();

最後にreturn $this;を効果的に実行するメソッドを呼び出します。

$obj->doSomething();

同じオブジェクトを返すので、同じオブジェクトに参照を返すため、次のように戻り値から同じクラスのメソッドを呼び出し続けることができます。

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

本当にそれだけです。 2つの重要なこと:

  1. ご指摘のとおり、PHP 5のみです。 PHP 4では適切に動作しません。値でオブジェクトを返すため、オブジェクトの異なるコピーでメソッドを呼び出しているため、コードが破損する可能性があるためです。

  2. 繰り返しますが、チェーン可能なメソッドでオブジェクトを返す必要があります。

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

このコードを試してください:

<?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'

?>
24
mwangaben

メソッド連鎖とは、メソッド呼び出しを連鎖できることを意味します。

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

つまり、method1()はオブジェクトを返す必要があり、method2()にはmethod1()の結果が与えられます。 Method2()は、戻り値をmethod3()に渡します。

良い記事: http://www.talkphp.com/advanced-php-programming/1163-php5-method-chaining.html

11
alexn

静的メソッド連鎖の別の方法:

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

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

PHPの70個のarray_関数すべてをチェーンする方法を示すこの記事を参照してください。

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

6
Lukas Dong