use AuditableWithOrder;
use \OwenIt\Auditing\Auditable {
AuditableWithOrder::transformAudit insteadof \OwenIt\Auditing\Auditable;
}
How to overwrite the trait on self or the others trait?
It’s about vanilla PHP, here is documentation PHP: Traits - Manualhttps://www.php.net/manual/en/language.oop5.traits.php, here is an example.
trait Taggable
{
public function slug()
{
return Str::slug($this->slug, '-');
}
}
For now, I don’t want to make a string slugging for slug, I would like changing to snake
, in the past, I would like to do following:
class Post
{
use Taggable;
/** overwritten */
public function slug()
{
return Str::snake($this->slug);
}
}
But here is a problem, if I have a ton of classes used the trait, I need to remember all of this to add the method, and I cannot over written by the other trait, it caused an error:
PHP Fatal error: Trait method slug has not been applied, because there are collisions with other trait methods on Post
So how to do for it correctly? use as
and insteadof
, if you want to over write
class Post
{
use Taggable {
Taggable::slug as snakeSlug;
}
public function snakeSlug($slug)
{
return Str::snake($slug);
}
}
If snakeSlug
does not exist, it will call to slug
. Also you can change the visibility.
class Post
{
use Taggable {
Taggable::slug as protected snakeSlug;
}
protected function snakeSlug($slug)
{
return Str::snake($slug);
}
}
If you put the method on Snakeable
, you need to use insteadof
class Post
{
use Snakeable;
use Taggable {
Snakeable::slug insteadof Taggable;
}
}
If you’re having multiple methods, you should specific each.
trait Taggable
{
public function slug($slug)
{
return Str::slug($slug, '-');
}
public function title($title)
{
return Str::limit($title, 200);
}
}
trait Snakeable
{
public function slug($slug)
{
return Str::snake($slug);
}
public function title($title)
{
return Str::limit($title, 1);
}
}
class Post
{
use Snakeable;
use Taggable {
Snakeable::slug insteadof Taggable;
Taggable::title insteadof Snakeable;
Snakeable::title as public title;
}
public function title($title)
{
return Str::of($title)->start('😄');
}
}
When do I need to do this?
Here is my situation, I need to over write a method in the package trait, in the past I need to copy all of method to upper class.
// the package trait.
trait Taggable
{
public function transform()
{
// do something...
}
}
class Post
{
use Taggable;
}
But I have a lots classes using it, so I want to capsule to trait.
// the package trait.
trait Taggable
{
public function transform()
{
// do something...
}
public function slug()
{
// do something...
}
}
// my customize trait.
trait TaggableWithTransform
{
// needs to over writen.
public function transform()
{
// do something...
}
}
class Post
{
use TaggableWithTransform;
use Taggable {
TaggableWithTransform::transform insteadof Taggable;
}
}