Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

PHP 5.2 vs PHP 5.3 parámetros por defecto

Estas en el tema de PHP 5.2 vs PHP 5.3 parámetros por defecto en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola encontré este código en un blog y me llamo mucho la atención y me di a la tarea de implementarlo en un proyecto personal. ...
  #1 (permalink)  
Antiguo 05/05/2010, 14:16
 
Fecha de Ingreso: mayo-2010
Mensajes: 7
Antigüedad: 13 años, 11 meses
Puntos: 0
PHP 5.2 vs PHP 5.3 parámetros por defecto

Hola encontré este código en un blog y me llamo mucho la atención y me di a la tarea de implementarlo en un proyecto personal.

Para ese momento tenia instalado wampserver el cual instala como todos sabemos php5, mysql y apache. Esta versión de wampserver instalaba php 5.2.
Hasta el momento el código me funcionaba muy bien y todo corría correctamente. Luego instale el XAMPP ya que a mi entender brinda mayores prestaciones además de tener la versión de PHP 5.3 y MySQL 5.1.37.

Y entonces comenzaron mis problemas, al parecer los argumentos por defecto en PHP 5.3 se pasan de otra forma.

Código PHP:
Ver original
  1. final class Database
  2. {
  3.     private static $dns       = DNS;
  4.     private static $username  = USERNAME;
  5.     private static $password  = PASSWORD;
  6.     private static $instance;
  7.     private static $PDO;
  8.  
  9.     private function __construct()
  10.     {
  11.     try {
  12.         self::$PDO = new PDO(self::$dns, self::$username, self::$password);
  13.         self::$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  14.     } catch (PDOException $e) {
  15.         echo 'Connection failed: ' . $e->getMessage();
  16.     }
  17.     }
  18.     public static function getInstance()
  19.      {
  20.        if (!isset(self::$instance))
  21.        {
  22.          $c = __CLASS__;
  23.          self::$instance = new $c;
  24.        }
  25.         return self::$instance;
  26.      }
  27.  
  28.     public function query($statement, $PDO = null, $object = null)
  29.     {
  30.         return self::$PDO->query($statement, $PDO, $object);
  31.     }
  32. }
  33.  
  34. $db = Database::getInstance();
  35. $db->query('DESCRIBE `table`');

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: mode must be an integer' in D:\xampp\htdocs\db\Database.php:160 Stack trace: #0 D:\xampp\htdocs\db\Database.php(160): PDO->query('DESCRIBE `table...', NULL, NULL) #1 D:\xampp\htdocs\db\Database.php(393): Database->query('DESCRIBE `table...') #2 {main} thrown in D:\xampp\htdocs\db\Database.php on line 160


No entiendo porque este mismo codigo funciona bien en PHP 5.2 y en PHP 5.3 lanza este error.

Espero que alguno de ustedes me pueda ayudar
  #2 (permalink)  
Antiguo 05/05/2010, 15:12
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

No es un error de los parámetros por defecto, si te fijas el error mismo te lo dice, que el error mode debe de ser un entero, es decir esto:
Código PHP:
Ver original
  1. self::$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

haz lo siguiente:
Código PHP:
Ver original
  1. var_dump(PDO::ERRMODE_EXCEPTION);

Ve que es lo que te sale.

Saludos.
  #3 (permalink)  
Antiguo 05/05/2010, 15:22
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 14 años, 11 meses
Puntos: 1517
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Además hago una observación la forma correcta de declarar static, abstract etc. es
Código PHP:
Ver original
  1. static public function getInstance()
  2. {
  3.  //código
  4. }
Igual también las propiedades
Código PHP:
Ver original
  1. static private $PDO;

Otra observación WAMP tiene la version i que tiene
- Apache 2.2.11
- MySQL 5.1.36
- PHP 5.3.0
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos

Última edición por abimaelrc; 05/05/2010 a las 15:27
  #4 (permalink)  
Antiguo 05/05/2010, 16:15
 
