Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

2.5 Anonymous Classes

Classes without names... they're more useful than you might think. You'll learn what they are and when you should use them in this lesson.

2.5 Anonymous Classes

The idea of an anonymous class might seem a little weird, but the concept isn't new to PHP. Languages like C# and Java have had anonymous classes for quite some time. And PHP's implementation is pretty much complete. You can create an anonymous class with properties and methods. It can implement an interface or extend a base class and it can also use traits. So let's start by looking at how to create an anonymous class. The syntax is a combination of creating an instance and defining a class. So we start with the new keyword, followed by class and then a pair of curly braces and we've just defined an anonymous class. Now the name anonymous class is somewhat of a misnomer, because what we end up with is an instance of the class that we have defined. So we could actually do something like this. Let's say that we have a class that we need to define for our application so that we can log whatever it is that we need to log. Now, this is the type of class where you usually just create a single instance and then you use that instance wherever you need to within your application. So in our case, it really doesn't make a whole lot of sense to define a new class, put it inside of a file and then use that class whenever we need to. Instead we could just create our object here and then pass that object to whatever needs are logger. And that's one of the big uses of an anonymous class. When you need a very simple class but you don't need to create multiple instances of the class. And it doesn't make sense to define a class inside of another file, then an anonymous class is a perfect candidate there. So we are creating a new object based upon this class that we are defining. This is a logger, so let's have a function called log and, of course, we would want to do some pretty important stuff here. But for our purposes, we're just going to output some data. This is the log method. So that then we can call this log method from our logger object. And whenever we run this we're going to see the message, this is the log method. So there we go. Now, this is a complete class but we can also add some things that we might need for a normal class. One of those would be a constructor, so let's define a constructor. We'll have a public function_construct and let's accept some data. I don't know what that data really needs to be in this particular case, so we're just going to to do this. We're going to say this->data = $data, so that we can pass whatever we wanted to to this constructor. And whenever we create an instance of this anonymous class, we call the constructor by essentially calling the class keyword, or at least that's what the syntax looks like. So we have a new class and then we pass in whatever value that we want for our data. So that can be somebody's name, or that can be a numeric value. It can be anything that this particular class needs. So we're just going to stick with a numeric value. And let's add that to our output so that this is the log method and data =, we'll just concatenate this data. So whenever we run this again, we should see the same message that we saw before but now we see that and data = 1000. So we have not only created a class but we have defined a class that has a constructor. We have passed data to that constructor. But let's also think about what we're doing here. We are creating an object that is essentially used for logging. And in a perfect world, our applications could say that that's great that we have something to log. But I want to control what that type of object is, or at least I want to control the interface of that. So we can say that our application needs an instance of an object that implements ILogger, and ILogger will have a method simply called log. So whenever we define our anonymous class, we can new up class, we pass in our data, and then we simply say implements whatever interface that we want. So in this case that is ILogger. So, of course, whenever we run this code, we're going to see the same results that we had before. However, if we change our interface, let's say that instead of a method called log, it's called log2. Well now if we try, we see that we have an error because our anonymous class does not correctly implement the ILogger interface. Let's also say that, okay, we have a base class that we want you to inherit from for our logger. So we could say that we have a base class called Logger or LoggerBase or BaseLogger, whatever you want to call it. In which case we would want to extend that base class. So instead of implementing this ILogger, we can say extends and then LoggerBase. And instead of calling the log method, let's do this. Let's var_dump and we will say logger instanceof LoggerBase. And whenever we run this, we are going to see that we have a value that is a boolean and it is going to be true. And then finally, if we had some traits that we wanted to use within our anonymous class, all we would need to do is, inside of the class definition, use whatever trait that we want to use. And we are good to go. So the idea of an anonymous class could seem weird, but as I mentioned before, this is the type of class that you would want to use whenever you need a class to do something. But you aren't going to create multiple instances of that class. You just need a single instance, you don't really need to define a complex class and put that inside of another file. So instead, you can use an anonymous class. You can define that class in line and use that in your code. And it's also very useful for testing. Instead of creating complex mocking APIs, you can just create an on-the-fly implementation for your interfaces and you're good to go. So it's an all-around wonderful feature.

Back to the top