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

Nuevos "Traits" PHP 5.4.0+

Estas en el tema de Nuevos "Traits" PHP 5.4.0+ en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Nuevos "Traits" (PHP 5.4.0+) Un post con el fin de actualizar la gente con nuevas características de PHP orientado a objetos. Desde PHP 5.4.0, PHP ...
  #1 (permalink)  
Antiguo 10/09/2011, 14:58
Avatar de andresdzphp
Colaborador
 
Fecha de Ingreso: julio-2011
Ubicación: $this->Colombia;
Mensajes: 2.749
Antigüedad: 13 años, 4 meses
Puntos: 793
Nuevos "Traits" PHP 5.4.0+

Nuevos "Traits" (PHP 5.4.0+)

Un post con el fin de actualizar la gente con nuevas características de PHP orientado a objetos.

Desde PHP 5.4.0, PHP implementa una metodología de reutilización de código llamada Traits.

Los traits (rasgos) son un mecanismo de reutilización de código en lenguajes de herencia simple, como PHP. El objetivo de un trait es el de reducir las limitaciones propias de la herencia simple permitiendo que los desarrolladores reutilicen a voluntad conjuntos de métodos sobre varias clases independientes y pertenecientes a clases jerárquicas distintas. La semántica a la hora combinar Traits y clases se define de tal manera que reduzca su complejidad y se eviten los problemas típicos asociados a la herencia múltiple y a los Mixins.

Un Trait es similar a una clase, pero con el único objetivo de agrupar funcionalidades muy específicas y de una manera coherente. No se puede instanciar directamente un Trait. Es por tanto un añadido a la herencia tradicional, y habilita la composición horizontal de comportamientos; es decir, permite combinar miembros de clases sin tener que usar herencia.

Ejemplo de Trait

Código PHP:
Ver original
  1. <?php
  2. trait ezcReflectionReturnInfo {
  3.     function getReturnType() { /*1*/ }
  4.     function getReturnDescription() { /*2*/ }
  5. }
  6.  
  7. class ezcReflectionMethod extends ReflectionMethod {
  8.     use ezcReflectionReturnInfo;
  9.     /* ... */
  10. }
  11.  
  12. class ezcReflectionFunction extends ReflectionFunction {
  13.     use ezcReflectionReturnInfo;
  14.     /* ... */
  15. }
  16. ?>

Precedencia

Los miembros heredados de una clase base se sobrescriben cuando se inserta otro miembro homónimo desde un Trait. De acuerdo con el orden de precedencia, los miembros de la clase actual sobrescriben los métodos del Trait, que a su vez sobrescribe los métodos heredados.

Ejemplo de Orden de Precedencia

Cita:
Se sobrescribe un miembro de la clase base con el método insertado en MiHolaMundo a partir del Trait DecirMundo. El comportamiento es el mismo para los métodos definidos en la clase MiHolaMundo. Según el orden de precedencia los métodos de la clase actual sobrescriben los métodos del Trait, a la vez que el Trait sobrescribe los métodos de la clase base.
Código PHP:
Ver original
  1. <?php
  2. class Base {
  3.   public function decirHola() {
  4.     echo '¡Hola ';
  5.   }
  6. }
  7.  
  8. trait DecirMundo {
  9.   public function decirHola() {
  10.     parent::decirHola();
  11.     echo 'Mundo!';
  12.   }
  13. }
  14.  
  15. class MiHolaMundo extends Base {
  16.   use DecirMundo;
  17. }
  18.  
  19. $o = new MiHolaMundo();
  20. $o->decirHola();
  21. ?>

El resultado del ejemplo sería: ¡Hola Mundo!

Multiples Traits

Se pueden insertar múltiples Traits en una clase, mediante una lista separada por comas en la sentencia use.

Código PHP:
Ver original
  1. <?php
  2. trait Hola {
  3.   public function decirHola() {
  4.     echo 'Hola ';
  5.   }
  6. }
  7.  
  8. trait Mundo {
  9.   public function decirMundo() {
  10.     echo ' Mundo';
  11.   }
  12. }
  13.  
  14. class MiHolaMundo {
  15.   use Hola, Mundo;
  16.   public function decirAdmiración() {
  17.     echo '!';
  18.   }
  19. }
  20.  
  21. $o = new MiHolaMundo();
  22. $o->decirHola();
  23. $o->decirMundo();
  24. $o->decirAdmiración();>
  25. ?>

El resultado del ejemplo sería: Hola Mundo!

Resolución de Conflictos

Si dos Traits insertan un método con el mismo nombre, se produce un error fatal, siempre y cuando no se haya resuelto explicitamente el conflicto.