Fecha de Ingreso: mayo-2010
Mensajes: 7
Antigüedad: 13 años, 11 meses
Puntos: 0
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

abimaelrc

Gracias no sabia.

GatorV
Código PHP:
Ver original
  1. var_dump(PDO::ERRMODE_EXCEPTION);

me devolvió un int(3)

Creo que este no es el error.

Salu2
  #5 (permalink)  
Antiguo 05/05/2010, 16:25
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 14 años, 11 meses
Puntos: 1517
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

¿Cuál es la línea 160?
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #6 (permalink)  
Antiguo 05/05/2010, 16:42
 
Fecha de Ingreso: mayo-2010
Mensajes: 7
Antigüedad: 13 años, 11 meses
Puntos: 0
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Código PHP:
Ver original
  1. return self::$PDO->query($statement, $PDO, $object);

Es está la línea le he quitado funcionalidades a la clase para no postearla completa.
  #7 (permalink)  
Antiguo 05/05/2010, 16:43
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Hola. Esta es la descripción del método query() de PDO el cual tiene varias variantes.

Descripción

Código PHP:
Ver original
  1. PDOStatement PDO::query ( string $statement )
  2. PDOStatement PDO::query ( string $statement , int $PDO::FETCH_COLUMN , int $colno )
  3. PDOStatement PDO::query ( string $statement , int $PDO::FETCH_CLASS , string $classname , array $ctorargs )
  4. PDOStatement PDO::query ( string $statement , int $PDO::FETCH_INTO , object $object )

En tu ejemplo utilizas la primera variante, tu metodo query() de la clase Database es un wrapper al verdadero método query() de PDO y estas definiendo los demás parámetros por defecto como null.
  #8 (permalink)  
Antiguo 05/05/2010, 16:57
 
Fecha de Ingreso: mayo-2010
Mensajes: 7
Antigüedad: 13 años, 11 meses
Puntos: 0
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

¿Entonces tendría que programar 3 métodos distintos para cada una de las variantes?

Vuelvo a la pregunta anterior. ¿Porque en PHP 5.2 me funciona bien?
  #9 (permalink)  
Antiguo 05/05/2010, 17:03
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

No, el problema es que estas pasando de forma incorrecta tu función, el problema es que si te fijas, la firma de Query necista un int en su segundo parámetro, si tu pasas null pasa un problema.

PHP5.3 es un poco más estricto que PHP5.2. Podrías hacer algo así:
Código PHP:
Ver original
  1. public function query($statement, $mode = 0, $object = null)

Aunque sí tendrías que hacer el chequeo de cada parámetro.

Por otro lado veo que tu clase solo es un singleton, por lo que podrías buscar otra forma de crearlo, extendiendo de la clase PDO así no tienes que sobrecargar los métodos.

Saludos.
  #10 (permalink)  
Antiguo 05/05/2010, 17:09
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Un ejemplo:
Código PHP:
Ver original
  1. final class Database extends PDO
  2. {
  3.     private static $dns = DNS;
  4.     private static $username = USERNAME;
  5.     private static $password = PASSWORD;
  6.     private static $PDO = null;
  7.    
  8.     public static function getInstance()
  9.     {
  10.         if (!(self::$PDO instanceof PDO)) {
  11.             self::$PDO = new PDO(self::$dns, self::$username, self::$password);
  12.             self::$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  13.         }
  14.         return self::$PDO;
  15.     }
  16. }
  17.  
  18. $db = Database::getInstance();
  19. $db->query('DESCRIBE `table`');
  #11 (permalink)  
Antiguo 05/05/2010, 17:44
 
Fecha de Ingreso: mayo-2010
Mensajes: 7
Antigüedad: 13 años, 11 meses
Puntos: 0
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Muchas gracias atrianaster y GatorV por su ayuda de momento probare a ver si logro dar con la solución.
  #12 (permalink)  
