[Solucionado] ¿Qué son los traits en PHP y cómo usarlos correctamente?

  • Autor Autor Miguel92
  • Fecha de inicio Fecha de inicio
Miguel92

Miguel92

Alfa
Verificación en dos pasos activada
Verificado por Whatsapp
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Hola a todos, desde que supe de la existencia (hace 1 o 2 días 😅), quiero usarlo, ya que de esta forma podré reducir secciones de bloques repetidas o usar para algo en concreto, doy un ejemplo

(traits)
un archivo App\Traits\algo.php
PHP:
<?php

namespace App\Traits;

use App\Models\Core;

trait Algo {
    protected Core $code;

    public function sayHelloFromCore() {
        return $this->code->esteEsMiMetodo(); // Supongamos que existe ese método
    }
}

Solución: (actualizado a las 09:10pm 12.04.25)
No usarlo de esta forma, ya que genera conflicto
Insertar CODE, HTML o PHP:
protected Core $code;
Esta sería la forma correcta
Insertar CODE, HTML o PHP:
protected $code;

(models)
un archivo App\Services\Otracosa.php
Insertar CODE, HTML o PHP:
<?php

namespace App\Services;

use App\Traits\Algo;
use App\Models\Core;

class SomeService {
    use Algo;

    protected $core;

    public function __construct(Core $core) {
        $this->code = $core; // Aquí le damos valor a la propiedad del trait ( es donde siempre me da problemas)
    }

    public function greet() {
        return $this->sayHelloFromCore();
    }
}

Lo más posible es que lo este haciendo mal o algo que no deba, y por lo que veo parece que es un conflicto entre el $core de trait y este archivo.

porque básicamente un Trait es:
"Un trait es un mecanismo de reutilización de código en lenguajes que no admiten herencia múltiple, como PHP. Te permite definir métodos y propiedades que luego pueden ser insertados en cualquier clase."
 
Última edición:
Osea que le estas pasando el core a la classe SomeService asi?

PHP:
$core = new Core();
$app = new SomeService($core);
 
Tienes un "conflicto de propiedades" creo.
 
Primero estaria bien si publicaras el mensaje de error que te marca, para poder replicarlo directamente.

No habia escuchado de los traits, pero viendo la documentacion y probando, al utilizar: use traitA los metodos y las propiedades son accesibles en la clase, pero como dices, intente replicar el error y lo que puedo decir es que debes establecer un valor por defecto en el constructor de la clase. Ademas, como menciono el usuario @YeltsinReyes no puedes utilizar el mismo nombre en las propiedades porque el trait entrara en conflicto.
PHP:
<?php
trait TraitA {
    protected $hello = 'Hello';
    public function sayHello() {
        echo $this->hello;
    }
}

trait TraitB {
    protected $world = 'world';
    public function sayWorld() {
        echo $this->world;
    }
}

class MyHelloWorld
{
    use TraitA, TraitB; // A class can use multiple traits
    
    // establece valores por defecto 
    public function __construct(?String $hello = "Hello", ?String $world = "world" ){
        $this->hello = $hello;
        $this->world = $world;
    }

    public function sayHelloWorld() {
        $this->sayHello();
        echo ' ';
        $this->sayWorld();
        echo "!\n";
    }
}

$myHelloWorld = new MyHelloWorld("Hola");
$myHelloWorld->sayHelloWorld();
// y si las propiedades son accesibles
$myHelloWorld->hello;
$myHelloWorld->world;

Tal como lo dice la IA, es como si estuvieras escribiendo las propiedades y los metodos en la clase:

¿Qué pasa internamente?​

PHP copia literalmente el contenido del trait dentro de la clase que lo usa, como si estuviera declarado directamente ahí. Así que si TraitA tiene propiedades y métodos, esos elementos pasan a formar parte del espacio de la clase.

⚠️ Pero ojo con esto:​

  • Si dos traits tienen una propiedad con el mismo nombre, y los usas en la misma clase, PHP lanzará un error.
  • Si quieres que la propiedad sea privada o protegida, puedes hacerlo también en el trait:
 
Gracias por responder YeltsinReyes y ronald3217, el problema era que lo estaba queriendo usar así.

en el trait y use Inyección de Dependencias
PHP:
namespace App\Traits;

use App\Models\{Core,User};

trait SameCode {

    protected $core;
    protected $user;

    public function __construct(Core $core, User $user) {
        $this->core = $core;
        $this->user = $user;
    }

    public function hola() {
        return "Hola {$this->core->settings['titulo']}";
    }

}

y como vi en su ejemplo que estaba el protected y la variable, lo probé y funciono,
 
Atrás
Arriba