I am looking to tidy up some code I have inherited. Essentially we have two classes (A + B) that extend off two separate classes that do various things differently, however A and B also share some functions. At present the functions are copy and pasted between the two and obviously I know this is wrong. I am looking to see if there it a solution to this so that I only have to define the functions once so that both A and B can use these. Any help would be great!
From php 5.4 you could use Traits.
Here is example from manual
<?php
trait ezcReflectionReturnInfo {
function getReturnType() { /*1*/ }
function getReturnDescription() { /*2*/ }
}
class ezcReflectionMethod extends ReflectionMethod {
use ezcReflectionReturnInfo;
/* ... */
}
class ezcReflectionFunction extends ReflectionFunction {
use ezcReflectionReturnInfo;
/* ... */
}
?>
In an ideal world, it's possible that what you really want there is multiple inheritance, but that is not supported by PHP (or many other languages) as it is much more complex than single inheritance.
One alternative to consider is arranging your code so that both classes eventually inherit from some common ancestor, so that you can put your code here. This may not always be desirable or practical, however, particularly if some of the classes extended are from different libraries with no shared dependency.
You might be able to alter the ancestry of some of your classes by using "composition" and "delegation" rather than direct inheritance. The basic idea is that rather than class B extending class A, you store an instance of class A as a property of class B; when certain methods of class B are called, they call corresponding methods of the A instance, while other methods of B are completely separate, and can be inherited from somewhere else. The magic method __call can be useful for implementing this without having to know every possible delegated method in advance.
As of PHP 5.4, there is a form of "horizontal code reuse" called Traits. Traits are sometimes described as "compiler-assisted copy-and-paste", because they don't represent any OOP relationship between the classes where they are used, only a way of editing the functions in one place.
If the functions are public, you might want to declare the classes as implementing an Interface, which lets other code check that a set of methods are available, usually by using the instanceof operator. This can be used in combination with a Trait, which contains the details of how those methods are implemented.
Related
How can I add a static method for all classes of my php using an class Class or class Object (meta class) like
class Object //meta class, all classes php henerit of it
{
static function test() { return 42; }
}
now if I make a new class like :
class User
{
}
I want to be abble to write :
User::test();
same with all classes I will write
PHP has no concept of metaclasses; the way in which classes themselves behave is essentially hard-coded into the language. (You could argue that internal classes written in C conceptually use a different metaclass than userland classes written in PHP, since they can implement a different set of hooks; but that's not a distinction that's visible in the language, and not really relevant to your example.)
It also has no universal base class; there is no "Object" or "Any" or "Mu" class which all other classes implicitly or explicitly inherit from.
More importantly, there is no way to add to an existing class; there is no way to "re-open" or "monkey-patch" a class, or add methods via "extension classes". So even if there was a default metaclass or universal base class, you wouldn't be able to change it. Any classes you wanted extra behaviour on would have to opt-in to being instances of a non-default metaclass, or inherit from a non-default base class.
It's not clear exactly what the use case is, but there are a number of things you can do:
Write your own base class which a large number of classes inherit from, to put your "universal" methods in.
Use traits which enable "horizontal code re-use", essentially by "compiler-assisted copy-and-paste".
You have to use the trait in each class where you want to "paste" its contents, but they will then be inherited from there, so you can have a handful of unrelated "base classes" all sharing a set of methods "pasted" from the same trait.
On the other hand, you might want to create a sub-class which takes an existing class and adds some methods using a trait.
More complex cases would require you to patch the source code of classes themselves. For instance, using a custom autoloader and https://github.com/nikic/php-parser to parse and manipulate class definitions before they are compiled. For instance, this just-for-fun sweary library installs as a Composer plugin and loads classes via a stream wrapper which removes restrictions such as "final".
Why not use a trait?
Unfortunately I haven't heard of anything like what you need in PHP.
<?php
trait Obj
{
static function test() { return 42; }
}
class User
{
use Obj;
}
echo User::test(); //prints 42
Hope this helps.
Sorry if this is a duplicate question or a common design principle, I have searched around but was unable to find any answers to this question. I'm probably just searching with the wrong keywords.
I have been looking at a popular library Sabre/Event (https://sabre.io/event/) and in the code there is a simple class/inheritance model that I am trying to understand:
The class EventEmitter implements EventEmitterInterface and uses EventEmitterTrait (see below for code).
There is a comment in EventEmitterTrait above the class which says:
* Using the trait + interface allows you to add EventEmitter capabilities
* without having to change your base-class.
I am trying to understand why this comment says this, and why it allows adding capabilities without changing the base class, and how that is different from just putting the routines into EventEmitter itself.
Couldn't you just extend EventEmitter and add capabilities in the derived class?
Simplified code:
// EventEmitter.php
class EventEmitter implements EventEmitterInterface {
use EventEmitterTrait;
}
// EventEmitterInterface.php
interface EventEmitterInterface {
// ... declares several function prototypes
}
// EventEmitterTrait.php
trait EventEmitterTrait {
// ... implements the routines declared in EventEmitterInterface
}
You're basically asking two questions here.
What are interfaces and why are they useful?
What are traits and why are they useful?
To understand why interfaces are useful you have to know a little about inheritance and OOP in general. If you've ever heard the term spaghetti code before (it's when you tend to write imperative code that's so tangled together you can hardly make sense of it) then you should liken that to the term lasagna code for OOP (that's when you extend a class to so many layers that it becomes difficult to understand which layer is doing what).
1. Interfaces
Interfaces diffuse some of this confusion by allow a class to implement a common set of methods without having to restrict the hierarchy of that class. we do not derive interfaces from a base class. We merely implement them into a given class.
A very clear and obvious example of that in PHP is DateTimeInterface. It provides a common set of methods which both DateTime and DateTimeImmutable will implement. It does not, however, tell those classes what the implementation is. A class is an implementation. An interface is just methods of a class sans implementation. However, since both things implement the same interface it's easy to test any class that implements that interface, since you know they will always have the same methods. So I know that both DateTime and DateTimeImmutable will implement the method format, which will accept a String as input and return a String, regardless of which class is implementing it. I could even write my own implementation of DateTime that implements DateTimeInterface and it is guaranteed to have that method with that same signature.
So imagine I wrote a method that accepts a DateTime object, and the method expects to run the format method on that object. If it doesn't care which class, specifically, is given to it, then that method could simply typehint its prototype as DateTimeInterface instead. Now anyone is free to implement DateTimeInterface in their own class, without having to extend from some base class, and provide my method with an object that's guaranteed to work the same way.
So in relation to your EventEmitter example, you can add the same capabilities of a class (like DateTime) to any class that might not even extend from DateTime, but as long as we know it implements the same interface, we know for sure it has the same methods with the same signatures. This would mean the same thing for EventEmitter.
2. Traits
Traits, unlike interfaces, actually can provide an implementation. They are also a form of horizontal inheritance, unlike the vertical inheritance of extending classes. Because two completely different class that do not derive from the same base class can use the same Trait. This is possible, because in PHP traits are basically just compiler-assisted copy and paste. Imagine, you literally copied the code inside of a trait and just pasted it into each class that uses it right before compile time. You'd get the same result. You're just injecting code into unrelated classes.
This is useful, because sometimes you have a method or set of methods that prove reusable in two distinct classes even though the rest of those classes have nothing else in common.
For example, imagine you are writing a CMS, where there is a Document class and a User class. Neither of these two classes are related in any meaningful way. They do very different things and it makes no sense for one of them to extend the other. However, they both share a particular behavior in common: flag() method that indicates the object has been flagged by a user for purposes of violating the Terms of Service.
trait FlagContent {
public function flag(Int $userId, String $reason): bool {
$this->flagged = true;
$this->byUserId = $userId;
$this->flagReason = $reason;
return $this->updateDatabase();
}
}
Now consider that perhaps your CMS has other content that's subject to being flagged, like a Image class, or a Video class, or even a Comment class. These classes are all typically unrelated. It probably wouldn't make much sense just to have a specific class for flagging content, especially if the properties of the relevant objects have to be passed around to this class to update the database, for example. It also doesn't make sense for them to derive from a base class (they're all completely unrelated to each other). It also doesn't make sense to rewrite this same code in every class, since it would easier to change it in one place instead of many.
So what seems to be most sensible here is to use a Trait.
So again, in relation to your EventEmitter example, they're giving you some traits you can reuse in your implementing class to basically make it easier to reuse the code without having to extend from a base class (horizontal inheritance).
Per Sabre's Event Emitter's docs on "Integration into other objects":
To add Emitter capabilities to any class, you can simply extend it.
If you cannot extend, because the class is already part of an existing
class hierarchy you can use the supplied trait.
So in this case, the idea is if you're using your own objects that already are part of a class hierarchy, you may simply implement the interface + use the trait, instead of extending the Emitter class (which you won't be able to).
The Integration into other objects documentation says:
If you cannot extend, because the class is already part of an existing class hierarchy you can use the supplied trait".
I understand it's a workaround when you already have an OOP design you don't want to alter and you want to add event capabilities. For example:
Model -> AppModel -> Customer
PHP doesn't have multiple inheritance so Customer can extend AppModel or Emitter but not both. If you implement the interface in Customer the code is not reusable elsewhere; if you implement in e.g. AppModel it's available everywhere, which might not be desirable.
With traits, you can write custom event code and cherry-pick where you reuse it.
This is an interesting question and I will try to give my take on it. As you asked,
What is the purpose of using traits to define functions for an interface ?
Traits basically gives you the ability to create some reusable code or functionality which can then be used any where in your code base. Now as it stands, PHP doesn't support multiple inheritance therefore traits and interfaces are there to solve that issue. The question here is why traits though ?? Well imagine a scenario like below,
class User
{
public function hasRatings()
{
// some how we want users to have ratings
}
public function hasBeenFavorited()
{
// other users can follow
}
public function name(){}
public function friends(){}
// and a few other methods
}
Now lets say that we have a post class which has the same logic as user and that can be achieved by having hasRatings() and hasBeenFavorited() methods. Now, one way would be to simply inherit from User Class.
class Post extends User
{
// Now we have access to the mentioned methods but we have inherited
// methods and properties which is not really needed here
}
Therefore, to solve this issue we can use traits.
trait UserActions
{
public function hasRatings()
{
// some how we want users to have ratings
}
public function hasBeenFavorited()
{
// other users can follow
}
}
Having that bit of logic we can now just use it any where in the code where ever it is required.
class User
{
use UserActions;
}
class Post
{
use UserActions;
}
Now lets say we have a report class where we want to generate certain report on the basis of user actions.
class Report
{
protected $user;
public function __construct(User $user)
{
$this->user = $user
}
public function generate()
{
return $this->user->hasRatings();
}
}
Now, what happens if i want to generate report for Post. The only way to achieve that would be to new up another report class i.e. maybe PostReport.. Can you see where I am getting at. Surely there could be another way, where i dont have to repeat myself. Thats where, interfaces or contracts come to place. Keeping that in mind, lets redefine our reports class and make it to accept a contract rather than concrete class which will always ensure that we have access to UserActions.
interface UserActionable
{
public function hasRatings();
public function hasBeenFavorited();
}
class Report
{
protected $actionable;
public function __construct(UserActionable $actionable)
{
$this->actionable = $actionable;
}
public function generate()
{
return $this->actionable->hasRatings();
}
}
//lets make our post and user implement the contract so we can pass them
// to report
class User implements UserActionable
{
uses UserActions;
}
class Post implements UserActionable
{
uses UserActions;
}
// Great now we can switch between user and post during run time to generate
// reports without changing the code base
$userReport = (new Report(new User))->generate();
$postReport = (new Report(new Post))->generate();
So in nutshell, interfaces and traits helps us to achieve design based on SOLID principles, much decoupled code and better composition. Hope that helps
As I looked for the new PHP7-features I stumbled upon anonymous classes.
I didn't understand when they should become useful, and looked for an example.
I read this article, but I don't see the benefits of this feature.
In the last section before the conclusion they wrote the following about the advantages:
One advantage is that we no longer need the named extension. Normally the named extension would be hidden away in some included file, if you ever needed to see how it is defined you have to start searching for it. With anonymous classes the definition is in the same place the object is created.
On the other hand, I see a big disadvantage because you can use this anonymous class only at the place it is defined.
Can someone please explain when this feature is useful?
Especially if it can help when building custom systems or extending a CMS like WordPress (preferably in German, although English is also welcome).
Anonymous classes could be useful in writing implementation classes for listener interfaces, so you don't need to create a file or a generic class just to implement once.
One of the most elegant things about anonymous classes is that they
allow you to define a one-shot class exactly where it is needed. In
addition, anonymous classes have a succinct syntax that reduces
clutter in your code. Java in a nutshell
So, you can have an anonymous implementation of an interface or even extend a class, with additional properties or overwritten methods.
Example:
return new class(10) extends SomeClass implements SomeInterface {
private $num;
public function __construct($num)
{
$this->num = $num;
}
};
Another situation:
Provide a simple implementation of an adapter class. An adapter class is one that defines code that is invoked by some other object. Take, for example, the list() method on a class called File. This method lists the files in a directory. Before it returns the list, though, it passes the name of each file to a FilenameFilter object you must supply. This FilenameFilter object accepts or rejects each file. When you implement the FilenameFilter interface, you are defining an adapter class for use with the $file->list() method. Since the body of such a class is typically quite short, it is easy to define an adapter class as an anonymous class.
$file = new File("/src");
// Now call the list() method with a single FilenameFilter argument
// Define and instantiate an anonymous implementation of FilenameFilter
// as part of the method invocation expression.
$filelist = $file->list(new class extends FilenameFilterClass {
public function accept(File $f, string $otherInfo) {
return pathinfo($f, PATHINFO_EXTENSION) === ".php";
}
});
Some nice basic understanding and use about anonymous classes could be found on Java (I know its not PHP, but it helps on understanding) examples at https://www.geeksforgeeks.org/anonymous-inner-class-java/
I should use a anonymous class only if this class is not used anywhere else and if these class isn't changed since the first coding.
So for example a database class could maybe a candidate for using a anonymous class because it should be use only once and could be included in any other php file. In most cases the data for accessing the database is in the config file. Therefore this file should be loaded for every php file that is using the database when you want to avoid the hard coding of the database params (which is a bad idea). If you coded these class as an anonymous class in the config file you have eliminated one include whithout losing the maintainance.
I am trying to build my own MVC framework (of course to learn it better) by following latest OOP design pattern. I was wondering, what is the best practice for placing repeatable codes (which are used to stay in the utility classes as static methods, which is consider not a good patterns).
For example, we want to traverse an multi dimensional array using dot separated string, and I have to utilize this algorithm in several classes (which are subclasses from other base classes). How can I do that without using utility class and without repeating the same code multiple times?
If those are utility functions, then define them as such in a separate namespace. Something akin to
<?php
namespace Utils;
function array_query($array, $query) {
// code for traversing the array
}
Put them in one or multiple files and you will be fine. Just remember to include that file in the boostrap stage of your app.
Bottom line: stop abusing static classes, we have namespaces for that sh*t now.
But, not all of what you think of as "utility functions" are actually. Some of the code, if you start using OOP code, should go in the associated classes. For example "email validation" should not go in a "utility function" but in a class:
class EmailAddress {
private $emailAddress;
public function __construct($emailAddress) {
$this->assertValidEmailAddress($emailAddress);
$this->emailAddress = $emailAddress;
}
private function assertValidEmailAddress($emailAddress) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new DomainException("Not an email address");
}
}
public function __toString() {
return $this->emailAddress;
}
}
And these kind of repeated "domain logic" fragments should go in separated entities, which then you can type-hint for other classes. Then you utilize it somewhere as:
public function register(EmailAddress $email, SafePassword $password): User
{
// your user registration logic
}
This way various services of yours can perform activities and you use try-catch for improved validation.
P.S.
You might need to take a hard look at what you are doing. That dotted access utility is neat (I had it too like 10 years ago), but actually is is a "temporary fix" for a deeper problem: you shouldn't be dealing with so deep array, that you need to simplify accessing them.
There's nothing wrong with a utility class, just don't lump all your unrelated utility functions into a single giant class. Separate (and namespace) them by what they do. For example, see Zend Filter or Symfony Filesystem.
Alternatively, if the classes that need this function all have a common parent, you can put the function in the top-most class or abstract.
Or if the classes do not have a common parent, you could create a Trait with a method called extractArrayFromDottedString() or similar.
Laravel does this by defining standalone "helper" functions. CakePHP and Yii do it by defining container utility classes (i.e. "Text" or "Xml") with static methods. Programming languages do similar things (i.e. PHP's implode(), Java's Math.round, C's strcpy, Python's sum(), etc.). Pretty much everything uses either standalone functions or static class methods.
Ultimately, the best choice is subjective. It depends on how you want to structure things. Research common design patterns in PHP, and get a feel for how different frameworks feel in practice. Then pick an approach and stay consistent.
Utility class is an anti pattern
Really not.
In OOP, designing the whole application with utility classes is very probably an anti pattern but defining utility classes wit static methods that provide routine/transverse tasks may make sense.
Not mixing utility methods with methods of existing classes that consume them may also provide a better cohesion and reusability of the utility class and consumer classes.
Of course as alternative you could define a class with instance methods.
This is valid, more verbose but has as advantage to improve the class testability. If you need to mock the invocations or to switch to other implementations for utility methods, instance methods have to be favored.
I am trying to improve my knowledge of OOP in PHP and have been researching abstract classes and interfaces.
What I have learned
They are both classes that cannot be instantiated themselves but can olny be extended (implemented in the case of interfaces)
Abstract classes provide methods and properties for other classes that extend them.
If a class uses an abstract method then the class itself must also be abstract.
If an abstract method is defined within an abstract class, all child classes must define the details of that method. Methods not defined as abstract can be used in the same way as normal methods.
Interfaces define what methods a class that implements it must have. The functionality of the methods are not defined in the interface, the interface just offers a list of methods that must be included in the child class.
An interface does not define any properties.
Classes can implement as many interfaces as they want to but they must define a method for every one of the interfaces they implement
I think that covers the basics. Please feel free to add to that if you think there's anything I have missed.
What I would like to know is if there are any real world examples of implementation of these classes, especially the interface class. Does anyone know of any open source applications that use them that I can browse to better understand them and see where and when they are used effectively? I have come across book examples which use animals which fails to demonstrate the importance of these classes.
The final keyword prevents the class being extended by other classes, example:
class Parent
{
}
class Mother extends Parent
{
}
final class Brother extends Mother /* - This class cannot be extended - */
{
}
class Pet extends Brother
{
}
The Pet class will throw an error stating: Fatal error: Class Pet may not inherit from final class (Brother)
This is also available for methods, so if you do not want to allow the methods to be inherited causing the child class to have the same method acting as an override.
http://php.net/manual/en/language.oop5.final.php
Yo used that you would like some real world examples of what interfaces can be used for, well a database abstraction layer
You have 1 base class which provides the basic methods to iterate your database data, but that would use a sub class for the the database type, such as MySql,MsSql etc, each database type would have its own class, but for the base class to make sure that it has these methods they would all implement the same interface.
Example
interface IDatabaseLayer
{
public function connect();
public function query();
public function sanitize();
//...
}
So the base class knows that MySql and MsSql have the above methods, thus reducing errors and being more organized.
When passing in objects to classes you want to be sure that the Object is of a certain type, PHP5 allows you to define what type of object should be passed into the methods as params.
lets say you have 3 classes
DatabaseCredentials
DatabaseConnection
DatabaseQuery
you can specifically define in the constructuin of DatabaseConnection that you require a DatabaseCredentials class like so:
class DatabaseConnection implements Connectable
{
public function __construct(DatabaseCredentials $ConnectionDetails)
{
$this->Connect($ConnectionDetails->BuildDSN());
}
}
A good way to really get started is by reading here:
http://php.net/manual/en/language.oop5.php
Another feature of PHP5 you may wish to look at is name spaces, this will allow you to keep your code organized, have multiple objects with the same name, makes auto loading more efficiently
Small Example:
namespace Database\MySql
{
class Database{}
}
namespace Database\MsSql
{
class Database{}
}
And you can just use like:
use Database;
$Database = new MySql\Database();
PHP comes with few interfaces predefinded by default: http://www.php.net/manual/en/reserved.interfaces.php
PHP also contains Standard PHP Library (SPL), which defines more:
interfaces http://www.php.net/manual/en/spl.interfaces.php
classes, including abstract ones: http://www.php.net/manual/en/spl.datastructures.php
Zend Framework is also very good example where such concepts are used. http://framework.zend.com/
Not a real world example as such, but one Design Pattern where you usually encounter interfaces and abstract classes is the Command Pattern. See link for example code.
In general, "programming against an interface" is considered good OO practise, because it decouples concrete implementations and let you more easily change them for other implementations, e.g. instead of asking for a specific class
public function fn(ConcreteClass $obj)
{
$obj->doSomething()
}
you just ask that it provides a certain set of methods
public function fn(MyInterface $obj)
{
$obj->doSomething()
}
Interfaces also help teasing apart large inheritance structures. Because PHP supports only Single Inheritance, you'll often see hierarchies like this:
BaseClass -> Logger -> Auth -> User
where each of these contains specific aspects used inside these classes. With an interface, you just do
User implements Loggable, Authenticable
and then include that specific code via Strategy Patterns or Composition/Aggregation, which is ultimately much more maintainable.
For a list of predefined interfaces in PHP see my answer to:
where to find "template" interfaces?.
You may follow the "PHP patterns" series by Giorgio Sironi in dzone or directly in his blog, really interesting if you are interested patterns and OOP.
Also you could take a look to the Best PHP programming book in stackoverflow if you're in need of a good PHP book.
We can say that interface is purely 100% abstract class but abstract is not. Because many time we defines function in abstract class. But in interface class we always declare function.