Antiguo 05/05/2010, 17:57
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Cita:
Iniciado por GatorV Ver Mensaje
Por otro lado veo que tu clase solo es un singleton, por lo que podrías buscar otra forma de crearlo, extendiendo de la clase PDO así no tienes que sobrecargar los métodos.
Saludos.
Hola GatorV, muy bien pensado, seria muy buena alternativa aunque “creo que no es posible” manteniendo el ejemplo de Danmichel que su clase es un wrapper. .

Explico, esta clase Database tiene implementado el Patrón Singleton y no puede extender de PDO directamente ya que el constructor de PDO es público y uno de los requisitos del Patrón Singleton, es que el constructor debe ser privado.

Por lo que si intentas extender de esta clase te daría un:

Fatal error: Access level to Database::__construct() must be public (as in class PDO)

Aunque debe existir alguna alternativa.

Última edición por atrianaster; 05/05/2010 a las 18:12
  #13 (permalink)  
Antiguo 05/05/2010, 19:19
Avatar de maturano  
Fecha de Ingreso: enero-2010
Ubicación: /home/
Mensajes: 537
Antigüedad: 14 años, 3 meses
Puntos: 36
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Cita:
Iniciado por atrianaster Ver Mensaje
Hola GatorV, muy bien pensado, seria muy buena alternativa aunque “creo que no es posible” [...]
Tu falta de fé me resulta molesta ...[*]

Código PHP:
Ver original
  1. final class Database extends PDO
  2. {
  3.  
  4.     public function __construct()
  5.     {
  6.         trigger_error('Call to private ' . __CLASS__ . '::__construct() from invalid context', E_USER_ERROR);
  7.     }
  8.  
  9.     static public function getInstance()
  10.     {
  11.         // ...
  12.     }
  13. }

Y supongo igual ayudará un "@access private" en la documentación.



---[*] Espero no tener que explicarlo
__________________
I ♥ The Music!
  #14 (permalink)  
Antiguo 05/05/2010, 23:06
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Matrano al parecer no entendiste nada. Antes de que te vuelvas a molestar, seria bueno que leyeras y analices lo que expuse anteriormente.
No me refería al ejemplo de GatorV , me refería al ejemplo que posteo DanMichel al inicio.

Última edición por atrianaster; 05/05/2010 a las 23:18
  #15 (permalink)  
Antiguo 06/05/2010, 00:06
Avatar de maturano  
Fecha de Ingreso: enero-2010
Ubicación: /home/
Mensajes: 537
Antigüedad: 14 años, 3 meses
Puntos: 36
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Te faltó una "u"; me leo raro.

Confieso: no leí todo el tema. Ahora lo hago y no entiendo la razón de tu reclamo. El tema si no lo he malentendido, se ha llevado así:
- danmichel coloca una clase para el manejo de la conexión a la base de datos teniendo una instancia interna de PDO.
- GatorV hace la observación que no se hace nada más allá de la implementación del patrón singleton. No es necesaria la sobre-escritura de los métodos si solo se va a ser un paso de parámetros hacia PDO. Propone, en su lugar, hacer herencia de PDO.
- Y aquí intervienes diciendo eso --la herencia-- no es posible porque un constructor público, obligado por la herencia, no cumple con el patrón singleton. Te cito (negritas de mi parte).

Cita:
Iniciado por atrianaster Ver Mensaje
Explico, esta clase Database tiene implementado el Patrón Singleton y no puede extender de PDO directamente ya que el constructor de PDO es público y uno de los requisitos del Patrón Singleton, es que el constructor debe ser privado.
Correcta observación... aunque "cerrada". Te propongo ser más flexible con aquello de "el constructor deber ser privado". Lo que importa es controlar el alcance del constructor a manera de impedir se pueda obtener una instancia directa de la clase (por medio de new). Si bien ese control lo obtienes desde el lenguaje declarando el constructor como privado o protegido, igual puedes controlarlo lanzado un error de ejecución (que igual la solución te lo proporciona el lenguaje ).


