PHP nesneleri nasıl Oyuncular

10 Cevap php

Ive some clases that share some attributes, and i would like to do something like: $dog = (Dog) $cat;

Bu doktorunun veya çevresinde herhangi bir jenerik iş var?

Onun değil bir üst sınıf, ya da bir arabirimi veya herhangi bir şekilde ilgili. Onlar i php bir köpek, bir kedi sınıftan özelliklerini harita ve bana yeni bir nesne vermek istiyorum sadece 2 farklı clases vardır. -

Ben biraz daha fazla nedenini belirlemek için ihave yapmak anlamsız bir şey gibi görünüyor sanırım.

ive clases that inherits from diferents parent clases cause ive made an inheritance tree based on the saving method, maybe my bad from the begining, but the problem is that i have a lot of clases that are practically equal but interacts one with mysql and the otherone with xml files. so i have: class MySql_SomeEntity extends SomeMysqlInteract{} and Xml_SomeEntity extends SomeXmlInteract{} its a little bit deeper tree but the problem its that. i cant make them inherits from the same class cause multimple inheritance is not alowed, and i cant separate current interaction with superclases cause would be a big throuble.

Temel olarak, her birinde atributes aynı pratiktir.

ben bu maching clases çok şey var çünkü i dönüştürür (her özniteliğinde değerleri geçirmek) ve im ama bu clases herkese basit yolu aramak için çalışırken bazı genel döküm ya da bunun gibi bir şey yapmak istiyorum.

10 Cevap

PHP kullanıcı tanımlı nesnelerin türü döküm için yerleşik bir yöntem yoktur. Burada birkaç olası çözüm, şunları kaydetti:

1) onu serisi bir kez ihtiyacınız özelliklerini yeni bir nesne dahil böylece dizeyi değiştirmek, nesnedeki seriyi kaldırmak için aşağıdaki gibi bir işlevi kullanın.

function cast($obj, $to_class) {
  if(class_exists($to_class)) {
    $obj_in = serialize($obj);
    $obj_out = 'O:' . strlen($to_class) . ':"' . $to_class . '":' . substr($obj_in, $obj_in[2] + 7);
    return unserialize($obj_out);
  }
  else
    return false;
}

2) Alternatif olarak, yansıma / elle hepsini yinelenmesi ya get_object_vars () kullanarak kullanarak nesnenin özelliklerini kopya olabilir.

This article "PHP karanlık köşelerinde" sizi aydınlatmak ve kullanıcı düzeyinde isleminden uygulanması gerekir.

Sen (PHP> = 5.3) benzer değil sınıf nesneleri döküm için yukarıdaki fonksiyon kullanabilirsiniz

/**
 * Class casting
 *
 * @param string|object $destination
 * @param object $sourceObject
 * @return object
 */
function cast($destination, $sourceObject)
{
    if (is_string($destination)) {
        $destination = new $destination();
    }
    $sourceReflection = new ReflectionObject($sourceObject);
    $destinationReflection = new ReflectionObject($destination);
    $sourceProperties = $sourceReflection->getProperties();
    foreach ($sourceProperties as $sourceProperty) {
        $sourceProperty->setAccessible(true);
        $name = $sourceProperty->getName();
        $value = $sourceProperty->getValue($sourceObject);
        if ($destinationReflection->hasProperty($name)) {
            $propDest = $destinationReflection->getProperty($name);
            $propDest->setAccessible(true);
            $propDest->setValue($destination,$value);
        } else {
            $destination->$name = $value;
        }
    }
    return $destination;
}

ÖRNEK:

class A 
{
  private $_x;   
}

class B 
{
  public $_x;   
}

$a = new A();
$b = new B();

$x = cast('A',$b);
$x = cast('B',$a);

Eğer bir çözüm arıyorsanız gibi (mentioned by author gibi) devralma kullanmadan, öyle görünüyor ki can başka transform tek sınıf with preassumption of the developer knows and understand the similarity of 2 classes.

Nesneler arasında dönüştürmek için varolan hiçbir çözüm yoktur. Ne deneyebilirsiniz şunlardır:

Sen döküm gerekmez. Her şey dinamiktir.

I have a class Discount.
I have several classes that extends this class:
ProductDiscount
StoreDiscount
ShippingDiscount
...

Somewhere kod var:

$pd = new ProductDiscount();
$pd->setDiscount(5, ProductDiscount::PRODUCT_DISCOUNT_PERCENT);
$pd->setProductId(1);

$this->discounts[] = $pd;

.....

