PHP ebeveyn / devralma ile Sorunları

8 Cevap php

EDIT: I got this working now. I have updated the code:

Burada birkaç örnek baktım ve hepsi mantıklı görünüyor. Ama işe alınamıyor. Benim Data Access Layer (DAL) genişleten bir sınıf var. Ben DB sonuçlarını almak için üst sınıf aramak istiyorum. Ne yanlış DOIG am?

DAL sınıf

class DAL { 
  protected $username;     // the username for db connect 
  protected $pwd;          // the pwd to use when connecting 
  protected $host;         // the host to which one connects 
  protected $dbname;       // the db to select 
  public $conn;          // reference to the db link resource 
  public $db;            // result of db_select 
  public $query_result;  // the stored result of the last query you ran 

  public function __construct() 
  { 
    $this->username     = ""; 
    $this->pwd          = ""; 
    $this->host         = ""; 
    $this->dbname       = ""; 
  } 

  public function connect() 
  { 
    /* connects to DB here */
  }  

  private function query($sql) 
  {
    /* Executes the query here and stores the result in $this->query_result */
  }

  public function getAllCountries()
  {
    $sql =" 
      SELECT id, name
      FROM country";

    //Process query
    $this->query($sql);

    if($this->query_result)
      return $this->query_result;      
  }
}

Ve bu benim diğer sınıf

class myOtherClass extends DAL{

  public function __construct() {
   parent::__construct();
   parent::connect();
  }

  public function getCountryListBox()
  {
    $result = parent::getAllCountries();

    if($result)
    {
      $selectbox = "<select id='countryListBox' name='countryListBox'>";

      while ($row = mysql_fetch_array($result))
      {
        $selectbox .= "<option value='".($row['id'])."'>".($row['name'])."</option>";
      }
      $selectbox .= "</select>";
    }
    else
      $selectbox = "Countries could not be retrievd from database.";

    return  $selectbox;    
  }  
}

Bu benim şablonunda kodu:

$sl = new myOtherClass();

echo '<form id="label_data_form">';
  $sl->getCountryListBox(); 
echo '</form>';

8 Cevap

Bunların arasındaki fark:

// $result = parent::getAllCountries();  // Like this
$result = this->getAllCountries();       // Or like this?

.. Muhtemelen en iyi burada açıklanmıştır:

class SuperFoo {
    function fubar () {
        echo "superfoo!";
    }

    function fuz () {
        echo "superfuz!";
    }
}

class SubBar extends SuperFoo {
    function fubar() {
        echo "subbar!";
    }

    function demonstrate() {
        $this->fubar();    // "subbar!"
        parent::fubar();   // "superfoo!"

        $this->fuz();      // "superfuz!"
        parent::fuz();     // "superfuz!"
    }
}

$s = new SubBar();
$s->demonstrate();

(Tamam, belki best izah değil ..)

Eğer özellikle üst sınıfında tanımlanmış davranış istediğiniz sürece, ben her zaman $this->... o yana gerekirse davranışı değiştirme seçeneği var kullanmak istiyorum.


MySQL hata SQL ile bir sorun neden gibi görünüyor - sınıf miras iyi çalışıyor görünüyor.

sınıf 'myOtherClass' 'getAllCountries ()' yöntemi uygulamak değilse, aşağıdaki çalışması gerekir:

$result = $this->getAllCountries();

'Bu' önce $ işaretini unutmayın!

bölümü için tüm ülkelerin listesini almak istiyorum:

// $result = parent::getAllCountries();  // Like this
$result = $this->getAllCountries();       // Or like this?

ikinci satır doğrudur. Sizin üst sınıfından devralınan çünkü getAllCountries (), senin nesnesinin bir yöntemdir. böylece ana yöntemini çağırmanız gerekmez. Eğer class ebeveynin yöntemleri çağırmak isterim tek bir yerde yöntemi üzerine yazmasını metodlar vardır.

neyse ben bunun yerine 'özel' bir 'koruma' olarak sizin DAL sınıf içinde özelliklerini tanımlamak öneririz. çünkü 'özel' onları tanımlamak, they can not be inherited.

DAL sınıfında yani:

protected $username;     // the username for db connect 
protected $pwd;          // the pwd to use when connecting 
protected $host;         // the host to which one connects 
protected $dbname;       // the db to select

Eğer bunları miras olmak istemiyorsanız sadece, özel olarak bu özellikleri tanımlamak gerekir. Ben sizin yeni nesne veritabanına bağlanmak için bu bilgileri gerektiğini düşünüyorum.

Steven, bana, doğru yazılmış olmasına rağmen size örnek yanlıştır diğer şeyler, dikkatinizi çizelim. Burada önemli bir konu Sorumluluk ayrım şudur: Data Access Layer sadece yardımcı sınıf depolama / genel amaçlı bir veri almak gibi hareket etmelidir. Herhangi bir ek mantık bu sınıfın dışında hareket ettirilmelidir.

  1. Database connection handling should not be part of DAL. ideal çözüm yapıcısındaki db nesneyi geçmek, bu nedenle DAL başka bir yerde yapılandırılmış bağlantı çalışır. Bu Bağımlılık Enjeksiyon denir ve genellikle iyi bir şey kabul edilir.

  2. Method getAllCountries genel amaçlı kitaplık için yol çok özeldir. Should be replaced with getAll geçerli tablodaki tüm kayıtları dönen. Her tablo karşılık gelen DAL nesnesi vardır ki tablo adı, kurucusuna geçirilen veya alt tanımlanmış olmalıdır.

  3. * Yöntem getCountryListBox DAL kütüphanenin sorumluluğunun bir parçası olmayan bazı HTML çıktısı üretir. DAL should only return raw data.

Bu ayrı şeyler tutmak değer, böylece ileride bunları yeniden kullanabilirsiniz. Çok özel problem uzantı ekleyerek bir sınıfın sorumluluğunu bulanıklaştırır. Bir sınıfın ana hedefleri çok dar görüşlü olmalıdır, yani sınıflar farklı şeyler yapıyor uzmanlaşmak olabilir. Birkaç derece uzmanlaşmış sınıflar arasındaki işbirliği karmaşık işlevleri sunma yolu olmalıdır.

Genel olarak konuşursak, kullanırsınız

$result = $this->getAllCountries();

($ bu daha ziyade bu! Not)

GetAllCountries yöntemin kendisinden başka herhangi bir yerden getAllCountries ararken. Bu geçersiz kılmak olsaydı, overriden yöntemi denilen olacağını sağlayacaktır.

Eğer temel sınıf sürümünü çağırmak istedim yöntemi içinde, size ebeveyn ile görüşmesi disambiguate gerekir ::

parent::getAllCountries();

Eğer herhangi bir yöntemle içindeki yöntem çağrısı bu formu kullanabilirsiniz, ama ben size daha sonra bu yöntemi geçersiz kılmak için fırsat vermez çünkü, varsayılan olarak bu yapmak için kötü bir uygulama olacağını iddia ediyorum unutmayın.

Düzenlemek size cevap?

Another typo:

kodunuzu - (-> yerine) ama bu doğru var sanırım.

Eğer 'myOtherClass' 'storelocator' sınıf olduğundan emin misin?

Eğer storelocator MyOtherClass bir örneği olduğundan emin misiniz? Çünkü getCountryListBox MyOtherClass tanımlanan, ve hata bir tanımlanmamış yöntemlerden getCountryListBox şikayet edilir, aradığınız yöntem ...

<?php $sl = new storelocator(); ?>
<form id="label_data_form">  
<?php $sl->getCountryListBox();  ?>

Update

Sen error handling logic (sorgu içinde ekleyin) ve getAllCountries () gerekmektedir.

Bu-> getAllCountries (); ince olmalıdır, bu bir tür olduğunu sağlanan ve aslında bir dolar ile $ bu, yani geliyordu.

Ben de sorgu () metodu hiçbir şey dönüyor ve böylece $ this-> query_result şey tuttuğunda durumlarda getAllCountries eksik mantığı () işaret etmek istiyorum. ülke DB orada değil durumlar olabilir, çünkü getAllCountries (), boş bir dizi gibi bir şey dönmesi gerekir. Bunu idare edebilmek istiyorum.