Con el código que propongo obtienes el mismo comportamiento que si declararas el método como privado, cumpliendo así con "los requisitos del patrón singleton". Hasta el mensaje de error es el mismo; si camina como pato, hace como pato y se ve como pato ...

El único detalle que quedaría es hacer saber ese constructor es privado no es accesible a herramientas como un IDE y/o la generación de la documentación de la API. Para ello, mencioné, debería resolverse con la etiqueta "@access" en el "docblock" correspondiente.


Entonces, ¿en verdad no te entendí?; ¿serías tan amable de explicarme en qué?. ¿O fuiste tú quien no me entendió?; ¿me expliqué mejor ahora? ...

Y sobre la molestia, diré: triste es, una broma explicar.
__________________
I ♥ The Music!

Última edición por maturano; 06/05/2010 a las 00:16 Razón: Que ironía. Estaba llamando privado al constructor...
  #16 (permalink)  
Antiguo 07/05/2010, 02:29
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Ok Matrano , es una broma.

Vamos por parte:

Cita:
Iniciado por maturano Ver Mensaje
- GatorV hace la observación que no se hace nada más allá de la implementación del patrón singleton. No es necesaria la sobre-escritura de los métodos si solo se va a ser un paso de parámetros hacia PDO. Propone, en su lugar, hacer herencia de PDO.
Respeto la opinión de GatorV.

Solo 2 detalles, no seria necesario extender de PDO y que carece de constructor lo cual ya no cumpliría con el Singleton.

Código PHP:
Ver original
  1. final class Database extends PDO
  2.       {
  3.           private static $dns = DNS;
  4.           private static $username = USERNAME;
  5.           private static $password = PASSWORD;
  6.           private static $PDO = null;
  7.          
  8.           public static function getInstance()
  9.           {
  10.               if (!(self::$PDO instanceof PDO)) {
  11.                   self::$PDO = new PDO(self::$dns, self::$username, self::$password);
  12.                   self::$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  13.               }
  14.               return self::$PDO;
  15.           }
  16.       }
  17.        
  18.       $db = Database::getInstance();
  19.       $db->query('DESCRIBE `table`');

Aunque pienso que la clase de Danmichel tiene cierto nivel de abstracción y va más allá de “una sobre-escritura de los métodos”, ya que el método query de la clase Database se abstrae del método query de PDO.

Código PHP:
Ver original
  1. final class Database
  2.       {
  3.           static private  $dns       = DNS;
  4.           static private  $username  = USERNAME;
  5.           static private  $password  = PASSWORD;
  6.           static private  $instance;
  7.           static private  $PDO;
  8.  
  9.           private function __construct()
  10.           {
  11.           try {
  12.               self::$PDO = new PDO(self::$dns, self::$username, self::$password);
  13.               self::$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  14.           } catch (PDOException $e) {
  15.               echo 'Connection failed: ' . $e->getMessage();
  16.           }
  17.           }
  18.           static public function getInstance()
  19.            {
  20.              if (!isset(self::$instance))
  21.              {
  22.                $c = __CLASS__;
  23.                self::$instance = new $c;
  24.              }
  25.               return self::$instance;
  26.            }
  27.  
  28.           public function query($statement, $PDO = null, $object = null)
  29.           {
  30.               return self::$PDO->query($statement, $PDO, $object);
  31.           }
  32.       }
  33.       $db = Database::getInstance();
  34.       $db->query('DESCRIBE `table`');

¿Que inconveniente tendríamos si quisiéramos cambiar la Capa de Abstracción de acceso a la Bases de Datos para utilizar ADODB en vez de PDO?

Supongamos que desarrollamos todo nuestro sistema invocando las propiedades y métodos que nos provee PDO directamente.

Inconvenientes

Estaríamos atados a una implementación concreta, con lo que rompemos con una premisa del Diseño Orientado a Objetos.

Tendríamos que re implementar toda nuestra lógica de negocio donde quiera que hayamos utilizado una propiedad o método pertenecientes a PDO.

- GatorV ¿Que me dices sobre abstraerse de los servicios que proveen las herramientas de abstracción de acceso a Bases de Datos, como Adodb, PDO ...?

