Example Lesson Videos - Advanced PHP for Drupal 8: Object Oriented Programming: Interfaces (Part 2 of 2)

  • Lesson Notes
  • Playlist
  • Transcript
Lesson Notes
These are two example lesson videos pulled from our Advanced PHP for Drupal 8.

See Full Course Syllabus and Schedule

Example Code For This Course

All the example code you see me using in this course is available as a git repository. This allows you "checkout" different versions of the code to move to any point in the course. Your primary assignment each week is to follow along with creating the modules you see me create in the lesson videos. You have two ways you can do this. Personally, I prefer to copy and type out the programs I see on screen, because I find it helps me remember things better. However, this can be fairly time-consuming, so there is a second option. Since I have provided many different versions of the code in the example git repository, you can watch the videos, and when you get to a checkout point (there will be an on-screen prompt), checkout that version of the code, read through it, and run it to confirm you understand what you've just watched. That will take less time, but I will leave it to you to decide how you learn best. Be sure you perform the clone operation in the correct folder, depending on whether or not you want to copy the code yourself or just use the example code to follow along. I discuss the appropriate locations in the code repository video.

Frequently Asked Questions

Do the lesson videos play on iPads and iPhones?

Yes, they work on both desktop/laptop computers and iOS devices.

How can I ask questions or get help?

You can ask questions about the lesson or get help with your assignment by posting to the class discussion forums and attending the weekly live Q&A sessions with the instructor. (online via webinar software)

Do I need to have my own website or hosting account to work on?

No, we will provide you with a development environment you can install on your computer. Installation and configuration of the local development is covered step-by-step in course lesson videos.

