2012-05-03 27 views
7

Php olarak bir nesne için aynı anda birden çok özellik ayarlamak mümkün mü? Yerine yapmanın :PHP Nesne, birden çok özellik belirleme

$object->prop1 = $something; 
$object->prop2 = $otherthing; 
$object->prop3 = $morethings; 

böyle bir şey yapmak:

$object = (object) array(
    'prop1' => $something, 
    'prop2' => $otherthing, 
    'prop3' => $morethings 
); 

ama nesneyi üzerine yazmadan.

+3

Neden bu şekilde kodun yaptıklarını gizlemek istersiniz? Gelecekte bir noktada (** belki siz **) bu kodu okumalı ve böyle bir şey yapması sadece onu anlamak için daha zor hale getirecektir. – rdlowrey

+0

Bunu neden sadece bir php dosyasına yapıştırıp çalıştırmıyorsunuz? İşe yarayacak mı diye sormak yerine, sadece kendiniz deneyin. – Yoshi

+2

Sadece sizin için bunu yapmak için bir yardımcı işlev oluşturun. Nesne ve dizi içinde geçirin. –

cevap

14

istediğiniz şekilde gibi değil. ancak bu bir döngü kullanılarak yapılabilir.

$map = array(
    'prop1' => $something, 
    'prop2' => $otherthing, 
    'prop3' => $morethings 
); 

foreach($map as $k => $v) 
    $object->$k = $v; 

Sadece 2 ek satırı görün.

+1

2 satır daha değil,% 50 daha fazla satır **; Ayarlanacak yalnızca iki özellik varsa daha da kötüsü. Hile yapmazsak ve hata önleyici “{' ve '}' yi kullanırsak 3 satır olur. – Pacerier

+1

@Pacerier Umarım trolling yaparsınız. Gerçek bir kullanım durumunda, bu tür diziler yüzlerce değeri tutabilirdi. Tabii ki sadece 2 değer verirseniz, ekstra iş çünkü üç satır. Fakat 358 değer içeren bir dizi ile çalışıyorsanız, bu çözüm üç satırda kalır. – Holonaut

+0

@Holonaut, Bu bir trol yorumu değil ciddi bir yorum olması gerekiyordu. Elbette, yüzlerce değerin olduğu durumlarda kullanım durumları vardır, ancak çoğu kullanım durumu sadece iki, üç veya dört değere sahiptir. – Pacerier

4

ben yapmayın öneriyoruz. Cidden, , yapmıyor.

Sizin kodunuz çok daha fazla MUCH temizleyici ilk yoludur, niyetleriniz daha nettir ve kodunuzu, birileri kodunuza bakacak ve "Ne cehennemdi?" salak düşünme "?

açıkça yanlış bir yol bir şey yapmakta ısrar ederse

, her zaman, bir dizi oluşturmak bunu yineleme ve bir döngü içinde bütün özelliklerini ayarlayabilirsiniz. Sana kod vermeyeceğim. Bu kötülük.

+0

Doğru değil. Diğer diller bu sözdizimine sahiptir ve ** temiz kod ** olarak kabul edilir. Bu, ** nasıl ** kullandığınıza bağlıdır. – Pacerier

2

Nesneyi döndürmek nesne için bazı ayarlayıcılar yazabilirsiniz:

public function setSomething($something) 
{ 
$this->something = $something; 
return $this; //this will return the current object 
} 

Ardından yapabilirdi:

$object->setSomething("something") 
     ->setSomethingelse("somethingelse") 
     ->setMoreThings("some more things"); 

Bir __set fonksiyonu olarak her özellik için bir ayarlayıcı yazmak gerekir bir değer döndürme yeteneğine sahip değildir.

Alternatif olarak, tesis => değer dizisi kabul etmek ve her şeyi ayarlamak için tek bir işlevi ayarlamak?

public function setProperties($array) 
{ 
    foreach($array as $property => $value) 
    { 
    $this->{$property} = $value; 
    } 
    return $this; 
} 

ve dizide geçmesine:

$object->setProperties(array('something' => 'someText', 'somethingElse' => 'more text', 'moreThings'=>'a lot more text')); 
+0

"her bir özellik için, bir __set işlevi bir değer döndüremediğinden, her bir özellik için bir yazmacı yazması gerekir". Cevabımın etrafına bir bak. –