Cita:
Iniciado por maturano Ver Mensaje
Correcta observación... aunque "cerrada". Te propongo ser más flexible con aquello de "el constructor deber ser privado". Lo que importa es controlar el alcance del constructor a manera de impedir se pueda obtener una instancia directa de la clase (por medio de new). Si bien ese control lo obtienes desde el lenguaje declarando el constructor como privado o protegido, igual puedes controlarlo lanzado un error de ejecución (que igual la solución te lo proporciona el lenguaje ).

Valida tu propuesta y “buen aporte” pero de esta forma que planteas impedirías por completo la creación de instancias de la clase Database, ya que no se podría crear instancias de la misma ni dentro de la clase ni desde fuera.

Cita:
Iniciado por maturano Ver Mensaje
Entonces, ¿en verdad no te entendí?; ¿serías tan amable de explicarme en qué?.
Me refería manteniendo el mismo ejemplo inicial de Danmichel “que el constructor contiene lógica”.

Última edición por atrianaster; 07/05/2010 a las 02:57
  #17 (permalink)  
Antiguo 07/05/2010, 14:25
Avatar de maturano  
Fecha de Ingreso: enero-2010
Ubicación: /home/
Mensajes: 537
Antigüedad: 14 años, 3 meses
Puntos: 36
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Cita:
Iniciado por atrianaster Ver Mensaje
Solo 2 detalles, no seria necesario extender de PDO y que carece de constructor lo cual ya no cumpliría con el Singleton.
El detalle es que solo es código de ejemplo, solo enfocado en el problema. Así como mi código no implementa el método getInstance(). ¿Que no tiene constructor?, pues se coloca.


Cita:
Iniciado por atrianaster Ver Mensaje
Aunque pienso que la clase de Danmichel tiene cierto nivel de abstracción y va más allá de “una sobre-escritura de los métodos”, ya que el método query de la clase Database se abstrae del método query de PDO.
Y lo único que hace es un paso de argumentos sin más. Aún haciendo herencia puede sobre-escribirse si hubiera más lógica no mostrada aquí.


Cita:
Iniciado por atrianaster Ver Mensaje
Valida tu propuesta y “buen aporte” pero de esta forma que planteas impedirías por completo la creación de instancias de la clase Database, ya que no se podría crear instancias de la misma ni dentro de la clase ni desde fuera.
¿Aún carente de fe? ¿Qué pasa con esa creatividad compañero?. Hablando de implementaciones, capas, patrones, abstracciones ... ¿y ve esta situación imposible?.

Extendiendo PDO, implementando Singleton de la manera estándar salvo la declaración del constructor como público:
Código PHP:
Ver original
  1. class Foo extends PDO
  2. {
  3.     static private $instance;
  4.  
  5.     static private $constructIsPrivate = true;
  6.  
  7.     /**
  8.      * @access private
  9.      */
  10.     public function __construct()
  11.     {
  12.         if (self::$constructIsPrivate) {
  13.             trigger_error('Call to private ' . __CLASS__ . '::__construct() from invalid context', E_USER_ERROR);
  14.         }
  15.  
  16.         echo "Ejecución normal del constructor.\n";
  17.  
  18.     }
  19.  
  20.     public static function getInstance()
  21.     {
  22.         if (!isset(self::$instance)) {
  23.             self::$constructIsPrivate = false;
  24.  
  25.             $c = __CLASS__;
  26.             self::$instance = new $c;
  27.  
  28.             self::$constructIsPrivate = true;
  29.         }
  30.  
  31.         return self::$instance;
  32.     }
  33. }
  34.  
  35. // $obj = new Foo(); >> PHP Fatal error:  Call to private Foo::__construct() from invalid context
  36.  
  37. $obj = Foo::getInstance(); // >> Ejecución normal del constructor.
  38. var_dump($obj); // object(Foo)

