No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso Avanzado de PHP

Curso Avanzado de PHP

Héctor Benitez

Héctor Benitez

Traits

9/35
Recursos
  • Es importante saber que aunque se está intentando usar el patrón de diseño MVC, normalmente no todo se tiene exclusivamente en estas 3 carpetas; podemos tener más carpetas pero teniendo en cuenta el mantener el código siempre bien organizado.
  • Un trait se declara creando un nuevo archivo, muy parecido a una clase pero en vez de class se utiliza la palabra trait. Para que una clase utilice un trait, se deberá usar dentro de la clase la palabra use y el nombre del trait.
  • Lo interesante de hacer traits en vez de poner el código directamente en una clase, es que esta funcionalidad podría servir para otras clases que no están relacionadas entre sí.
  • Un trait puede ser implementado en tantas clases como queramos.

Aportes 22

Preguntas 2

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Si en vez del texto del return devuelve (unknown) a que se debería ?

  • Estoy usando el trait en el modelo
    -La ruta del trait es correcta
    -Ya revise mi sintaxis
 {% for datos in job %}
                    <div class="col-md-3">
                        <img src="{{datos.getImage()}}" style="max-width: 100%">
                    </div>
                    <div class="col-md-9">
                        <ul>

                                <li class="work-position">
                                    <h5> {{datos.title}} </h5>
                                    <p> {{datos.description}}</p>
                                    <strong>Achievements:</strong>
                                    <ul>
                                        {% for dato in activity %}
                                            {% if dato.jobs_id == datos.id %}
                                                <li> {{ dato.description}} </li>
                                            {% endif %}
                                        {% endfor %}
                                    </ul>
                                </li>

                        </ul>
                    </div>
                {% endfor %}
use app\Traits\HasDefaultImage;

class Jobs extends Model {
    //use SoftDeletes;
    use HasDefaultImage;
<?php
namespace App\Traits;

trait HasDefaultImage {
    public function getImage(){
        if(!$this->imagen){
         return "https://ui-avatars.com/api/?name=John+Doe&size=166";
        }
        return  "hola";//$this->imagen;
    }
}

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.

https://www.php.net/manual/es/language.oop5.traits.php

Si en vez del texto del return devuelve (unknown) deben comentar el closure en IndexController:

 
        $name = 'Hector Benitez';
        $limitMonths = 3;

        // $filterClosure = function (array $job) use ($limitMonths) {
        //     return $job['months'] > $limitMonths;
        // };
        // $jobs = array_filter($jobs->toArray(), $filterClosure);

        return $this->renderHTML('index.twig', [
            'name' => $name,
            'jobs' => $jobs
        ]);

Los traits los conocí gracias a Laravel y curioseando en su código fuente jaja, un ejemplo de dónde lo usa Laravel (En su versión 8) es en los modelos, podemos ver que las clases usan los traits HasFactory y Notifiable, los traits son increibles!

Al parece al convertir jobs a array con toArray hace de q al mandarlo a la vista este pierda sus metodos como objeto ya que no se estaria enviando un array de objetos como se hacia originalmente sino q ahora se esta enviando solamente un array multidimensional simple q al ser llamado en la vista ya no reconozca sus metodos porque ya no es un objeto , entonces para arreglar esto ya no se puede usar el fitro con la funcion filter_array ya q esta solamente recibe como parametro un arreglo y ya no un objeto de eloquent por lo que lo mejor es crear otro filtro sin modificar la estructura de los objetos q se enviaran a la vista :

foreach ($jobs as $key => $job) {
            if($job -> months <= $limitMonths){
                unset($jobs[$key]);
            }
        }

Según tengo entendido los trait por convención deberían terminar con la palabra Trait, esto lo leí en:

https://www.php-fig.org/bylaws/psr-naming-conventions/

¿Hay alguna nomenclatura estandar para definir los nombres de los trait a parte de este PSR?

No sé que tiene Héctor, pero tiene terrible alegría al explicar los traits, se le ve en la cara en el min 5:10 jajaja

Traits

Es un mecanismo de reutilización de código que se utiliza en lenguajes de herencia simple como php o ruby.

Excelente clase, muy bien explicado los Traits

Podría decirse que los traits de php son como los “mixins” de los preprocesadores?

Hola!. Esto es lo que se llama “injection over inheritance”?

Los rasgos («traits» en inglés) son un mecanismo de reutilización de código en lenguajes de herencia simple, como PHP. El objetivo de un rasgo 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.

Un Trait es similar a una clase, pero con el único objetivo de agrupar funcionalidades muy específicas y de una manera coherente.

Hola, yo quise retomar la funcion getDurationAsSTring que vimos en el curso de PHP básico para hacer el reto de crea un Trait, con el fin de ver que se podía utilizar similar a una clase y les quiero compartir el código, de pronto a alguien le interese y me pueda dejar sus comentarios sobre si es práctico o se podría mejorar o que tan recomendable es hacerlo así. Gracias de antemano:

<?php

namespace App\traits;

trait  HasDefaultMonthsDuration{

    private $numYears;
    private $numtMonths;