Para resolver los conflictos de nombres entre Traits en una misma clase, se debe usar el operador insteadof para elejir unívocamente uno de los métodos conflictivos.

Como esto sólo permite excluir métodos, se puede usar el operador as para permitir incluir uno de los métodos conflictivos bajo otro nombre.

Ejemplo Resolución de Conflictos

Cita:
En este ejemplo, Talker utiliza los traits A y B. Como A y B tienen métodos conflictos, se define el uso de la variante de smallTalk del trait B, y la variante de bigTalk del traita A.

Aliased_Talker hace uso del operador as para poder usar la implementación de bigTalk de B, bajo el alias adicional talk.
Código PHP:
Ver original
  1. <?php
  2. trait A {
  3.   public function smallTalk() {
  4.     echo 'a';
  5.   }
  6.   public function bigTalk() {
  7.     echo 'A';
  8.   }
  9. }
  10.  
  11. trait B {
  12.   public function smallTalk() {
  13.     echo 'b';
  14.   }
  15.   public function bigTalk() {
  16.     echo 'B';
  17.   }
  18. }
  19.  
  20. class Talker {
  21.   use A, B {
  22.     B::smallTalk insteadof A;
  23.     A::bigTalk insteadof B;
  24.   }
  25. }
  26.  
  27. class Aliased_Talker {
  28.   use A, B {
  29.     B::smallTalk insteadof A;
  30.     A::bigTalk insteadof B;
  31.     B::bigTalk as talk;
  32.   }
  33. }
  34. ?>

Modificando la Visibilidad de los Métodos

Al usar el operador as, se puede también ajustar la visibilidad del método en la clase exhibida.

Código PHP:
Ver original
  1. <?php
  2. trait HolaMundo {
  3.   public function decirHola() {
  4.     echo 'Hola Mundo!';
  5.   }
  6. }
  7.  
  8. class MiClase1 {
  9.   use HolaMundo { decirHola as protected }
  10. }
  11.  
  12. class MiClase2 {
  13.   use HolaMundo { hacerHolaMundo as private decirHola }
  14. }
  15. ?>

Traits Compuestos de Traits

Al igual que las clases, los Traits también pueden hacer uso de otros Traits. Al usar uno o más traits en la definición de un trait, éste puede componerse parcial o completamente de miembros de finidos en esos otros traits.

Código PHP:
Ver original
  1. <?php
  2. trait Hola {
  3.   public function decirHola() {
  4.     echo 'Hola ';
  5.   }
  6. }
  7.  
  8. trait Mundo {
  9.   public function decirMundo() {
  10.     echo 'Mundo!';
  11.   }
  12. }
  13.  
  14. trait HolaMundo {
  15.   use Hola, Mundo;
  16. }
  17.  
  18. class MiHolaMundo {
  19.   use HolaMundo;
  20. }
  21.  
  22. $o = new MiHolaMundo();
  23. $o->decirHola();
  24. $o->decirMundo();
  25. ?>

El resultado del ejemplo sería: Hola Mundo!

Miembros Abstractos de Traits

Los traits soportan el uso de métodos abstractos para imponer requisitos a la clase a la que se exhiban.

Código PHP:
Ver original
  1. <?php
  2. trait Hola {
  3.   public function decirHolaMundo() {
  4.     echo 'Hola'.$this->obtenerMundo();
  5.   }
  6.   abstract public function obtenerMundo();
  7. }
  8.  
  9. class MiHolaMundo {
  10.   private $mundo;
  11.   use Hola;
  12.   public function obtenerMundo() {
  13.     return $this->mundo;
  14.   }
  15.   public function asignarMundo($val) {
  16.     $this->mundo = $val;
  17.   }
  18. }
  19. ?>

Miembros Estáticos en Traits

Los métodos de un trait pueden referenciar a variables estáticas, pero no puede ser definido en el trait. Los traits, sin embargo, pueden definir método estáticos a la clase a la que se exhiben.

Código PHP:
Ver original
  1. <?php
  2.   trait Contador {
  3.     public function inc() {
  4.       static $c = 0;
  5.       $c = $c + 1;
  6.       echo "$c\n";
  7.     }
  8.   }
  9.  
  10.   class C1 {
  11.     use Contador;
  12.   }
  13.  
  14.   class C2 {
  15.     use Contador;
  16.   }
  17.  
  18.   $o = new C1(); $o->inc(); // echo 1
  19.   $p = new C2(); $p->inc(); // echo 1
  20. ?>