Cita:
Iniciado por atrianaster Ver Mensaje
Me refería manteniendo el mismo ejemplo inicial de Danmichel “que el constructor contiene lógica”.
Y, como verás, puede seguir teniéndola. Sí, es posible ...



Cita:
Iniciado por atrianaster Ver Mensaje
¿Que inconveniente tendríamos si quisiéramos cambiar la Capa de Abstracción de acceso a la Bases de Datos para utilizar ADODB en vez de PDO?

Supongamos que desarrollamos todo nuestro sistema invocando las propiedades y métodos que nos provee PDO directamente.

Inconvenientes

Estaríamos atados a una implementación concreta, con lo que rompemos con una premisa del Diseño Orientado a Objetos.

Tendríamos que re implementar toda nuestra lógica de negocio donde quiera que hayamos utilizado una propiedad o método pertenecientes a PDO.

- GatorV ¿Que me dices sobre abstraerse de los servicios que proveen las herramientas de abstracción de acceso a Bases de Datos, como Adodb, PDO ...?
Ajá, ajá, ajá. De acuerdo, de acuerdo, de acuerdo ... pero ¿y si nos enfocamos?. Estamos hablando de una clase en concreto, de un código concreto.

El asunto es, para el código presentado, la herencia es posible, quedando un mejor código y siendo el cambio transparente para quien utilice la clase. Estas últimas intervenciones son porque hiciste una --buena-- observación correcta (no se puede declarar el constructor como privado) y otra errada (sí se puede implementar Singleton con un constructor púbico). Lo demás es solo ruido (no tienes por qué copiar también las actitudes ).


Entonces, ¿convencido?, ¿hay más peros?

Que la fuerza esté contigo.
__________________
I ♥ The Music!

Última edición por maturano; 07/05/2010 a las 14:31
  #18 (permalink)  
Antiguo 09/05/2010, 20:29
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

maturano:

Nunca afirme que no se podía. En cuanto a tu código buen aporte, veo que estuviste haciendo la tarea en casa. Estoy convencido y no hay más peros.

El código quedaría así:

Código PHP:
Ver original
  1. <?php
  2. /**
  3.  * Represents a connection between PHP and a database server
  4.  *
  5.  */
  6. final class Database extends PDO
  7. {
  8.     static private  $dns = DNS;
  9.     static private  $username = USERNAME;
  10.     static private  $passwd = PASSWD;
  11.     static private  $options;
  12.     static private  $instance;
  13.     static private  $constructIsPrivate = true;
  14.  
  15.     /**
  16.      * A private constructor; prevents direct creation of object
  17.      *
  18.      * @access static private
  19.      */
  20.     public function __construct()
  21.     {
  22.       if (self::$constructIsPrivate) {
  23.          trigger_error('Call to private ' . __CLASS__ . '::__construct() from invalid context', E_USER_ERROR);
  24.       }
  25.       try {
  26.            parent::__construct(self::$dns, self::$username, self::$passwd/*, self::$options*/);
  27.            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  28.       } catch (PDOException $e) {
  29.            echo 'Connection failed: ' . $e->getMessage();
  30.       }
  31.     }
  32.  
  33.     /**
  34.      * Create a instance of Database class with The singleton method
  35.      *
  36.      * @access static public
  37.      * @return Database object
  38.      */
  39.      static public function getInstance()
  40.      {
  41.        if (!isset(self::$instance))
  42.        {
  43.          self::$constructIsPrivate = false;
  44.          $c = __CLASS__;
  45.          self::$instance = new $c;
  46.          self::$constructIsPrivate = true;
  47.        }
  48.         return self::$instance;
  49.      }
  50.  
  51.     /**
  52.      * Executes an SQL statement, returning a result set as a PDOStatement object
  53.      *
  54.      * @access public
  55.      * @param  string $statement
  56.      * @param  $PDO
  57.      * @param  object $object
  58.      * @return PDOStatement
  59.      */
  60.      public function query($statement, $PDO, $object)
  61.      {
  62.         return parent::query($statement, $PDO, $object);
  63.      }
  64.  
  65.  
  66.     /**
  67.      * Prevent users to clone the instance
  68.      *
  69.      * @access public
  70.      * @return string trigger_error
  71.      */
  72.     public function __clone()
  73.     {
  74.         trigger_error('Clone is not allowed.', E_USER_ERROR);
  75.     }
  76. }
  77. ?>
  #19 (permalink)  
