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

Problema con Exception disparado dentro de __toString()

Estas en el tema de Problema con Exception disparado dentro de __toString() en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Bueno, tengo clarísimo que dentro de un método __toString no pueden dispararse excepciones, pero... Tengo un stack de objetos que pretendo escapar como string, haciendo ...
  #1 (permalink)  
Antiguo 08/12/2008, 10:49
Avatar de ArrauKano  
Fecha de Ingreso: noviembre-2002
Ubicación: Santiago
Mensajes: 664
Antigüedad: 21 años, 5 meses
Puntos: 4
Problema con Exception disparado dentro de __toString()

Bueno, tengo clarísimo que dentro de un método __toString no pueden dispararse excepciones, pero...

Tengo un stack de objetos que pretendo escapar como string, haciendo simplemente un implode(), de tal modo que el casting llame automáticamente a la salida en forma de texto de cada objeto y los junte en una sola cadena.

Todos los objetos del stack son hijos de "Widget", y mi clase Widget tiene un método __toString() que llama a otro método getContent().

Código php:
Ver original
  1. abstract class Rox_Wigdet
  2. {
  3.  
  4.     public function getContent()
  5.     {
  6.         return 'Contenido';
  7.     }
  8.  
  9.     final public function __toString()
  10.     {
  11.         try {
  12.             return (string) $this->getContent();
  13.         } catch ( Rox_Widget_Exception $e ) {
  14.             trigger_error($e->getMessage(), E_USER_WARNING);
  15.             }
  16.         return '';
  17.     }
  18. }

La idea es que cada widget pueda definir su contenido y que siempre se dibujen de igual manera.

Para prevenir que el contenido del objeto dispare cualquier excepcion, pensé en rodear todo el __toString con un bloque try...catch.

Pensé que estaba todo bien, pero hoy al modificar un widget, tuve un problema que disparó una excepcion, y descubrí que por algún motivo, la excepcion simplemente se saltó el bloque .

Acá hice un ejemplo reproducible:

Código php:
Ver original
  1. <?php
  2.  
  3. class A {
  4.  
  5.     public function output()
  6.     {
  7.         return ' algo A ';
  8.     }
  9.  
  10.     public function __toString()
  11.     {
  12.         try {
  13.             $out = $this->output();
  14.         } catch ( Exception $e ) {
  15.             trigger_error($e->getMessage(), E_USER_WARNING);
  16.             $out = $e->getMessage ();
  17.         }
  18.        return $out;
  19.     }
  20. }
  21.  
  22. class B extends A {
  23.     public function output()
  24.     {
  25.         return ' algo B ';
  26.     }
  27. }
  28.  
  29. class C extends B {
  30.     public function output()
  31.     {
  32.         throw new Exception('boooooooo!');
  33.         return ' algo C ';
  34.     }
  35. }
  36.  
  37.  
  38. /** Prueba: */
  39.  
  40. $stack = array(
  41.     new A(),
  42.     new B(),
  43.     new C()
  44. );
  45.  
  46. echo implode( $stack );
__________________
Blog | Tecnosquad

Última edición por ArrauKano; 08/12/2008 a las 10:54
  #2 (permalink)  
Antiguo 08/12/2008, 11:04
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: Problema con Exception disparado dentro de __toString()

Mmm esque según lo que tengo entendido es que __toString() devuelva el contexto actual en un string de la clase, no que sea __toString() el encargado de devolver la representación de texto del objeto.

Es un poco complicado entenderlo pero la idea es por ejemplo, construyes tu objeto, llamas a algunos métodos para que haga algo, y al final llamas a __toString() este te tiene que devolver el estado actual, no es __toString() el encargado de realizar ultimos procesos de salida o algo.

Tu idea de sobreescribir un solo método (por ejemplo output()) no es la más correcta ya que __toString() no es una función terminadora, es mas bien un informante del estado actual.

Saludos.
  #3 (permalink)  
Antiguo 08/12/2008, 11:15
Avatar de ArrauKano  
Fecha de Ingreso: noviembre-2002
Ubicación: Santiago
Mensajes: 664
Antigüedad: 21 años, 5 meses
Puntos: 4
Respuesta: Problema con Exception disparado dentro de __toString()

Entonces, la idea sería llamar a método "ejecutor" de cada objeto "Widget" en el stack, guardar el output en una propiedad y solo retornar el string, para poder concatenar todo con el implode() ?

Igual sería algo latoso.

Pero independiente de la técnica a seguir, en ningún lado del manual vi ese comportamiento de __toString(), porque simplemente no le hace caso al bloque try...catch().

Además, juraría que en algún minuto me funcionó (una versión más antigua de php tal vez).
__________________
Blog | Tecnosquad
  #4 (permalink)  
Antiguo 08/12/2008, 11:18
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: Problema con Exception disparado dentro de __toString()

Mmm puede que sea algo que hayan desactivado en alguna versión de PHP, por ende el error, esque antes si lees el Manual __toString() solo era llamado en por ejemplo echo, o print, ahora es llamado en cualquier lugar donde se haga el casting a string, entonces por ejemplo str_replace() si le pasas el objeto y te lanza una excepcion deja al interprete en un estado inconsistente, por ende desactivaron el uso de lanzar excepciones y mejor tirar un warning.

Saludos.
  #5 (permalink)  
Antiguo 08/12/2008, 16:22
Avatar de enriqueplace  
Fecha de Ingreso: mayo-2005
Ubicación: Uruguay / Argentina
Mensajes: 1.102
Antigüedad: 18 años, 11 meses
Puntos: 32
Respuesta: Problema con Exception disparado dentro de __toString()

El problema que estoy viendo es que intentas crear un "cañón destructor de planetas" dentro de un "excusado", y este se creó para otra cosa.

Crea métodos, si quieres que todos hagan lo mismo, create una interfaz para definir los métodos de los Widget's y la clase que los use solo acepte de tipo la interfaz, deja el toString para lo que es, cuando lo quieres convertirlo a texto (si no te sirve que haga algo en ese contexto, no lo hagas).
__________________
Blog phpsenior.com Cursos a Distancia surforce.com
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 02:04.