Código PHP:
Ver original
  1. <?php
  2.   trait Singleton {
  3.     public static function getInstance() { ... }
  4.   }
  5.  
  6.   class MiSingleton extends SomeUnrelatedSuperClass {
  7.     use Singleton;
  8.   }
  9.  
  10.   MiSingleton::getInstance();
  11. ?>

Espero que les haya gustado, a mi me parece interesante el tema, aunque no muy claro todavía.

Más información en nuestro querido manual:

http://php.net/manual/es/language.oop5.traits.php

Saludos
__________________
Si sabemos como leer e interpretar el manual será mucho más fácil aprender PHP. En lugar de confiar en ejemplos o copiar y pegar - PHP
  #2 (permalink)  
Antiguo 10/09/2011, 17:01
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 10 meses
Puntos: 845
Respuesta: Nuevos "Traits" PHP 5.4.0+

Agrego otra referencia, Stefan Marr.
Seguro saldran cosas interesantes aunque en lo personal todavia no tengo una opinion formada al respecto y como dice el autor

Cita:
It is almost like a language supported and failsafe copy’n'paste mechanism to build classes.
Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #3 (permalink)  
Antiguo 11/09/2011, 18:58
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Nuevos "Traits" PHP 5.4.0+

Interesante lo nuevo, como dice masterpuppet todavía no me decido si es beneficioso o perjudicial, voy a esperar a ver que se puede crear correctamente y esperemos no haga más fácil hacer código espaguetti.
  #4 (permalink)  
Antiguo 18/09/2011, 02:13
Avatar de pablofmorales  
Fecha de Ingreso: abril-2008
Ubicación: Buenos Aires, Argentina, Argentina
Mensajes: 222
Antigüedad: 16 años, 7 meses
Puntos: 37
Respuesta: Nuevos "Traits" PHP 5.4.0+

Cita:
Iniciado por GatorV Ver Mensaje
Interesante lo nuevo, como dice masterpuppet todavía no me decido si es beneficioso o perjudicial, voy a esperar a ver que se puede crear correctamente y esperemos no haga más fácil hacer código espaguetti.

Creo que este tipo de cambios esta mas orientados a mejorar Zend Framework y no para el uso normal.

Alguien que hace codigo spaguetti, no creo que pueda entender como aplicarlo. Al menos que haga copy/paste claro.
__________________
blog
  #5 (permalink)  
Antiguo 25/09/2012, 12:09
 
Fecha de Ingreso: mayo-2011
Ubicación: Buenos Aires
Mensajes: 41
Antigüedad: 13 años, 5 meses
Puntos: 2
Respuesta: Nuevos "Traits" PHP 5.4.0+

Hola a todos por suerte entendi todos los ejemplos menos: Miembros Estáticos en Traits. Si alguien me lo pudiera explicar le agradeceria de antemano llevo horas tratando de entenderlo.
Muchas gracias.
  #6 (permalink)  
Antiguo 25/09/2012, 12:15
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 18 años, 5 meses
Puntos: 2135
Respuesta: Nuevos "Traits" PHP 5.4.0+

Simplemente es que el trait como tal no puede definir variables estáticas, pero sí puede hacer uso de ellas, el ejemplo del contador es lo que dice, define una variable estática (static $c), y al darle el use del trait a las otras clases, cada clase hace uso de su propia variable.
  #7 (permalink)  
Antiguo 25/09/2012, 15:58
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años, 7 meses
Puntos: 2534
Respuesta: Nuevos "Traits" PHP 5.4.0+

A mi en lo personal me parece beneficioso de muchas formas, habilita por decirlo así el patchy-monkey en php, entre otras yerbas.

Un caso concreto, cuando se trabaja con RoR es el uso de DataMappers, que con Traits podría ser así la cosa.

Código php:
Ver original
  1. namespace Model;
  2.  
  3. class Book
  4. {
  5.   use \DataMapper\Base;
  6.   use \DataMapper\Validations;
  7.   use \DataMapper\Engine\MongoDB;
  8. }
  9.  
  10. // ...
  11.  
  12. echo Book::find_by_slug_and_owner_id('hello-world', 99);

Cosas del estilo pues, finalmente me quedo con la descripción del "copy/paste seguro".

Ciertamente es otra forma de ir construyendo clases con diversas funcionalidades sin estar obligados a extender.

Particularmente funcionalidades como estas me permiten seguir expresando cuanta cosa me venga en mente sin envidiar otros lenguajes dinámicos.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.

Etiquetas: 5.4.0+, clase, nuevos, php, poo, traits, variables
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

SíEste tema le ha gustado a 6 personas




La zona horaria es GMT -6. Ahora son las 04:02.