Antiguo 09/05/2010, 22:31
 
Fecha de Ingreso: mayo-2010
Mensajes: 7
Antigüedad: 13 años, 11 meses
Puntos: 0
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Se aprende mucha POO en Foros del Web, gracias todos, veo que tienen mucha experiencia.

Mi última duda, como podría implementar el método query, que en dependencia de la variante que use invoque al método correspondiente. Pero lo que deseo es centralizarlo todo en el mismo método.

Estas son las variantes disponibles de dicho método:

Código PHP:
Ver original
  1. PDOStatement PDO::query ( string $statement )
  2. PDOStatement PDO::query ( string $statement , int $PDO::FETCH_COLUMN , int $colno )
  3. PDOStatement PDO::query ( string $statement , int $PDO::FETCH_CLASS , string $classname , array $ctorargs )
  4. PDOStatement PDO::query ( string $statement , int $PDO::FETCH_INTO , object $object )

Espero que no sea mucho pedir.
  #20 (permalink)  
Antiguo 10/05/2010, 08:05
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Con la opción que te deje no tienes que re-escribir el método query y puedes usar todas sus variantes. O puedes ver el ejemplo que deje en este post: http://www.forosdelweb.com/f68/numer...on-pdo-804971/

Saludos.

Última edición por GatorV; 10/05/2010 a las 13:50
  #21 (permalink)  
Antiguo 10/05/2010, 17:19
Avatar de maturano  
Fecha de Ingreso: enero-2010
Ubicación: /home/
Mensajes: 537
Antigüedad: 14 años, 3 meses
Puntos: 36
Respuesta: PHP 5.2 vs PHP 5.3 parámetros por defecto

Cita:
Iniciado por danmichel Ver Mensaje
Mi última duda, como podría implementar el método query, que en dependencia de la variante que use invoque al método correspondiente. Pero lo que deseo es centralizarlo todo en el mismo método.
Eso se le conoce como Sobrecarga, por si no lo sabías, para que leas al respecto.

En PHP no es soportada la sobrecarga como en otros lenguajes, tendrías que simularla. La manera común y "documentada" es mediante el método mágico __call(), pero igual lo puedes hacer que un método público (query(), en este tu caso) llame a determinado método privado en función del número de argumentos pasados; esto lo sabrías con la función func_num_args(). En cualquier caso, tendrías que aplicar la lógica por tu cuenta.
www.php.net/__call
www.php.net/func_num_args

Deberías encontrar información al respecto en este mismo foro y en internet en general.


Por otra parte, se te sugirió heredar PDO precisamente para no sobreescribir los métodos si solo van a llamar al mismo método de PDO. Cuando heredas obtienes el mismo comportamiento de la clase padre. si no sobreescribes el método query(), al invocarlo tendrías la misma funcionalidad que con PDO; entendí por eso fue todo el asunto de la herencia.


Si tienes más lógica en tu método, más allá que del simple paso de parámetros, igual considera que podría no ser buena idea aquello de "tener todo centralizado en un solo método". Si el comportamiento va a ser distinto de acuerdo al paso de parámetros, podría ser buena idea hacer clara esa distinción manejando métodos públicos para cada caso. No tengo claro cuál sea tu objetivo, pero suele ser un error común de diseño el que pretendiendo tener una API simple se termine con código complejo, rebuscado, poco reusable y difícil de mantener. Solo, cuidado con ello.

Nuevamente, si tu código es tal cual lo presentas aquí, la sobre-escritura no es necesaria si se implementa la herencia.
__________________
I ♥ The Music!

Etiquetas: defecto, php
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:16.