tipos privados orientado objetos metodos ejemplos constructores clases php oop constructor

privados - En una clase PHP5, ¿cuándo se llama un constructor privado?



php orientado a objetos (5)

Aquí hay un singleton muy simple que solo genera una cadena de fecha / hora:

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"); } }

Hacer algo así obviamente me da la misma fecha una y otra vez:

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

Y hacer esto no genera ningún error:

class NewDate extends TheDate { public function __construct() { } }

Digamos que estoy escribiendo una clase de PHP (> = 5.0) que debe ser un singleton. Todos los documentos que he leído dicen que el constructor de la clase sea privado, por lo que no se puede crear una instancia directa de la clase.

Entonces, si tengo algo así:

class SillyDB { private function __construct() { } public static function getConnection() { } }

¿Hay algún caso en el que __construct () se llame distinto de si estoy haciendo un

new SillyDB()

llamar dentro de la clase en sí?

¿Y por qué puedo instanciar SillyDB desde adentro?


OK, hice algunas pruebas yo mismo.

  • Si no declaras tu propio constructor en la subclase, intentar crear una instancia arrojará un error fatal, porque intenta llamar al constructor de la superclase.
  • En el caso de una conexión DB, cuando presumiblemente regresas (en PHP, de todos modos) una instancia mysqli o el recurso devuelto por la función mysql_connect() (o algún otro enlace a algún otro RDBMS), siempre y cuando marques el instancia privada, no hay amenaza de que alguien lo subclasifique y altere el enlace.
  • Como he mencionado antes, si alguien realmente quiere anular su comportamiento y hacer conexiones múltiples, podría hacerlo escribiendo una nueva clase.

Pruebe el código, Marque, y dígame qué averigua.

EDITAR: Además, en esta situación particular, no estoy seguro de por qué tendrías que preocuparte por evitar que una persona haga subclases. Si alguien tiene acceso a su código PHP para subclasificarlo, entonces también tienen acceso a su código para copiarlo y cambiar los modificadores de acceso a algo que ellos (por cualquier razón) encuentren adecuado.

La utilidad práctica de Singleton en este caso es que, al usarla, puede asegurarse de estar siempre usando la misma conexión de base de datos para una solicitud HTTP dada. Lo logra. Las otras cosas (usando constructores final y privados) es útil saber desde una perspectiva teórica, y aún más útil saber si desea distribuir código de calidad API a otros programadores, pero en el caso de este ejemplo en particular, todas las palabras clave lo que está haciendo es agregar bytes al tamaño de su archivo de clase.


Un pequeño truco: para completar, probablemente declararías la clase como definitiva, ya que no querrías que alguien subclasifique esta clase e implemente su propio constructor público.

(Perdóneme si el compilador detecta la anulación de un constructor privado, pero no creo que lo haga)


__construct() solo se __construct() si lo __construct() desde un método para la clase que contiene el constructor privado. Entonces, para su Singleton, podría tener un método como ese:

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();

La razón por la que puede / querría crear una instancia de la clase desde sí mismo es para que pueda verificar que solo exista una instancia en un momento determinado. Este es el objetivo de un Singleton, después de todo. El uso de un Singleton para una conexión de base de datos garantiza que su aplicación no está haciendo una tonelada de conexiones de base de datos a la vez.