PHP Tür Dayatma: dizi desteklenen DEĞİL nesne?

9 Cevap php

Ben bir şey eksik ya da gerçekten PHP 5.x ipucunu genel nesne türü için destek yoktur muyum?

Ben nesneleri ima en azından kutunun dışında, değil ise diziler ima desteklenen bu gerçekten garip buluyorum.

Böyle bir şey var istiyorum:

function foo(object $o)

Sadece bizim gibi:

function foo(array $o)

Kullanılması mümkün Örnek: Bir nesneler toplama sınıfının yöntemleri.

Çözüm: Tüm sınıflar tarafından uygulanan bir arabirim "Nesne" kullanarak ya da genel bir sınıf "Nesne" bütün sınıfları uzanan ve böyle bir şey yazma:

function foo(Object $o)

Eh, o sadece sevimli değil.

Edit: Biri stdclass kullanarak silinmiş yazı önerdi. Bu işe yaramazsa:

Catchable fatal error: Argument 1 passed to c::add() must be an instance of stdClass, instance of b given

9 Cevap

Hayır, bu yapılamaz. Ben bir şey eksik değildi.

Tür Dayatma müşteri kodu API uyum yapmalıdır yana, kabul arayüzleri ile çözüm hemen sağ görünüyor.

Bu açıdan bak: yourMethod(array $input) yourMethod() bir dizi kullanmak, böylece sen de geçerlidir ve yourMethod() tarafından kullanılabilir exactly which native functions biliyorum verir .

Eğer gibi yöntemini belirtirseniz: yourSecondMethod(yourInterface $input) Ayrıca arayüzü eşlik hangi kurallar kümesi arama hangi bilmeniz beri $input uygulanabilir yöntemler / bilirdiniz {[ (2)]}.

Eğer yöntemleri girişi kullanmak için hangi bilmenin bir yolu yok çünkü senin durumunda, herhangi bir nesneyi kabul, yanlış görünüyor. Örnek:

function foo(Object $o) {
    return $o->thisMethodMayOrMayNotExist();
}

(Sözdizimi geçerli olduğunu ima değil)

Bir nesne döküm türü ... Eğer bekliyoruz itiraz HANGİ tanımlamanız gerekir zaman sadece "nesne" diyemeyiz.

Gönderen: http://php.net/manual/en/language.oop5.typehinting.php

class MyClass
{
    /**
     * A test function
     *
     * First parameter must be an object of type OtherClass
     */
    public function test(OtherClass $otherclass) {
        echo $otherclass->var;
    }


    /**
     * Another test function
     *
     * First parameter must be an array
     */
    public function test_array(array $input_array) {
        print_r($input_array);
    }
}

// Another example class
class OtherClass {
    public $var = 'Hello World';
}

Acını hissediyorum, ama ben de bunu yapmanın bir yolunu bulamıyorum.

Diğer posterleri bir dizi söylediler rağmen, bu 'Object' tipi katkısını istemek çok mantıklı; onlar sadece gerektiren bir senaryo dikkate almadım.

Ben yansıma API ile bazı işler yapmak için çalışıyorum ve bundan dolayı benim işlevine geçirilen sınıf umurumda değil. Umurumda bütün bir nesne olmasıdır. Ben bir int, float, bir dize veya bir dizi istemiyorum. Ben bir nesne istiyorum. Bu yansıma şimdi PHP parçası olduğunu göz önüne alındığında, kesinlikle nesne türü katkısını olması mantıklı.

Yerine gerçek bir sınıf adını ipucu olabilir zaman neden object ipucu isterim - bu çok daha yararlı olacaktır. Ayrıca ya int, float, bool, string veya resource ipucu değil unutmayın.

Burada gerekli olan başka bir örnek ...

Ben kayıt kilitleme uygulamak için bir sınıf oluşturduk. Kayıtlar farklı nesne türlerine bir dizi biri olma. Kilitleme sınıfı bir nesne (kilitli olması bir) gerektirir ama o nesnenin ne tür umurumda değil birkaç yöntem vardır.

Örneğin

public static function lockRecord($record, User $user, $timeout=null)
{
    if(!is_object($record)) throw new \InvalidException("Argument 1 must be an object.");

    $lock=new Lock();
    $lock->setRecord($record);
    $lock->setUser($user);
    $lock->setTimeout($timeout);
    $lock->activate();
    return($lock);
}

Sen benim çözüm is_object () kullanın ve bir özel durum için olduğunu görürsünüz, ama Ben çok çok türü yerine ima ile bunu yapmak mümkün olurdu.

Tamam, öyle değil dünyanın sonu, ama bir utanç olduğunu düşünüyorum.

public static function cloneObject($source)
{
    if ($source === null)
    {
        return null;
    }

    return unserialize(serialize($source));
}

Eğer ihtiyacınız olacaktır yerdir.

Her zaman set_error_handler kullanarak bu desteği kesmek olabilir.

Bu uygulamak için en iyi yolu olarak adlandırılan bir dejenere arayüz oluşturmak olacaktır Object. Bir dejenere arayüzü hiçbir tanımlanan yöntemleri anlamına gelir.

interface Object {

   // leave blank

}

Sonra temel sınıflar, sen uygulayabilirsiniz Object.

class SomeBase implements Object {

   // your implementation

}

Eğer istediği gibi artık işlevini çağırabilirsiniz

function myFunc (Object $obj);

myFunc($someBase);

Eğer Object arabiriminden miras alınan her nesneye başarılı olursa, bu tip ipucu geçecek. Bir dizi, int, string vb iletirseniz, tip ipucu başarısız olur.