"Inline"

5 Cevap php

Yaygın Python ve Ruby gibi OO dillerde kullanılan bir deyim bir nesneyi başlatmasını ve gibi nesnenin kendisi için bir başvuru döndürmek yöntemleri zincirleme edilir:

s = User.new.login.get_db_data.get_session_data

PHP, bu yüzden gibi bu davranışını çoğaltmak mümkündür:

$u = new User();
$s = $u->login()->get_db_data()->get_session_data();

Aşağıdaki sonuçlar girişiminde syntax error, unexpected T_OBJECT_OPERATOR,

$s = new User()->login()->get_db_data()->get_session_data();

Bu amaç için Is there actually a clean, simple way to instantiate PHP classes "inline" (as shown in the above snippet): Bu yaptığım bitireceğiz muhtemelen ne olduğunu, statik yöntemler kullanılarak başarılı olabilir, ama ben lazyweb kontrol etmek istedim gibi görünüyor?

Ben statik yöntemleri kullanmaya karar verirseniz, is it too sorcerous to have a class's static method return an instantiation of the class itself? Bu tür kirli hissediyor (Etkili? Benim kendi yapıcı-ki-değil-bir-kurucu yazma), ama çok korkutucu yan etkileri yok, ben sadece bunu yapabilir.

Ben de bir get_user () yöntemi ile bir UserFactory ön örneğini sanırım, ama ben yukarıda ne sordu çözümler merak ediyorum.

5 Cevap

Bu çözüm önerilerinden Tüm bazı sözdizimsel Incelik gerçekleştirmek için PHP eğmek için kodunuzu zorlaştırıyor. PHP (iyi) gibi olmayan bir şey olmak isteyen çılgınlığa yoludur.

Ben sadece kullanmak istiyorum:

$u = new User();
$s = $u->login()->get_db_data()->get_session_data();

Nispeten kısa, açık ve hiçbir black magic hataları tanıtmak olduğunu içerir.

Ve tabii ki, her zaman Ruby veya Python hareket olabilir. Bu sizin hayatınızı değiştirecek.

  • Ve evet, ben PHP sert duyuyorum. Ben her gün kullanabilirsiniz. Yıllardır kullanıyorum. Gerçekte accreted, yerine tasarlanmış ve göstermesidir.
<?php

    class User
    {
    	function __construct()
    	{
    	}

    	function Login()
    	{
    		return $this;
    	}

    	function GetDbData()
    	{
    		return $this;
    	}

    	function GetSession()
    	{
    		return array("hello" => "world");
    	}
    }

    function Create($name)
    {
    	return new $name();
    }

    $s = Create("User")->Login()->GetDbData()->GetSession();

    var_dump($s);
?>

Bu tabii ki olası bir çözüm :), sen fonksiyon için daha iyi bir isim seçmelisiniz ...

Ya da küçük bir yükü sakıncası yoksa:

<?php

    class User
    {
    	function __construct($test)
    	{
    		echo $test;
    	}
...
    }

    function CreateArgs($name)
    {
    	$ref = new ReflectionClass($name);
    	return $ref->newInstanceArgs(array_slice(func_get_args(), 1));
    }

    $s = CreateArgs("User", "hi")->Login()->GetDbData()->GetSession();

    var_dump($s);
?>

Eğer benzer bir şey alabilirsiniz tek yolu bir fabrika ya da tek statik yöntemi ile. Örneğin:

class User
{
    //...
    /**
     *
     * @return User
     */
    public static function instance()
    {
    	$args = func_get_args();
    	$class = new ReflectionClass(__CLASS__);
    	return $class->newInstanceArgs($args);
    }
    //...
}

Yani (için :: örneğine (gönderilen herhangi argümanlarımdan kullanarak)) yeni bir örneğini oluşturmak için PHP5 yansıma API kullanır ve zincirleme yapmak için izin döndürür:

$s = User::instance()->login()->get_db_data()->get_session_data();

Arada bu kod bu statik yöntemini kopyalarken değiştirmeniz gerekecek tek şey PHPDoc Yorumun @ dönüş olduğu kadar esnektir.


Eğer erken dostumuz Nelson gibi kodunuzu optimize etmek istiyorsanız sizinle Kullanıcı içeriğini :: örneği () değiştirebilirsiniz:

return new self();

Kesmek (sözdizimi soruna geçici çözüm) ve nesne oluşturma kodu kendisi birbirine ayrılmamak için hiçbir neden yok.

Yeni bir ifade nesne operatörünün sol üyesi, ancak bir işlev çağrısı ifadesi olabildiğince kullanılamaz beri, sadece kendi argümanını döndüren bir işlev çağrısı içinde nesneyi kaydırmak gerekir:

function hack($obj) { return $obj; }

$mail = hack(new Zend_Mail())
  -> setBodyText('This is the text of the mail.')
  -> setFrom('somebody@example.com', 'Some Sender')
  -> addTo('somebody_else@example.com', 'Some Recipient')
  -> setSubject('TestSubject');

Basit bir kısayol

$Obj = new ClassName();
$result = $Obj->memberFunction();

olduğunu

$result = (new ClassName())->memberFunction();