8

Sen Object Oriented PHP Best Practices bakmak gerekir:

"ayarlayıcı işlevleri iade beri $ yapabilirsiniz bu yüzden gibi onları zincirle:"

$object->setName('Bob') 
     ->setHairColor('green') 
     ->setAddress('someplace'); 

Bu arada bir fluent interface olarak bilinir. onun türünü kaybeder, böylece

+3

Bu tamamen farklı bir şey. ** değişken özellikler ** oluşturmak için kısayollardan bahsediyor ve cevabınızla ilgisi yok. – Pacerier

+0

Eğer 'public function __set ($ k, $ v) kullanımı hakkında konuşsaydınız {$ this -> $ k = $ v; $ this return;}, sonra * hala * işe yaramaz çünkü çünkü (($ obj-> k = "v") -> k2) = "v2"; 'sözdizimi hatasıdır. – Pacerier

0

Aslında bu yapmazdım .... ama eğlence için ben

$object = (object) ($props + (array) $object); 

sen $ oluşan bir stdClass ile bitirmek kamu özelliklerini nesneleri olur.

+0

Bu, sorunun gereklerini karşılamayan nesneyi geçersiz kılar. '$ object === $ old_object' artık doğru değil. – Pacerier

0

yöntem objectThis() stdClass sınıf dizi özellikleri ya da dizi transtypage için. Doğrudan transtri sayfasını (nesne) kullanmak sayısal dizini kaldıracak, ancak bu yöntemi kullanarak sayısal dizini koruyacaktır.

public function objectThis($array = null) { 
    if (!$array) { 
     foreach ($this as $property_name => $property_values) { 
      if (is_array($property_values) && !empty($property_values)) { 
       $this->{$property_name} = $this->objectThis($property_values); 
      } else if (is_array($property_values) && empty($property_values)) { 
       $this->{$property_name} = new stdClass(); 
      } 
     } 
    } else { 
     $object = new stdClass(); 
     foreach ($array as $index => $values) { 
      if (is_array($values) && empty($values)) { 
       $object->{$index} = new stdClass(); 
      } else if (is_array($values)) { 
       $object->{$index} = $this->objectThis($values); 
      } else if (is_object($values)) { 
       $object->{$index} = $this->objectThis($values); 
      } else { 
       $object->{$index} = $values; 
      } 
     } 
     return $object; 
    } 
} 
+0

kod örneğinden önceki açıklama bazı iyileştirmeler kullanabilir –

0

Ben bu eski bir sorudur farkında ama rastlamak başkalarının yararına, son zamanlarda bu kendim çözmüş ve Açıkçası yerleşik hiçbir önlem vardır sonucu

<?php 
    //Just some setup 
    header('Content-Type: text/plain'); 
    $account = (object) array(
     'email' => 'foo', 
     'dob'=>((object)array(
      'day'=>1, 
      'month'=>1, 
      'year'=>((object)array('century'=>1900,'decade'=>0)) 
     )) 
    ); 
    var_dump($account); 
    echo "\n\n==============\n\n"; 

    //The functions 
    function &getObjRef(&$obj,$prop) { 
     return $obj->{$prop}; 
    } 

    function updateObjFromArray(&$obj,$array){ 
     foreach ($array as $key=>$value) { 
      if(!is_array($value)) 
       $obj->{$key} = $value; 
      else{ 
       $ref = getObjRef($obj,$key); 
       updateObjFromArray($ref,$value); 
      } 
     } 
    } 

    //Test 
    updateObjFromArray($account,array(
     'id' => '123', 
     'email' => '[email protected]', 
     'dob'=>array(
      'day'=>19, 
      'month'=>11, 
      'year'=>array('century'=>1900,'decade'=>80) 
     ) 
    )); 
    var_dump($account); 

paylaşmak istedim Ana uyarısı, updateObjFromArray işlevinin $array içindeki iç içe geçmiş diziler için $obj'daki ilgili anahtarın zaten var olduğunu ve bir nesnenin olduğunu doğrulaması veya bir nesnenin bir hata yapması gibi davranması gerektiği varsayılmaktadır.

Bu yardımcı olur umarız! :)

İlgili konular