PHP: Yeni oluşturulan bir nesnenin üzerine zincir yöntemi nasıl?

6 Cevap php

PHP yeni oluşturulan bir nesne üzerinde zincir yöntemlere bir yolu var olup olmadığını bilmek istiyorum?

Gibi bir şey:

class Foo {
    public function xyz() { ... return $this; }
}

$my_foo = new Foo()->xyz();

Herkes bunu başarmak için bir yol biliyor musun?

6 Cevap

Hayır, kullandığınız zaman

new Classname();

sözdizimi, zincir nesnelleştirilmesi kapalı bir yöntem çağrısı yapamaz. PHP 5.3 'ın sözdizimi bir sınırlama var. Bir nesne örneği sonra, uzak zinciri yapabilirsiniz.

Ben bu almak için kullanılan gördüm bir yöntem bir çeşit statik örnekleme yöntemidir.

class Foo
{
    public function xyz()
    {
        echo "Called","\n";
        return $this;
    }

    static public function instantiate()
    {
        return new self();
    }
}


$a = Foo::instantiate()->xyz();

Statik bir yöntem yeni çağrısını sararak, siz bir yöntem çağrısı ile bir sınıf örneğini, ve bu kapalı zincirine sonra özgürsünüz.

Bu gibi global bir işlev tanımlayın:

function with($object){ return $object; }

Daha sonra aramak mümkün olacak:

with(new Foo)->xyz();

PHP 5.4 'te yapabilirsiniz yeni oluşturulmuş bir nesne kapalı zinciri:

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

PHP'nin eski sürümleri için, Alan Fırtına çözümü kullanabilirsiniz.

Bu cevap demode - bu nedenle onu düzeltmek istiyorum.

PHP 5.4.x yılında yeni bir çağrı için bir yöntem zincir olabilir. Örneğinde olduğu gibi bu sınıf atalım:

<?php class a {
    public function __construct() { echo "Constructed\n"; }
    public function foo() { echo "Foobar'd!\n"; }
}

Şimdi, biz bu kullanabilirsiniz: $b = (new a())->foo();

Ve çıktı:

Constructed
Foobar'd!

Daha fazla bilgi kılavuzda bulunabilir: http://www.php.net/manual/en/migration54.new-features.php

Peki, bu eski bir soru olabilir ama programlama bir çok şey gibi - sonunda cevap değişir.

PHP 5.3 ile ilgili, hayır, sen yapıcısı doğrudan zincir olamaz. Düzgün miras karşılamak amacıyla, ancak kabul edilen yanıt genişletmek için, bunu yapabilirsiniz:

abstract class Foo 
{    
    public static function create() 
    {
        return new static;
    }
}

class Bar extends Foo
{
    public function chain1()
    {
        return $this;
    }

    public function chain2()
    {
        return $this;
    }
}

$bar = Bar::create()->chain1()->chain2();

Bu sadece iyi çalışır ve size yeni bir Bar () örneğini döndürür.

PHP 5.4 ise, basitçe yapabilirsiniz:

$bar = (new Bar)->chain1()->chain2();

Umarım bu ben var gibi soru karşısında tökezleyerek birisi yardımcı olur!

Onlar gelecekteki bir sürümde 'bunu düzeltmek' eğer gerçekten yararlı olacaktır. Gerçekten zincirine yeteneği (koleksiyonlarını yerleştirmek özellikle) takdir:

Ben kapalı zincirleme olabilir (oluşturmak adlandırılan benim çerçevenin taban sınıf) için bir yöntem eklendi. Otomatik olarak tüm alt sınıfları ile çalışması gerekir.

class baseClass
{
    ...
    public final static function create()
    {
        $class = new \ReflectionClass(get_called_class());
        return $class->newInstance(func_get_args());
    }
    ...
    public function __call($method, $args)
    {
        $matches = array();
        if (preg_match('/^(?:Add|Set)(?<prop>.+)/', $method, $matches) > 0)
        {
            //  Magic chaining method
            if (property_exists($this, $matches['prop']) && count($args) > 0)
            {
                $this->$matches['prop'] = $args[0];
                return $this;
            }
        }
    }
    ...
}

Sınıf :: (oluşturmak) -> SetName ('Kris') -> setAge (36);