Playlist
Transcript
In this video, I'm going to discuss interfaces in PHP. Interfaces are an object-oriented programming concept. They're usually described as contracts between different parts of the system. Interfaces allow you to specify what the public methods for a class will be, even before that class is written. And so these interfaces are typically used when you are going to have many different classes that need to behave in a similar way, and so the interface describes what their common behavior will be. Interfaces are used extensively in modern object-oriented programming for a few reasons. I think the most important are, if you have multiple developers working on a project, each developer can focus on their own subsystem of the project, and so if for example these two subsystems that two different developers are working on, they need to interact with one another, they can define an interface at the beginning of the project, and then go off into their own separate development environments, work on their own separate subsystems without having to coordinate all of the implementation details between the two of them, as long as they both conform to their interface, the contract of how their subsystem will behave with the rest of the project. Then those two subsystems and those two programmers should be able to work together without a lot of back and forth. So that's one reason that interfaces are used. The second is sort of an extension of that which is when you have modern frameworks, and so in PHP this might be something like the Symphony Framework or Code Igniter or even content management systems like Drupal or WordPress, the system gets built first, and then afterwards, people come and they add some plugins or modules to the framework to change the behavior or to create some particular implementation of behavior in with those frameworks. And so in that case, the second developer is actually coming after the entire system has been developed. And so they need a way that they can write a new code presented to the system which is already developed in which it won't be changed in a way that that would just work and interface allows that to happen because as long as the new developer who's writing that plugin or module conforms to a particular interface, okay, it creates kind of a standard, this contract. As long as they conform to that interface then their code should work with the existing code that's already in the framework. And so interfaces make these kind of plugins and modules possible, and in some cases they also allow the sort of implementers who come later with these Frameworks to exchange whole subsystems of the frameworks using a process called dependency injection. Now, we're not going to get into the frameworks or dependency injection in this video. I'm just going to focus on what interfaces are and how you implement them in PHP. So we'll be continuing the scenario that we've been working on for the series of videos about object-oriented programming. So in that scenario, we have a business review system where we can add businesses. We have different types of businesses in our system. We started off with restaurants, but we extended that with inheritance so that we could do different types of businesses. So we have accountants and plumbers in our system. We have reviews in our system that they're scored reviews where people get an integer value out of 10 for some review that they get. And now what we want to do, let's say we've been asked to extend the system so that it supports different review types. And in particular, we want to support text-based reviews. Now, these won't be score and text. These will be completely separate so there'll be certain reviews that have scores like they have now, and there'll be different reviews that are just text, just like a comment. And so the system needs to support both and we've also been asked to design the system with the idea that there'll be more review types coming in the future that we need to be able to adapt to. And so how can we design the system both to implement the particular text review task that we've been given, and make it flexible so that in the future, we can easily add new review types without a lot of extra coding work? So interfaces can help us accomplish this, and they can do that by... we will specify an interface that is the expected behavior of a review class. And then we will be able to implement multiple review classes that conform to that behavior as it's specified in the interface. So our first step will be to decide what the contract will be. What is it that we need, what behavior do we need all reviews to provide in order to use our system? So if we go back and we look at sort of the core processing loop which is here in index.php of our system, what is it that we actually need the reviews to do? Well, down here in the section where the reviews get printed, if we focus on that, we can see that our reviews, one thing we do is we check to see if a review is for a particular business. So we're definitely going to have to have a way that we can tell which business a review is for. And so we'll probably need something like this getBusiness method that we have now. And then the second thing we do is we print out - and in this case we print out the score, and we print out the max score for our current integer value reviews. Now, we're going to change this because we know that the text reviews aren't going to have a score. But this functionality is, we need, if we can just abstract it a little bit, what we need is a way to generate a string that we can display to the user to show the value of this review. So in the case of a score that would be these integer values of the score and the max score, but in the case of the text, it would just be the text of the review. So the two key pieces of functionality we need are probably a get business method, and I'm going to call the second method the, get display string method, because I think that that will sort of abstract enough that we'll be able to implement many different types of reviews with that. So now that we've decided what the core functionality will be, we are ready to create an interface to describe that functionality to PHP. So we do that by creating a new file. I'll call the file Reviewinterface.php, and then let me paste some code in. All right, so here is our review interface. So let's go through this and see the parts of it. So you can see it kind of looks like a class file. It has the namespace line just like a class file has. It has a... in this case, it has a use line because we're going to need to use the Business class down here, and then when we get into the core part of the interface, it has the keyword interface followed by the name of the interface. Now you'll see that I used... I called this ReviewInterface. You don't have to have the word 'interface' in the name of your interface. That's just a convention that I like to follow, because then it makes it easy when you're browsing through or if you're doing some sort of autocomplete in your IDE, it's easy to tell which ones are the interfaces versus the classes. But that's just totally up to you, stylistically. So I have: interface ReviewInterface and then I have the curly brackets. So again, this is similar to a class, and then I have my methods defined down here. I've got typing hinting for the comments; that's the same like a class. My method signature is the same like I would do in a class. Just public function and the name of the method of... name of the function or method followed by a parenthesis. Now, the one thing that is different is, instead of having the curly brackets, I just have a semicolon at the end of each of these lines. And the reason is, remember this interface is not going to do any implementation. It's just the contract. It just describes which methods that the classes that implement this interface must provide, but it doesn't do any code work. It doesn't provide any actual code or implementation details. So that's why we don't have any curly brackets or any code in there. We're just defining what the methods will be. And so that's all we need to do to create the interface. Now, we're ready to go to our review class and implement this particular interface in the review class. Let's start with the current scored review and get that entirely working. And then we'll come back at the end and add the new text review functionality. So let's save this and then we'll go over to the review class, and the first thing I'm going to want to do, this word 'Review' is too broad. We know that there's going to be a lot of different types of reviews, so let's be specific about what kind of review this is. So this is going to be a score review. So I'm going to change the name of the class to ScoreReview, and because we want our autoloading to work correctly, we also need to change the name of the file. Remember the name of the file must always match the name of the class. So I'm going to rename the file to ScoreReview, as well, so that it matches with the class. And now I'm ready to implement the interface, and the way I do that... actually, actually, I should probably bring the interface into the system first with a use statement. And then I'll come down here and to the class line I write: implements ReviewInterface. All right, so I just added this implements review interface on the end of the class line, and that's all that's necessary. You can think of this as sort of signing the contract. All right. This review interface is a contract that we will provide these methods, and when you add this line, implements ReviewInterface, you are signing it and saying this class agrees to do that. Now, as soon as I signed that contract, you'll notice that NetBeans gave me an error message over here or there's a little red line underneath the word 'ScoreReview'. I'll have hover over this, this very small text. So you may not be able to see in the video, but what it says is that we have not created the method get display string. So NetBeans can already see immediately that we signed a contract, but we haven't done what we said we were going to do. So we need to come down here and add a new method. We can actually copy the method's signature from the review interface. And then instead of the semicolon here, we actually need to provide the functionality. So we want to provide functionality that's similar to what we had over here. So over here we had Score colon... we got the particular score of the max score. So let's create a string like that as our display string. So we'll return Score: and then concatenate with this ->score of, and then we need to get the max score from this class which we can do with the self keyword. All right, so this should give us a similar type of string, score, the current score of whatever the max is for this particular object, this particular review. So we'll save that and then we need to go back to index.php and make some changes here. So instead of specifically looking at the score, let's add code that uses the display string method. So this code will print out the display string from the review which hopefully should be the same type of string we had before. And finally, we need to go into bootstrap.php. Because we... Because we changed the name of this class, we need to update that all throughout this part. So I'm just going to replace the word 'Review'. Okay, so now we've changed all of the Review lines so that they're ScoreReviews. And then we brought in the ScoreReview class to bootstrap. So that should be everything we need to switch the system around so that it now uses the review interface. We haven't implemented any new behavior but we've gotten the system ready for new behavior. Let's check to make sure it works before we move on. Okay, so when I refresh this, everything looks exactly the same. Now, we're ready to implement the text review functionality, and so I want you to pay close attention as we go in here to exactly which files we have to change in order to do that. So, all right. So we're ready to create the text review. We'll need to create a new class, so we'll create a new file, TextReview.php. And then in this file, we'll start with namespace, Bitwisdom\Reviews. We're going to need to use the business class and the review interface, and then we're ready to write our class. This is class TextReview. It implements, ReviewInterface. And then it will have a couple properties. We'll need a property to hold the text of this review, and we'll need a property to hold the business that this review is about. So let's add some comments here. The text will be a string, the business will be a type business, and now we can use NetBeans actually to help us write some of the rest of the code. So if I go here to source, insert code, I can choose override and implement the methods, and you'll see that it actually pre-checks getBusiness and getDisplayString, because it knows that I have to provide those methods as part of the review interface that I'm implementing. So I'll click okay, and it gives me sort of the initial setup here. So we can: return this-> business from here, and then for the display string, let's have it: return comment: this->text. And let's just finish this out by providing the right type hints that we should, and we're going to need some getters and setters and constructors. So again, let's have NetBeans do that work for us. So we'll do the constructor. We'll need both the text and the business in there. So that looks good. And then let's add the getters and setters for text, and we can just add the type hinting here to say this will be a string. And then we're done. All right, so now we have created this text review class. There's only one more step that we need to do which is in bootstrap.php, I'm creating all these score reviews. I need to add in some text reviews. So I'm going to paste in some code that I have in another window. And so now this system has both score reviews and text reviews. Oh, actually, I've missed one line here. I should put a use statement in here to bring in the text reviews, the TextReview class. And now my bootstrap is going to load up a bunch of different reviews of both types. So I'll save this. And now I want you to notice that at no point have we edited our index.php file. All right. In our simplistic example here, the index.php is sort of our core code. You can think of it as being the framework. When we added this new text review, we didn't have to edit it. All we did is we created one new class, and then I did change the bootstrap only because I wanted to create some new text reviews, but in a typical framework environment, just this class is all you would have to write. So let's go and make sure it works. If I refresh you will see that it works great. The comments, the text reviews are coming in here, and they're behaving just like the scored reviews. And again, we did all that without having to edit our core code of index.php. So at this point we have created an extensible system where you know, if the boss comes in tomorrow and says we need another review type, all we would have to do is create one new class to handle that review type. And so that's really the power of interfaces. We wouldn't have to worry about changing anything in the core code. And so that's really the power of interfaces and why they are so commonly used in modern object-oriented programming.