$sd = new StoreDiscount();
$sd->setDiscount(5, StoreDiscount::STORE_DISCOUNT_PERCENT);
$sd->setStoreId(1);

$this->discounts[] = $sd;

Ve bir yerde ben var:

foreach ($this->discounts as $discount){

    if ($discount->getDiscountType()==Discount::DISCOUNT_TYPE_PRODUCT){

        $productDiscount = $discount; // you do not need casting.
        $amount = $productDiscount->getDiscountAmount($this->getItemTotalPrice());
        ...
    }

}// foreach

GetDiscountAmount ProductDiscount belirli bir işlevi olduğunu ve getDiscountType İndirim belirli fonksiyonudur.

Ne gerçekten yapmak istediğiniz uygulamaya bir interface gibi geliyor.

Arayüz nesne işleyebilir yöntemleri belirlemek ve size arabirimini destekleyen bir nesne isteyen bir yönteme arabirimini uygulayan bir nesne geçirdiğinizde, sadece arabirim adı ile argüman yazın.

Ben iyi yaklaşım sadece bir sınıfın yeni bir örneğini oluşturmak ve daha nesne atamak olduğunu düşünüyorum. İşte ben yapardım:

public function ($someVO) {

     $someCastVO = new SomeVO();
     $someCastVO = $someVO;
     $someCastVO->SomePropertyInVO = "123";

}

Bunu yapmak size kodu çoğu IDE ipucu vermek ve doğru özelliklerini kullanarak sağlamak yardımcı olacaktır.

Daha iyi bir yaklaşımın:

class Animal
{
    private $_name = null;

    public function __construct($name = null)
    {
        $this->_name = $name;
    }

    /**
     * casts object
     * @param Animal $to
     * @return Animal
     */
    public function cast($to)
    {
        if ($to instanceof Animal) {
            $to->_name = $this->_name;
        } else {
            throw(new Exception('cant cast ' . get_class($this) . ' to ' . get_class($to)));
        return $to;
    }

    public function getName()
    {
        return $this->_name;
    }
}

class Cat extends Animal
{
    private $_preferedKindOfFish = null;

    public function __construct($name = null, $preferedKindOfFish = null)
    {
        parent::__construct($name);
        $this->_preferedKindOfFish = $preferedKindOfFish;
    }

    /**
     * casts object
     * @param Animal $to
     * @return Animal
     */
    public function cast($to)
    {
        parent::cast($to);
        if ($to instanceof Cat) {
            $to->_preferedKindOfFish = $this->_preferedKindOfFish;
        }
        return $to;
    }

    public function getPreferedKindOfFish()
    {
        return $this->_preferedKindOfFish;
    }
}

class Dog extends Animal
{
    private $_preferedKindOfCat = null;

    public function __construct($name = null, $preferedKindOfCat = null)
    {
        parent::__construct($name);
        $this->_preferedKindOfCat = $preferedKindOfCat;
    }

    /**
     * casts object
     * @param Animal $to
     * @return Animal
     */
    public function cast($to)
    {
        parent::cast($to);
        if ($to instanceof Dog) {
            $to->_preferedKindOfCat = $this->_preferedKindOfCat;
        }
        return $to;
    }

    public function getPreferedKindOfCat()
    {
        return $this->_preferedKindOfCat;
    }
}

$dogs = array(
    new Dog('snoopy', 'vegetarian'),
    new Dog('coyote', 'any'),
);

foreach ($dogs as $dog) {
    $cat = $dog->cast(new Cat());
    echo get_class($cat) . ' - ' . $cat->getName() . "\n";
}

Sen fabrikalar hakkında düşünebilir

class XyFactory {
    public function createXyObject ($other) {
        $new = new XyObject($other->someValue);
        // Do other things, that let $new look like $other (except the used class)
        return $new;
    }
}

Aksi user250120s çözüm sınıf döküm yakın geliyor sadece bir tanesidir.

class It {
    public $a = '';

    public function __construct($a) {
        $this->a = $a;
    }
    public function printIt() {
        ;
    }
}

//contains static function to 'convert' instance of parent It to sub-class instance of Thing

class Thing extends it {
    public $b = '';

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }
    public function printThing() {
        echo $this->a . $this->b;
    }
        //static function housed by target class since trying to create an instance of Thing
    static function thingFromIt(It $it, $b) {
        return new Thing($it->a, $b);
    }
}


//create an instance of It
$it = new It('1');

//create an instance of Thing 
$thing = Thing::thingFromIt($it, '2');


echo 'Class for $it: ' . get_class($it);
echo 'Class for $thing: ' . get_class($thing);

İade:

Class for $it: It
Class for $thing: Thing