    public function getDurationAsString($months)
    {
        $strYears = null;
        $strMonths = null;
        if (empty($months) || $months == 0)
            return null;
        else {
            $this->setNumYears($months);
            $this->setNumtMonths($months);
            if($this->getNumYears() !== null)
                $strYears = $this->numYears > 1 ? "Years" : "Year";
            if($this->getNumtMonths() !== null)
                $strMonths = $this->numtMonths == 1 ? 'Month' : "Months";
            return "Duration: $this->numYears $strYears $this->numtMonths $strMonths ";
        }
    }

    public function getNumYears()
    {
        return $this->numYears;
    }

    public function setNumYears($months): void
    {
        $this->numYears = floor($months/12) == 0 ? null : floor($months/12);
    }

    public function getNumtMonths()
    {
        return $this->numtMonths;
    }

    public function setNumtMonths($months): void
    {
        $this->numtMonths = $months % 12 == 0 ? null : $months % 12;
    }

}

Es importante saber que aunque se está intentando usar el patrón de diseño MVC, normalmente no todo se tiene exclusivamente en estas 3 carpetas; podemos tener más carpetas pero teniendo en cuenta el mantener el código siempre bien organizado.

Un trait se declara creando un nuevo archivo, muy parecido a una clase pero en vez de class se utiliza la palabra trait. Para que una clase utilice un trait, se deberá usar dentro de la clase la palabra use y el nombre del trait.

Un trait puede ser implementado en tantas clases como queramos.

Lo interesante de hacer traits en vez de poner el código directamente en una clase, es que esta funcionalidad podría servir para otras clases que no están relacionadas entre sí.

Excelente el uso de los Traits

En un momento llegue a pensar que los Traits eran interfaces, luego encontré que son cosas con propósitos muy diferentes aquí el enlace

amigos tengo la siguiente situación, cuando muestro mis imagenes en el index.twig si no pongo el nombre de mi carpeta uploads antes que {{ job.getImage(job.title) }} entonces solo se muestra la imagen que viene de la url, pero si pongo mi ruta así: src=“uploads/{{ job.getImage(job.title) }}” si me muestra mis imagenes almacenadas en local pero no la que esta en la url, les agradezco su ayuda c:

index.twig

{% for job in jobs %}
                <div class="work-position">
                    <div class="col-3">
                      <img src="uploads/{{ job.getImage(job.title) }}" alt="" width="100px" height="100px" >
                    </div>
                    <div class="col">
                      <h5> {{ job.title }} </h5>
                      <p> {{ job.description }} </p>
                    </div> 
                </div>
              {% endfor %}

en mi archivo trait

<?php

namespace App\Traits;

trait HasDefaultImage 
{
    public function getImage($altText) {
        //si no hay imagen cargada.
        if(! $this->image){
            return "https://ui-avatars.com/api/?name=$altText&size=160";
        }//si hay imagen cargada.
        return $this->image;
    }
}

en mi indexController.php


class IndexController extends BaseController {
    public function indexAction () {

     

        //Nos trae todos los registros que encuentre.
        $jobs = Job::all();
        $project1 = new Project('Project 1', 'Description 1');
        $projects = [
            $project1
        ];

        return $this->renderHTML('index.twig', [
            'jobs' => $jobs
        ]);
    }
}

en mi JobsController.php

try {
                 //Enviaremos la información por el formulario. 

                //$jobValidator->validate($postData); //true
                 $jobValidator->assert($postData); //true

                 //creo una nueva instancia.
                  $postData = $request->getParsedBody();

                  //cuando usamos psr7 para mensajes http dentro de php.
                  $files = $request->getUploadedFiles();
                  $logo = $files['logo'];

                  $filePath  = "";
                    //SI ESTUVO BIEN LA SUBIDA DEL ARCHIVO
                  if ($logo->getError() == UPLOAD_ERR_OK) {
                      //estos metodos ya vienen declarados en psr7
                    $fileName = $logo->getClientFileName();
                    $filePath = "uploads/$fileName";
                    $logo->moveTo($filePath);
                    //para darle permisos a un archivo.
                    //chmod($logo, 0644);
                  }

                  //var_dump($files);
                  //si no queremos hacer esto entonces aremos esto:
                  $job = new Job();
                  $job->title = $postData['title'];
                  $job->description = $postData['description'];
                  $job->image = $filePath;
                  $job->save();

                  $responseMessage = 'Saved';

             }

Pueden usar esta validación dentro dentro de su función

public function getImage($title) {
       return is_null($this->image_url) ? "https://ui-avatars.com/api/?name=$title" : $this->image_url;
   } 

Hola, Ahora que veo este tema de los traits, quisiera saber si lo puedo usar en una aplicación donde tengo una tabla (modelo) personas, y otras tablas como empleados, clientes etc, pero todos pertenecen a una persona, y dado que todas extienden de model no pueden extender de persona. Es buena idea crear un trait Persona, y usarlo en en estos modelos y hacer cosas como que cuando intente crear un empleado o un cliente el trait cree la persona primero, para no tener que primero crear la persona y luego el empleado, o cuando le solicite el nombre al empleado esto lo obtenga del trait persona?