Object Oriented PHP En İyi Uygulamalar

6 Cevap php

Ben bir kişiyi temsil eden bir sınıf var demek, bu sınıf içinde bir değişken $ isim olurdu.

Daha önce, script'lerime ben sonra sadece kullanarak adını ayarlayın nesnesinin bir örneğini oluşturursunuz:

$object->name = "x";

Ancak, bu iyi bir uygulama değildi söylendi? Ben bir işlev set_name () veya bu gibi benzer bir şey olmalıdır ki:

function set_name($name)
{
    $this->name=$name;
}

Bu doğru mu?

Bu örnekte ben db yeni bir "kişi" kaydı eklemek istiyorsanız, nasıl, kişi yani $ isim, $ yaş, $ adres, sınıfa $ telefon vb eklemek amacıyla ilgili tüm bilgi aktarmak yok Ben yapmalıyım:

function set($data)
{
    $this->name= $data['name'];
    $this->age = $data['age'];
    etc
    etc

}

Sonra ona bir dizi göndermek? Bu en iyi uygulama olurdu? ya da birileri iyi uygulama tavsiye lütfen?

6 Cevap

Yerine, doğrudan onları (diğerleri) arasında aşağıdaki avantajları verir erişim (örneğin gibi set_name için verdi) nesne üzerinde özellikler için açık alıcı ve ayarlayıcıları kullanarak:

  • Herhangi bir dış aramaları değiştirmek zorunda kalmadan 'iç' uygulamasını değiştirebilirsiniz. (Eğer erişim tutarlı bir yolunu sağlamak için) bu şekilde 'dışında' kod öylesine genellikle değişime ihtiyaç duymaz.
  • Siz özellikleri sınıfın dışında çağrılırsa / kullanılmak içindir ki çok açıkça sağlar. Diğer insanların sınıfını kullanarak başlatırsanız, bu çok yararlı olacaktır.

Bu gerçekten necessary bunu olmasa da en iyi uygulama olarak kabul edilebilir (ve bazı kullanımlar için overkill düşünülebilir neden Yukarıdaki nedenler; nesne çok az 'işleme' yapıyor fakat örneğin sadece davranır 'veri' için bir yer tutucu olarak).

Sen setter / alıcı yöntemleri olmalıdır. Onlar bir ağrı vardır ama mutlaka bunları kendiniz yazmak zorunda değilsiniz. Bir IDE (örneğin Eclipse ya da NetBeans) sürece sınıf üyesi sağlamak gibi otomatik olarak sizin için bu üretebilir. Ancak, tüm bu uğraşmak istemiyorsanız ve PHP5 konum, eğer sorunu gidermek için onun sihirli yöntem kullanabilirsiniz:

   protected $_data=array(); 
   public function __call($method, $args) {
        switch (substr($method, 0, 3)) {
            case 'get' :
                $key = strtolower(substr($method,3));
                $data = $this->_data[$key];
                return $data;
                break;
            case 'set' :
                $key = strtolower(substr($method,3));
                $this->_data[$key] = isset($args[0]) ? $args[0] : null;
                return $this;
                break;
            default :
                die("Fatal error: Call to undefined function " . $method);
        }
    } 

Bu kod, bir varolmayan bir yöntem seti ile başlayarak veya almak kullanmak her zaman çalışacaktır. Yani şimdi şöyle / almak (ve dolaylı olarak beyan) değişkenleri ayarlayabilirsiniz:

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

echo $object->getName(); //Outputs Bob
echo $object->getHairColor(); //Outputs Green

No need to declare members or setter/getter functions. If in the future you need to add functionality to a set/get method you simply declare it, essentially overriding the magic method. Also since the setter method returns $this you can chain them like so:

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

hangi yazmak ve okumak kolay hem de kod için yapar.

The only downside to this approach is that it makes your class structure more difficult to discern. Since you're essentially declaring members and methods on run time, you have to dump the object during execution to see what it contains, rather than reading the class. If your class needs to declare a clearly defined interface (because it's a library and/or you want phpdoc to generate the API documentation) I'd strongly advice declaring public facing set/get methods along with the above code.

Ben mükemmel CristopheD katılıyorum (yukarı olarak). Yeni bir person oluştururken Ben sadece iyi bir uygulama eklemek istiyorum.

Genellikle, bir zorunlu alanları kabul etmek, bir kurucu ve isteğe bağlı alanlar için varsayılan değerleri ayarlayın. Gibi bir şey:

class Person
{
  private $name;
  private $surname;
  private $sex;

  // Male is the default sex, in this case
  function Person($name, $surname, $sex='m'){
    $this->name = $name;
    $this->surname = $surname;
    $this->sex = $sex;
  }

  // Getter for name
  function getName()
  {
    return $this->name;
  }

  // Might be needed after a trip to Casablanca
  function setSex($sex)
  {
     $this->sex = $sex;
  }
}

Açıkçası, (seks setter için yinelenen kodunu not) yapıcısındaki pasör yöntemini kullanabilirsiniz.

Tam OOP gitmek için, benzer bir şey yapmak gerekir:

class User {

private $_username;
private $_email;

public function getUsername() {
    return $this->_username;
}
public function setUsername($p) {
    $this->_username = $p;
}
...
public function __construct() {
    $this->setId(-1);
    $this->setUsername("guest");
    $this->setEmail("");
}
public function saveOrUpdate() {
    System::getInstance()->saveOrUpdate($this);
}
}

Eğer bir kullanıcıyı kaydetmek istiyorsanız, sadece bir tane oluşturmak Setters kullanarak değerlerini atamak ve $ user-> saveOrUpdate do (), ve bütün tasarruf mantığı işlemek için başka bir sınıf var.

Lütfen örnek değişken sadece özel kullanım için ise ChristopheD cevabı bir kontrpuan olarak, ben bir alıcı yazma ile rahatsız ve olmaz setter ve sadece örnek değişken özel beyan.

Diğer nesneleri nesneye erişmek için gerekiyorsa, her zaman bir alıcı ekleyebilirsiniz. (Bu, diğer sınıflar gaz giderici tarafından döndürülen nesneyi değiştirmek mümkün olabilir de, başka bir sorunu ortaya çıkarır. Ancak alıcı her zaman copy örnek değişkeni dönmek olabilir.)

Buna ek olarak, bir alıcı / ayarlayıcı kullanarak da other parts of the same class Ben vesileyle çok yararlı buldum kendi uygulanması hakkında bilerek kalkanlar!

Doğrudan erişim ($ kişi-> name) ve erişimci yöntemleri ($ kişi-> getName) iki görüş daha genel bir açıdan bakıldığında zararlı olarak kabul edilir. OOP, nesneleri kendi iç yapısı hakkında herhangi bir bilgi paylaşmak ve sadece kendilerine gönderilen iletileri yürütmek gerekir. Örnek:

// BAD

function drawPerson($person) {
  echo $person->name; // or ->getName(), doesn't matter
}

$me = getPersonFromDB();
drawPerson($me);

// BETTER

class Person ....
   function draw() {
       echo $this->name;
    }

$me = getPersonFromDB();
$me->draw();

Daha fazla okuma: http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html