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

PHP OO ¿Desaconsejado el uso de variables globales?

Estas en el tema de ¿Desaconsejado el uso de variables globales? en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola, hace poco leí en un sitio que el uso de las variables globales no está recomendado porque según decía, cuando el código es grande ...

  #1 (permalink)  
Antiguo 27/06/2012, 09:15
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
¿Desaconsejado el uso de variables globales?

Hola, hace poco leí en un sitio que el uso de las variables globales no está recomendado porque según decía, cuando el código es grande se hace difícil saber de donde viene esa variable y por donde pasó. Así que si cometiéramos un error en alguna parte del código manipulando una variable, generaríamos un error en otra parte, y no sabríamos desde donde se produjo, y que en el caso de POO, viola el principio de encapsulamiento, pues estaríamos permitiendo modificar propiedades internas del objeto desde un lugar externo.

¿Es correcto eso? De ser así ¿Cómo podría utilizar funciones de otras clases sin hacer uso de las globales?
  #2 (permalink)  
Antiguo 27/06/2012, 09:37
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: ¿Desaconsejado el uso de variables globales?

Así es, es totalmente correcto lo que dices.

Pues la forma es instanciando la clase donde necesites, hay muchas formas, la forma más correcta es la inyección de dependencias, es un patrón de desarrollo de Software para POO, que te permite en lugar de hardcodear la dependencia en la clase, inyectarla desde fuera de la clase para que sea usada, por ejemplo:

// no recomendado
Código PHP:
Ver original
  1. class User {
  2.      private $db;
  3.  
  4.      public function __construct() {
  5.              $this->db = new DB(/* Datos *); // hardcoded
  6.              $this->db = Registry::get('db'); // vía registro (no recomendado tampoco)
  7.      }
  8. }
  9.  
  10. $user = new User();
  11. $user->algo();

// recomendado
Código PHP:
Ver original
  1. class User {
  2.        private $db;
  3.  
  4.        public function setDb(DBInterface $db) { $this->db = $db; }
  5.        public function getDb() { return $this->db; }
  6. }
  7.  
  8. // en otro file donde hagas el setup
  9. $db = new Db(/* datos */);
  10. $user = new User();
  11. $user->setDb($db);
  12.  
  13. // Donde uses $user
  14. $user->algo();

Todo eso se puede automatizar usando un Dependency Container que te permite "auto conectar" los objetos dependiendo de un registro de dependencias, es la forma más correcta actualmente para manejar las dependencias en Software.

Saludos.
  #3 (permalink)  
Antiguo 27/06/2012, 10:41
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
Así es, es totalmente correcto lo que dices.

Pues la forma es instanciando la clase donde necesites, hay muchas formas, la forma más correcta es la inyección de dependencias, es un patrón de desarrollo de Software para POO, que te permite en lugar de hardcodear la dependencia en la clase, inyectarla desde fuera de la clase para que sea usada, por ejemplo:

// recomendado
Código PHP:
Ver original
  1. class User {
  2.        private $db;
  3.  
  4.        public function setDb(DBInterface $db) { $this->db = $db; }
  5.        public function getDb() { return $this->db; }
  6. }
  7.  
  8. // en otro file donde hagas el setup
  9. $db = new Db(/* datos */);
  10. $user = new User();
  11. $user->setDb($db);
  12.  
  13. // Donde uses $user
  14. $user->algo();

Todo eso se puede automatizar usando un Dependency Container que te permite "auto conectar" los objetos dependiendo de un registro de dependencias, es la forma más correcta actualmente para manejar las dependencias en Software.

Saludos.
Gracias por contestar. Imagino que tengo que realizar el "include" de las clases que utilizaría en el otro archivo, donde definiría la bd. Si fuera el caso, imagino que si tuviera muchas clases el consumo sería grande. He tenido varios percances, y por eso si tuvieras un poco de tiempo para dedicarme a mí y a los que también tengan esta duda, ¿podrías crear los tres archivos para saber cómo quedaría? Es decir, dos clases (básicas, aunque solo muestre Hola mundo) y un archivo de configuración también básico (en mi caso uso mysqli), para saber dónde iría el "include" siendo más de una clase y cómo se gestionaría, ya que hasta ahora yo siempre había usado globales y así de pronto instanciarlas de una forma que desconocía, me viene desconcertando. De esta forma me guiaría y ya podría realizarlo con otras clases que tuviera. Gracias por adelantado, si no pudieras hoy, no importa, pero me gustaría saberlo.
  #4 (permalink)  
Antiguo 27/06/2012, 11: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: ¿Desaconsejado el uso de variables globales?

El include ya no se recomienda, ya se estandarizo el uso de la nomenclatura PSR-0 para las clases y usar un Autoloader para la carga de clases.

Puedes usar algo simple como Pimple que es un container que maneja todas las dependencias, casos y más avanzados pues depende del framework que uses.

Saludos.
  #5 (permalink)  
Antiguo 27/06/2012, 11:25
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
El include ya no se recomienda, ya se estandarizo el uso de la nomenclatura [URL="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md"]PSR-0[/URL] para las clases y usar un Autoloader para la carga de clases.

Puedes usar algo simple como [URL="http://pimple.sensiolabs.org/"]Pimple[/URL] que es un container que maneja todas las dependencias, casos y más avanzados pues depende del framework que uses.

Saludos.
Entonces sin el uso de un Dependency Container no es posible a menos que se usen globales? Actualmente no estoy usando ningún framework ni librerías externas más que poo nativo, ya que no me siento cómodo usándolos.
  #6 (permalink)  
Antiguo 27/06/2012, 11:45
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: ¿Desaconsejado el uso de variables globales?

No, no es necesario un container, es solo que ayuda a la hora de configurar tu objeto ya que te evitas estar construyendo las dependencias que necesita tu clase para funcionar, solamente es que configures bien el container y listo.

Puedes hacerlo directo, pero recuerda que PHP por defecto no es un lenguaje 100% Orientado a Objetos, por lo que siempre tienes que adoptar algún patrón de diseño para organizar tu proyecto, y depende del patrón que uses debes de tener alguna parte donde hagas el "setup" o "bootstrap" de tu proyecto ahí es donde configuras e inyectas las cosas a tus objetos que necesites (donde haces el manejo de dependencia).

Como es una tarea complicada, por eso fue que te proporcioné el link de Pimple, ya que es un Container bastante simple que solamente necesitas configurar bien y usarlo para obtener instancias de tus clases.

Saludos.
  #7 (permalink)  
Antiguo 27/06/2012, 11:46
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: ¿Desaconsejado el uso de variables globales?

También te recomiendo este link, habla muy bien del tema: http://fabien.potencier.org/article/...ency-injection
  #8 (permalink)  
Antiguo 27/06/2012, 13:08
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
También te recomiendo este link, habla muy bien del tema: [url]http://fabien.potencier.org/article/11/what-is-dependency-injection[/url]
Algo no me quedó claro. Esos archivos que descargué del primer enlace, es una demo de como se hace o son funciones que se necesitan integrar en el proyecto? No lo entiendo muy bien, es la primera vez que escucho lo de las inyecciones de dependencia de este modo. De todas formas voy a leer ese segundo enlace que me has pasado a ver si me aclaro un poco. Gracias de nuevo.
  #9 (permalink)  
Antiguo 27/06/2012, 15:27
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: ¿Desaconsejado el uso de variables globales?

¿hablas de Pimple? es un simple contenedor, su uso es simple, solamente lo incluyes y lo configuras y listo, usas Pimple en lugar de new Class.

Saludos.
  #10 (permalink)  
Antiguo 27/06/2012, 19:00
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
¿hablas de Pimple? es un simple contenedor, su uso es simple, solamente lo incluyes y lo configuras y listo, usas Pimple en lugar de new Class.

Saludos.
Mi idea es seguir usando new "Class" sin necesidad de frameworks ni contenedores... pero no usar globales. ¿Es posible?
  #11 (permalink)  
Antiguo 27/06/2012, 19:25
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: ¿Desaconsejado el uso de variables globales?

No entiendo muy bien donde tienes el problema, simplemente no utilices variables globales.
__________________
http://es.phptherightway.com/
thats us riders :)
  #12 (permalink)  
Antiguo 27/06/2012, 19:28
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por masterpuppet Ver Mensaje
No entiendo muy bien donde tienes el problema, simplemente no utilices variables globales.
Pues el problema está, en que si no uso las variables globales, ¿qué hago para llamar una función de otra clase? Si por ejemplo tengo dos clases, una de usuarios y otra de notas, y la información del usuario está en una función llamada "info", tendría que llamar a $user->info('algo'); ... pero si no hay globales u otra cosa (y "otra cosa" es lo que quiero saber, ya que desconozco otras posibilidades a globales), no podría hacer eso desde la clase "notas". ¿Me explico?
  #13 (permalink)  
Antiguo 28/06/2012, 09:08
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: ¿Desaconsejado el uso de variables globales?

Ya te dije tendrías que hardcoder la dependencia en tu clase (o usar inyección de dependencias), ya que veo que no tienes ganas de aprender, solamente hardcodea la dependencia:

Código PHP:
Ver original
  1. class Notes {
  2.        public function getNotesForUser($id) {
  3.                 $User = new User($id);
  4.                
  5.                 return $User->getNotes();
  6.        }
  7. }

Saludos.
  #14 (permalink)  
Antiguo 28/06/2012, 09:13
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
Ya te dije tendrías que hardcoder la dependencia en tu clase (o usar inyección de dependencias), ya que veo que no tienes ganas de aprender, solamente hardcodea la dependencia:

Código PHP:
Ver original
  1. class Notes {
  2.        public function getNotesForUser($id) {
  3.                 $User = new User($id);
  4.                
  5.                 return $User->getNotes();
  6.        }
  7. }

Saludos.
Sí que quiero aprender lo que no sepa y mejorar lo que ya sé, no veo lógica a lo contrario. Pero por ejemplo, en el mensaje que cito no dices nada de cómo se conecta una clase con otra, a menos que haga un include, ¿cómo la clase va a ser que new User es una clase existente y dónde está? Hay cosas que no las comprendo. De todas formas gracias, buscaré en Google (aunque ya lo hice y nada apto) más sobre "hardcoder", porque lo de la inyección de dependencias no lo comprendo según los enlaces que pasaste, ya que no eran para este lenguaje.
  #15 (permalink)  
Antiguo 28/06/2012, 09:35
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: ¿Desaconsejado el uso de variables globales?

Claro que son de PHP, los dos que te dejé, y ya te dije más arriba, debes de usar un Autoloader para evitar los includes, realmente haces que repita lo que te digo, puedes usar un Autoloader de los que hay o el que trae PHP de forma nativa: spl_autoload_register

Eso hace que te evites hacer un include() antes de hacer el new Class, ya que el autoloader lo que hace es eso, cargar las clases que no han sido definidas.

Cuando programes en PHPOO, sea o no con MVC, debes de usar siempre un Autoloader para evitar estar haciendo includes.

Saludos.
  #16 (permalink)  
Antiguo 28/06/2012, 10:12
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
Claro que son de PHP, los dos que te dejé, y ya te dije más arriba, debes de usar un Autoloader para evitar los includes, realmente haces que repita lo que te digo, puedes usar un Autoloader de los que hay o el que trae PHP de forma nativa: [URL="http://mx2.php.net/manual/en/function.spl-autoload-register.php"]spl_autoload_register[/URL]

Eso hace que te evites hacer un include() antes de hacer el new Class, ya que el autoloader lo que hace es eso, cargar las clases que no han sido definidas.

Cuando programes en PHPOO, sea o no con MVC, debes de usar siempre un Autoloader para evitar estar haciendo includes.

Saludos.
Entonces poniendo algo como:

Código PHP:
Ver original
  1. spl_autoload_register(function ($clase) {
  2.     include(dirname(__FILE__) . '/classes/' . $clase . '.php');
  3. });

Y luego dentro de la clase lo que me comentaste ayer:

Código PHP:
Ver original
  1. Class User
  2. {
  3.     private $db;
  4.    
  5.     public function setDB(DBInterface $db)
  6.     {
  7.         $this->db = $db;
  8.     }
  9.     public function getDb()
  10.     {
  11.         return $this->db;
  12.     }
  13. }

¿Y si quiero agregar más clases en esa misma?

Por ejemplo, si quiero usar dentro de la clase user, las configuraciones que sería la clase core y una clase de seguridad por ejemplo. ¿Cómo sería? Poner private $core (que sería "$core = new Core" en el archivo donde se cargarían) y lo mismo para la otra de seguridad. Pero ¿ya podría usar $core y $security en las funciones de la clase user sin las globales o habría que hacer algo más? Aunque creo que esto es sólo para evitar todos includes, pero me he liado un poco.

Otra duda más, ¿spl_autoload_register() al cargar todas las clases que se encuentren no consumiría más que algunos includes dependiendo de un "if" (si voy al registro, cargo las del registro y no una clase de administración, por ejemplo)?


Gracias.

Última edición por salomon26; 28/06/2012 a las 10:32
  #17 (permalink)  
Antiguo 28/06/2012, 10:50
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: ¿Desaconsejado el uso de variables globales?

El autoloader lo único que hace es evitar que tengas que hacer un include() para traer la definición de la clase y la puedas incluir sin que se genere un error.

Respecto a agregar más clases, para eso es el autoloader, puedes instanciar las clases que quieras y se van a incluir siempre y cuando tengan la misma estructura de nomenclaturas / carpetas, por ejemplo:

Código PHP:
Ver original
  1. class Foo {
  2.       public function bar() {
  3.                 $foobar = new Foobar();
  4.                 $baz = new Baz();
  5.                 $foofoo = new Foofoo();
  6.       }
  7. }

El autoloader funciona tantas veces como clases sea necesario, y sí es un poco más lento a hacer un include() directamente, pero realmente no es notorio en la vida real por lo que no te preocupes no es un cuello de botella ni mucho menos, aparte de que guarda un cache de lo que se incluyo, por lo que solo es marginal la diferencia.

Saludos.
  #18 (permalink)  
Antiguo 28/06/2012, 10:57
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
El autoloader lo único que hace es evitar que tengas que hacer un include() para traer la definición de la clase y la puedas incluir sin que se genere un error.

Respecto a agregar más clases, para eso es el autoloader, puedes instanciar las clases que quieras y se van a incluir siempre y cuando tengan la misma estructura de nomenclaturas / carpetas, por ejemplo:

Código PHP:
Ver original
  1. class Foo {
  2.       public function bar() {
  3.                 $foobar = new Foobar();
  4.                 $baz = new Baz();
  5.                 $foofoo = new Foofoo();
  6.       }
  7. }

El autoloader funciona tantas veces como clases sea necesario, y sí es un poco más lento a hacer un include() directamente, pero realmente no es notorio en la vida real por lo que no te preocupes no es un cuello de botella ni mucho menos, aparte de que guarda un cache de lo que se incluyo, por lo que solo es marginal la diferencia.

Saludos.
Ahora veo las cosas un poco más claras que antes. Aunque, según veo en esa función, en vez de poner "global $foobar, $baz, $foofoo;" las instancias. ¿Entonces es necesario instanciarlas también en el "setup"?

Saludos y gracias nuevamente.
  #19 (permalink)  
Antiguo 28/06/2012, 11: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: ¿Desaconsejado el uso de variables globales?

Desconozco a que te refieres con el "setup" pero pues debes de instanciarlas donde las necesites es la base de POO, si no instancias una clase no la puedes utilizar (a menos que sea una clase estática)
  #20 (permalink)  
Antiguo 28/06/2012, 12:10
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
Desconozco a que te refieres con el "setup" pero pues debes de instanciarlas donde las necesites es la base de POO, si no instancias una clase no la puedes utilizar (a menos que sea una clase estática)
En un principio dijiste esto:

Cita:
// en otro file donde hagas el setup
$db = new Db(/* datos */);
$user = new User();
$user->setDb($db);
*
// Donde uses $user
$user->algo();
Imagino que es donde se haría el include, que ahora es la carga automatizada con spl_autoload_register(). No haría falta instanciarla en ese "setup" que podemos llamar common.php, ¿no? Pues no va a ser utilizada ahí, sólo en algunas funciones de algunas clases.

También, para no instanciar en todas las funciones, se podría crear una función para instanciar automáticamente?

Sería algo como:

Código PHP:
Ver original
  1. Class User
  2. {
  3.     private $security;
  4.     private $core;
  5.    
  6.     function &getInstance()
  7.     {
  8.     $this->ext->security = new Security;
  9.         $this->ext->core = new Core;
  10.      }
  11.    
  12.     function getData()
  13.     {
  14.         $user_id = $this->ext->security->string($_POST['uid']);
  15.     }
  16.  
  17.     // O bien
  18.     function security_class()
  19.     {
  20.         return new Security;
  21.     }
  22.    
  23.     function getData2()
  24.     {
  25.         $user_id = $this->security_class->string($_POST['uid']);
  26.     }
  27. }

O un constructor... donde dice string sería una función de la clase security, mientras que $this->ext->security es la instancia de la clase "Security". ¿Sería posible?

Última edición por salomon26; 28/06/2012 a las 12:51
  #21 (permalink)  
Antiguo 28/06/2012, 13:02
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: ¿Desaconsejado el uso de variables globales?

Precisamente, si vas a usar inyección de dependencias es mejor usar un contenedor, eso es un hecho.

Por otro lado para evitar el uso de globales podrías usar un registro, aunque como te digo no es lo mejor ya que es casi lo mismo a usar globales.

Respecto al setup me refería a un bootstrap, todo depende del patrón de diseño que estés usando pero en algún lado debes de hacerlo, sí vas a usar paginas "planas" pues tendrías que hacerlo de forma más manual, por ejemplo:

autos.php
Código PHP:
Ver original
  1. namespace App;
  2.  
  3. class Autos {
  4.        private $security;
  5.        private $core;
  6.  
  7.        public function setSecurity($security) {
  8.                $this->security = $security;
  9.        }
  10.  
  11.        public function setCore($core) {
  12.                $this->core = $core;
  13.        }
  14.  
  15.        public function getAutos($fecha) {
  16.               $fecha = $this->security->clean($fecha);
  17.  
  18.               return array();
  19.        }
  20. }

common.php
Código PHP:
Ver original
  1. <?php
  2. // register autoloader
  3. set_include_path(get_include_path().PATH_SEPARATOR.'/path/a/tus/clases');
  4.  
  5. $Core = new App\Core();
  6. $Security = new App\Security();

listadoAutos.php:
Código PHP:
Ver original
  1. <?php
  2. include('common.php');
  3.  
  4. $autos = new App\Autos();
  5. $autos->setCore($Core);
  6. $autos->setSecurity($Security);
  7. $fecha = isset($_GET['fecha']) ? $_GET['fecha'] : date('Y-m-d');
  8. foreach ($autos->getAutos($fecha) as $auto) {
  9.          echo $auto;
  10. }

Claro todo esto es suponiendo algo más plano, todo depende de que patrón de diseño tengas, y que tengas bien organizadas tus clases en namespaces como debe de ser
  #22 (permalink)  
Antiguo 29/06/2012, 06:35
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
Precisamente, si vas a usar inyección de dependencias es mejor usar un contenedor, eso es un hecho.

Por otro lado para evitar el uso de globales podrías usar un registro, aunque como te digo no es lo mejor ya que es casi lo mismo a usar globales.

Respecto al setup me refería a un bootstrap, todo depende del patrón de diseño que estés usando pero en algún lado debes de hacerlo, sí vas a usar paginas "planas" pues tendrías que hacerlo de forma más manual, por ejemplo:

autos.php
Código PHP:
Ver original
  1. namespace App;
  2.  
  3. class Autos {
  4.        private $security;
  5.        private $core;
  6.  
  7.        public function setSecurity($security) {
  8.                $this->security = $security;
  9.        }
  10.  
  11.        public function setCore($core) {
  12.                $this->core = $core;
  13.        }
  14.  
  15.        public function getAutos($fecha) {
  16.               $fecha = $this->security->clean($fecha);
  17.  
  18.               return array();
  19.        }
  20. }

common.php
Código PHP:
Ver original
  1. <?php
  2. // register autoloader
  3. set_include_path(get_include_path().PATH_SEPARATOR.'/path/a/tus/clases');
  4.  
  5. $Core = new App\Core();
  6. $Security = new App\Security();

listadoAutos.php:
Código PHP:
Ver original
  1. <?php
  2. include('common.php');
  3.  
  4. $autos = new App\Autos();
  5. $autos->setCore($Core);
  6. $autos->setSecurity($Security);
  7. $fecha = isset($_GET['fecha']) ? $_GET['fecha'] : date('Y-m-d');
  8. foreach ($autos->getAutos($fecha) as $auto) {
  9.          echo $auto;
  10. }

Claro todo esto es suponiendo algo más plano, todo depende de que patrón de diseño tengas, y que tengas bien organizadas tus clases en namespaces como debe de ser
Bien, gracias. Voy a realizar algunas pruebas. ¿A qué te refieres con páginas "planas"? No tengo un patrón de diseño claro todavía, pero estoy ideando algo.

Edito: spl_autoload_register() me está dando problemas de la forma que pusiste, de la forma que yo puse al principio (de php.net) sí se incluye bien, las clases las tengo en la dirección: carpeta public "/inc/clases/user.class.php" (utilizo xamp) ¿Cómo debería ir?

Edito de nuevo: Al llamar a una función desde una clase a otra, da el error: "Call to a member function mifuncion() on a non-object"... En el index llamo a una función, si en la función retorno algo sin necesidad de llamar a otra clase (un 'Hola mundo'), aparece. Pero si en el return pongo la función de otra clase (return $this->user->getHola();), aparece eso. Está la función para definir $this->user en la clase y lo demás que he visto en tu anterior respuesta. ¿La clase no está cargando a otra clase? Aunque hice un include y aparecía "redeclared", por lo tanto creo que la carga.

Última edición por salomon26; 29/06/2012 a las 08:44 Razón: Una pregunta más
  #23 (permalink)  
Antiguo 29/06/2012, 08:58
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: ¿Desaconsejado el uso de variables globales?

spl_autoload_register (sin parámetros) por defecto registra un autoloader compatible con PSR-0 que ya te había dicho desde un inicio.

Sí te da ese error deberías de publicar tu código o lo que estés haciendo ya que es claro, estas tratando de llamar a un método de un objeto en un no objeto, por eso te marca ese fatal error.

Saludos.
  #24 (permalink)  
Antiguo 29/06/2012, 09:16
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
spl_autoload_register (sin parámetros) por defecto registra un autoloader compatible con [URL="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md"][B]PSR-0[/B][/URL] que ya te había dicho desde un inicio.

Sí te da ese error deberías de publicar tu código o lo que estés haciendo ya que es claro, estas tratando de llamar a un método de un objeto en un no objeto, por eso te marca ese fatal error.

Saludos.
Sí, pero al parecer la dirección está mal porque no los incluye, pero de la forma que vi en php.net sí.

El código:

index.php
Código PHP:
Ver original
  1. include('includes/common.php');
  2. echo $Core->gethola();

common.php
Código PHP:
Ver original
  1. spl_autoload_register(function ($clase) {
  2.     include(dirname(__FILE__) . '/clases/' . $clase . '.class.php');
  3. });
  4.  
  5. $Core = new Core();
  6. $User = new User();

core.class.php
Código PHP:
Ver original
  1. Class Core
  2. {
  3.     private $User;
  4.    
  5.     public function setUser($User)
  6.     {
  7.         $this->user = $User;
  8.     }
  9.     public function gethola()
  10.     {
  11.         return $this->user->mifuncion();
  12.     }
  13. }

user.class.php
Código PHP:
Ver original
  1. Class User
  2. {
  3.     private $Core;
  4.    
  5.     public function setCore($Core)
  6.     {
  7.         $this->core = $Core;
  8.     }
  9.     public function mifuncion()
  10.     {
  11.         return 'Hola Mundo';
  12.     }
  13. }
En esta también está core aunque no se use una función de dicha clase todavía, pero lo conservo porque si no existiera el error sí se usaría.

Si el 'Hola Mundo' estuviera en la función "gethola()" sí se mostraría, pero el error aparece cuando se llama a la función "mifuncion()" de otra clase, en este caso "User".

No uso namespaces, ya que en las pruebas tengo dos clases y nada más (además de que con él y sin él el error está). Cuando tengo un error mucho tiempo al final dejo de pensar con claridad.
  #25 (permalink)  
Antiguo 29/06/2012, 10:21
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: ¿Desaconsejado el uso de variables globales?

El error esta en que nunca mandas llamar a setUser, por eso $this->user es nulo al mandar llamar gethola().

Saludos.
  #26 (permalink)  
Antiguo 29/06/2012, 11:24
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
El error esta en que nunca mandas llamar a setUser, por eso $this->user es nulo al mandar llamar gethola().

Saludos.
Se me pasó. Gracias. Pero ahora tengo una duda... ¿siempre que vaya a usar otras clases tendré que hacer esto...

Código PHP:
Ver original
  1. $User->setCore($Core);
  2. $User->setUser($User);
...?

Es decir, ponerle un nombre llamando a la función que define el $this->user o $this->core u otra clase cuando vaya a llamar a una función de otra clase? Creo que puedo acostumbrarme aunque serían muchas llamadas a dicha función, pero no estoy seguro de que sea mejor así, ¿o sí? Comparado con las globales.

Y lo de spl_autoload_register() lo dejo tal y como lo tenía que sí funciona? De la forma que pasaste sigo sin poder configurarlo con una dirección correcta.

Última edición por salomon26; 29/06/2012 a las 12:15
  #27 (permalink)  
Antiguo 29/06/2012, 13:10
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: ¿Desaconsejado el uso de variables globales?

Lo que pasa es que el spl_autoload_register se apega al PSR-0, por eso te invito a leer acerca de, aunque solo funciona con Namespaces, no con clases con underscore (De_Este_Estilo).

Respecto a lo otro sí, a menos que hardcodees la dependencia en tu clase user:
Código PHP:
Ver original
  1. class User {
  2.        private $core;
  3.  
  4.        public function __construct()
  5.        {
  6.                $this->core = new Core();
  7.        }
  8. }

O si usar un DI Container (como Pimple) puedes automatizar todo eso y decirle a Pimple que dependencias necesita tu clase user a la hora de instanciarla.

Saludos.
  #28 (permalink)  
Antiguo 29/06/2012, 13:55
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
Lo que pasa es que el spl_autoload_register se apega al PSR-0, por eso te invito a leer acerca de, aunque solo funciona con Namespaces, no con clases con underscore (De_Este_Estilo).

Respecto a lo otro sí, a menos que hardcodees la dependencia en tu clase user:
Código PHP:
Ver original
  1. class User {
  2.        private $core;
  3.  
  4.        public function __construct()
  5.        {
  6.                $this->core = new Core();
  7.        }
  8. }

O si usar un DI Container (como Pimple) puedes automatizar todo eso y decirle a Pimple que dependencias necesita tu clase user a la hora de instanciarla.

Saludos.
¿No es posible un guión bajo en las clases para usar la forma que pusiste? De la otra forma no generar ningún error, ¿hay algún problema, mayor consumo de memoria o algo que deba tener en cuenta al usarla de la forma que vi en php.net? Los namespaces no tengo problemas en usarlos, tarde o temprano lo tendría que hacer. Pero me gusta separar las palabras con esos guiones (Hasta ahora no tengo clases con más de una palabra, pero es probable que las tuviera pronto). Según el anterior enlace se convertiría en una barra separadora, ¿cierto?

Buscaré información de como implementar Pimple, porque no he usado contenedores antes y no sé cómo hacerlo correctamente. Si conocieras algún enlace explicativo en profundidad, te agradecería que me lo pasaras. Gracias por haber respondido a mis preguntas.

Última edición por salomon26; 29/06/2012 a las 14:05
  #29 (permalink)  
Antiguo 29/06/2012, 15:23
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: ¿Desaconsejado el uso de variables globales?

De forma nativa no, tienes que usar un autoloader como el del link que te pase o implementar uno propio.

Lo mejor es usar los namespaces a las clases con _ ya que precisamente para eso es para el uso nativo de Namespaces en lugar de Clases_Que_Son_Muy_Largas.

Respecto a usar Pimple es sencillo ahí mismo te dice como, pero aquí un ejemplo simple y pequeño:
Código PHP:
Ver original
  1. $container = new Pimple();
  2. $container['core'] = $container->share(function($c) {
  3.         return new Core();
  4. });
  5. $container['user'] = function($c) {
  6.         $user = new User(); // o por constructor es igual
  7.         $user->setCore($c['core']);
  8.         return $user;
  9. };
  10.  
  11. // ahora sí a usar user
  12. $user = $container['user'];
  13. // usar eso es igual a
  14. // $core = new Core();
  15. // $user = new User()->setCore($core);

Saludos.
  #30 (permalink)  
Antiguo 01/07/2012, 17:28
 
Fecha de Ingreso: mayo-2012
Ubicación: En mi casa
Mensajes: 22
Antigüedad: 11 años, 11 meses
Puntos: 1
Respuesta: ¿Desaconsejado el uso de variables globales?

Cita:
Iniciado por GatorV Ver Mensaje
De forma nativa no, tienes que usar un autoloader como el del link que te pase o implementar uno propio.

Lo mejor es usar los namespaces a las clases con _ ya que precisamente para eso es para el uso nativo de Namespaces en lugar de Clases_Que_Son_Muy_Largas.

Respecto a usar Pimple es sencillo ahí mismo te dice como, pero aquí un ejemplo simple y pequeño:
Código PHP:
Ver original
  1. $container = new Pimple();
  2. $container['core'] = $container->share(function($c) {
  3.         return new Core();
  4. });
  5. $container['user'] = function($c) {
  6.         $user = new User(); // o por constructor es igual
  7.         $user->setCore($c['core']);
  8.         return $user;
  9. };
  10.  
  11. // ahora sí a usar user
  12. $user = $container['user'];
  13. // usar eso es igual a
  14. // $core = new Core();
  15. // $user = new User()->setCore($core);

Saludos.
Voy a ver lo que hago, gracias. ¿Qué diferencias tiene la forma automatizada de cargar clases que pusiste con la que puse yo?

Última edición por salomon26; 01/07/2012 a las 19:24

Etiquetas: poo
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.
Tema Cerrado




La zona horaria es GMT -6. Ahora son las 09:44.