LogoNavigate back to the homepage

How to overwrite the trait on self or the others trait?

Yish
October 23rd, 2020 · 1 min read

It’s about vanilla PHP, here is documentation PHP: Traits – Manual, here is an example.

1trait Taggable
2{
3 public function slug()
4 {
5 return Str::slug($this->slug, '-');
6 }
7}

For now, I don’t want to make a string slugging for the slug, I would like changing to the snake, in the past, I would like to do the following:

1class Post
2{
3 use Taggable;
4
5 /** overwritten */
6 public function slug()
7 {
8 return Str::snake($this->slug);
9 }
10}

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 be overwritten by the other trait, it caused an error:

1PHP Fatal error:
2Trait method slug has not been applied, because there are collisions with other trait methods on Post

So how to do it correctly? use as and insteadof if you want to overwrite

1class Post
2{
3 use Taggable {
4 Taggable::slug as snakeSlug;
5 }
6
7 public function snakeSlug($slug)
8 {
9 return Str::snake($slug);
10 }
11}

If snakeSlug does not exist, it will call to slug. Also, you can change the visibility.

1class Post
2{
3 use Taggable {
4 Taggable::slug as protected snakeSlug;
5 }
6
7 protected function snakeSlug($slug)
8 {
9 return Str::snake($slug);
10 }
11}

If you put the method on Snakeable, you need to use insteadof

1class Post
2{
3 use Snakeable;
4 use Taggable {
5 Snakeable::slug insteadof Taggable;
6 }
7}

If you’re having multiple methods, you should specific each.

1trait Taggable
2{
3 public function slug($slug)
4 {
5 return Str::slug($slug, '-');
6 }
7
8 public function title($title)
9 {
10 return Str::limit($title, 200);
11 }
12}
13
14trait Snakeable
15{
16 public function slug($slug)
17 {
18 return Str::snake($slug);
19 }
20
21 public function title($title)
22 {
23 return Str::limit($title, 1);
24 }
25}
26
27class Post
28{
29 use Snakeable;
30 use Taggable {
31 Snakeable::slug insteadof Taggable;
32 Taggable::title insteadof Snakeable;
33 Snakeable::title as public title;
34 }
35
36 public function title($title)
37 {
38 return Str::of($title)->start('');
39 }
40}

When do I need to do this?

Here is my situation, I need to overwrite a method in the package trait, in the past I need to copy all of the methods to the upper class.

1// the package trait.
2trait Taggable
3{
4 public function transform()
5 {
6 // do something...
7 }
8}
9
10class Post
11{
12 use Taggable;
13}

But I have a lots classes using it, so I want to capsule to trait.

1// the package trait.
2trait Taggable
3{
4 public function transform()
5 {
6 // do something...
7 }
8
9 public function slug()
10 {
11 // do something...
12 }
13}
14
15// my customize trait.
16trait TaggableWithTransform
17{
18 // needs to over writen.
19 public function transform()
20 {
21 // do something...
22 }
23}
24
25
26class Post
27{
28 use TaggableWithTransform;
29 use Taggable {
30 TaggableWithTransform::transform insteadof Taggable;
31 }
32}

More articles from Yish

Create an API authentication with Laravel Sanctum

Laravel Sanctum is a lightweight authentication system for SPAs and mobile, it’s the token based APIs, here is a simple example with Vue.js.

October 20th, 2020 · 1 min read

阿布都中東料理Abdu Arabian Cuisine

今天拜訪了位於公館的阿布都中東料理,這是我第一次嘗試中東料理,整體來說相當滿意,食物非常好吃。

October 17th, 2020 · 1 min read
© 2019–2020 Yish
Link to $https://twitter.com/yishlaiLink to $https://github.com/Mombuyish