Traits in PHP: Proper way of implementation
Trait is very useful concept in OOP PHP. Although it is very similar to php class but it has so many different uses in OOP approach. In this article i will try to describe how to use trait in a proper way & when we use trait instead of class and common trait scopes.
The main benefit of traits is its re-usable nature. The PHP language is a single inheritance language. This means that any given class can only extend a single other class. As an example, let’s say you have two base classes:
Unfortunately, as it stands in PHP, you cannot perform multiple inheritance by extending classes. You can extend either BaseA or BaseB, but not both at the same time:
But what if you want the functionality of both of these in a single class? Traits can solve this problem:
This method of inheritance is known as “Horizontal Reuse”. It is intended to reduce code duplication and share code horizontally.
As described above, traits are very easy to use. In their most basic form, you declare a trait using the
You can then have classes which use this trait:
Traits can also contain class properties:
Basically, when a trait is used in a class, it is more or less directly copied into the class. I’ll go over some basic properties of traits, and some common use cases.
One thing to note is that the scope of functions and properties within a trait are inherited by the child class. This means a
public object will act in the class the same way it acts as it does in the trait. One way to think about it is that the contents of the trait are more or less directly copied into the classes which use them. What does this mean for each scope specifically?
Unlike single inheritance, private scope in a trait will be available to the extending classes. Take this example:
In the above code, the
ExtendingClass will throw an error - this is because it is trying to access a function which is private to
Protected scope for a trait means that any class which extends the trait, or the children of the trait are able to access the function or variable. In the previous example, if
privateFunc were a
protected function, then
ExtendingClass would be valid.
Anyone can access the variable or function. Simple as that.
Sometimes, it is possible that you need to import a trait into a class, but there is a conflicting function or variable name. This can be solved using either the
insteadof specifies that you want to use
someFunc from A instead of B. The
as operator specifies a different name for the imported function - basically an alias. If you use the
insteadof operator and don't alias the replaced function, then it is essentially discarded. In the case above,
B::someFunc was discarded since it was not aliased.
In above i try to describe using of trait in a proper manner.