Ve třídě PHP5, když se soukromý konstruktor zavolá?

hlasů
36

Řekněme, že píšu PHP (> = 5.0) třídu, která je chtěl být ojedinělým. Všechny dokumenty, které jsem četl říci, aby se třída konstruktor soukromý takže třída nemůže být přímo instance.

Takže pokud mám něco takového:

class SillyDB
{
  private function __construct()
  {

  }

  public static function getConnection()
  {

  }
}

Existují případy, kdy __construct () se nazývá jiné, než když dělám

new SillyDB() 

zavolat uvnitř třídy samotné?

A proč mám dovoleno instanci SillyDB zevnitř sebe vůbec?

Položena 25/08/2008 v 15:11
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
61

__construct()by byl nazýván pouze tehdy, pokud volána v rámci metody pro třídu, která obsahuje soukromý konstruktor. Takže pro Singleton, můžete mít metodu, jako je takto:

class DBConnection
{
   private static $Connection = null;

   public static function getConnection()
   {
      if(!isset(self::Connection))
      {
         self::Connection = new DBConnection();
      }
      return self::Connection;
   }

   private function __construct()
   {

   }
}

$dbConnection = DBConnection::getConnection();

Důvod, proč jste schopni / chtěli vytvořit instanci třídy zevnitř je sám o sobě, takže můžete zkontrolovat, aby se ujistil, že pouze jedna instance existuje v daném okamžiku. To je smyslem je Singleton, po tom všem. Použití Singleton pro připojení databáze zajišťuje, že vaše aplikace není dělat tuny spojů DB najednou.

Odpovězeno 25/08/2008 v 15:22
zdroj uživatelem

hlasů
6

Zde je velmi jednoduchý ojedinělým, že právě vytváří datum / čas řetězec:

class TheDate
{
    private static $DateInstance = null;
    private $dateVal;

    public static function getDateInstance()
    {
        if(!isset(self::$DateInstance))
        {
            self::$DateInstance = new TheDate();
        }

        return self::$DateInstance;
    }

    public static function getDateVal()
    {
        return self::$DateInstance->dateVal;
    }

    private function __construct()
    {
        $this->dateVal = strftime("%Y-%m-%d %H:%M:%S");
    }
}

Dělá něco podobného mě samozřejmě dává stejný den znovu a znovu:

$date1 = TheDate::getDateInstance();
echo $date1->getDateVal() . "<br />";

$date2 = TheDate::getDateInstance();
echo $date2->getDateVal() . "<br />";

A dělá to negeneruje žádné chyby:

class NewDate extends TheDate
{
    public function __construct()
    {

    }
}
Odpovězeno 26/08/2008 v 18:41
zdroj uživatelem

hlasů
4

OK, běžel jsem pár testů sám.

  • Pokud nechcete deklarovat svůj vlastní konstruktor do podtřídy, snaží se vytvořit instanci bude hodit fatální chybu, protože se pokouší volat konstruktor nadtřídy.
  • V případě připojení k DB, když jste pravděpodobně vracet (v PHP, stejně) mysqli instance nebo zdroj vrácený mysql_connect()funkcí (nebo nějaký jiný odkaz na nějakou jinou RDBMS), tak dlouho, jak si označit instance soukromé, neexistuje hrozba někoho subclassing ji a manipulaci s odkazem.
  • Jak jsem již zmínil dříve, pokud někdo opravdu chce potlačit své chování a aby více připojení, mohly by stejně dobře to tím, že píše novou třídu.
Odpovězeno 27/08/2008 v 01:04
zdroj uživatelem

hlasů
2

Otestovat kód, značka, a dejte mi vědět, co zjistíte.

EDIT: Také v této konkrétní situaci, nejsem si jistý, proč budete muset dělat starosti s zabránění jakékoliv osobě v subclassing. Má-li někdo přístup k PHP kódu, aby ji podtřídy, pak mají také přístup ke kódu zkopírovat a změnit modifikátory přístupu k něčemu, co oni (z jakéhokoli důvodu) nalézt vhodné.

Praktická užitečnost Singleton v tomto případě je, aby ji používat, můžete zajistit, že budete vždy používat stejné připojení databáze pro daný požadavek HTTP. Dosahuje to. Druhou věcí (s použitím finali soukromé konstruktéři), je užitečné vědět, z pohledu teorie, a ještě více užitečné vědět, pokud chcete distribuovat API kvality kódu pro ostatní programátory, ale v případě tohoto konkrétního příkladu, všechna klíčová slova jsou dělá přidává byty na velikosti vaší třídy souboru.

Odpovězeno 26/08/2008 v 17:37
zdroj uživatelem

hlasů
0

Trochu nit picking: Pro úplnost byste pravděpodobně třídu deklarovat jako konečný příliš, protože byste nechtěli někoho podtříd této třídy a provádí vlastní veřejný konstruktor.

(Odpusťte mi, pokud kompilátor chytí nerespektování soukromého konstruktoru, ale nemyslím si, že to dělá)

Odpovězeno 26/08/2008 v 17:13
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more