 Gwiswm! ...a gweithio ar gyfodol, if any time if there is anything you want to ask or you want me to explain. I am going to start with the most important question, which is, what is object-oriented programming? I think that, in the Drupal community, this is a term you have been hearing quite a lot. Over the last however many years you've been developing Drupal 8. Object Oriented Programming is something that bothers me. Object Orientation is the computer science of long words. Object Orientation is perfectly simple concepts, dressed up to sound as if you might not be able to understand them. I dispute that, I think you can understand them. I think if you hear you're a programmer and I think I can teach you Object Oriented Programming within the next 60 minutes. So, let's start by dealing with some of those long words. Here is a glossary of long words you might hear associated with Object Oriented Programming. The things we call methods, they are functions. Would you please raise your hand if you know how to write a function? Okay good, you're ready for Object Oriented Programming. Methods, take parameters, some of them can be optional, they return values. Guys, we're good, there is no problem here. Properties, we call those variables. It's all good, again you assign things to them, they store stuff. A class is the recipe for making an object. So the class is the code that you write that describes how the object is going to look when you make it. The object is what we actually make. Except we don't say make, we say instantiate. Yeah, make, we're all good. So now we've covered the basics and I've explained to you what Object Oriented Programming is, unnecessarily long words. Then let's talk about why it's important. I do think it's important. My background is that I have been doing PHP for long enough that I started out with mostly functions. I remember meeting an object for the first time. I also understand and deeply respect what great things were built by Drupal people without an object in sight. It is clear to me that you do not need objects to achieve great things. That said, they're pretty cool. They make things much, much easier and I think you'll like them. Object Oriented Programming gives us encapsulation, which is, guess what, another big word. But this big word means putting together some useful stuff all in one place. So in Object Oriented Programming, our variables become properties where we might have had an array of values associated with a thing. Now they are properties on an object. They really look a lot like array elements and you can still think of them like that. Where once you might have had functions and for a given module all the functions would have the same prefix. Now we just put those methods into the same class. The code inside them doesn't look all that different. The stuff you already know really, really still applies. So we take these properties, the data that goes with the thing, whatever the thing is, and we take these methods, the functions, the features that you write and we put them together in an object. So you have the data and the functionality in a single thing. So now you've got everything encapsulated in one place and so you can say, right you, go over there, sort yourself by date and output the first five records, go. No other code needs to be involved. You delegate responsibility to a thing, technical term, object, that has both the data that it needs and the functionality required to perform this stuff. So where you are used to seeing an array of data, I know that you sometimes put them in standard classes. They're still basically just collections of data. And you have some functions all prefixed with the same thing because they're in the same module. We're just going to put them in the same place and we're about object-oriented programming. Woo! And we win. So, so far we've established that the knowledge that you already have is transferable. There are some other nice perks that come with object-oriented programming. Let me tell you about auto-loading. Auto-loading means you'll never write another required statement. You'll never wonder whether this module is already included or not because PHP will just find it and load it when you need it. You'll only ever find and load the code that is actually needed. So you won't be loading database libraries, internationalisation, the big user preferences thing. I don't know anything about Drupal, but I'm sure you have one of those big user customization things. A few people are nodding. Good. You won't load any of that when you're just showing the thanks for signing up to the mailing list page because you don't need it. So never be auto-loaded. Your pages will never include stuff that they don't need. It works something like this. I hope you can read the text. First of all, we don't include or require anything. We just plow on regardless. When we want to use a class, we just use the class. PHP is like, mmm, do I know about this class? If we know about the class, that's fine. We carry on. If we don't know, PHP runs the autoloader. The autoloader does its magic, and then PHP is like, now do we know? And if we know, then we just carry on. If we use the same class again later, it's already loaded. It's only if PHP runs the autoloader and doesn't find your class code will you see an error. So you just kind of unhook from your safety equipment. Start using those classes by name. Your autoloaders will find them. In order for PHP to be able to do this, there are a few things that we need to put in place to help it because PHP is way more stupid than you are. What we do is we need a really strict set of recipes that says, if I need this class, where should I look? So you can think of PHP as the most junior developer in your team on her first day at work. So she'll come and say, I need to edit this particular class. Where is it? And you will say, ah, you should look in this directory, that directory, and it will be called whatever. We need to do more or less the same thing for PHP. So we have some conventions. Each class goes on its own in a file. We never declare anything else in the same file as a class. We also have a really predictable set of rules that go from what your class is called to where in the directory structure your class will go. This lets autoloading work, and you can just move on. The prerequisites are a little bit more complicated than this. Drupal has recently adopted the PSR4 standard. So PSR stands for PHP Standards Recommendations. This is where all of the frameworks and all of the awesome, modern PHP tools in the world agree on stuff. And stuff number four is to do with autoloading and dictates exactly how you should name your classes, your files, your directories, your namespaces, and everything else. So if you like that sort of thing, you can read it in full. So how do we write an autoloader? I have established that everybody here knows how to write a function. This function accepts the name of the class that PHP should be looking for. So its incoming parameter is the class name that we're trying to load. Then you write the code that says look in the library directory. Inside that function you then require that file and return. That's it. You write a function that says given this class name, include this. So it might be, and if it's that male client that we've been using for years that doesn't use a sensible naming standard, if the class name looks like this, load this, otherwise, follow my rules. So you might have some logic in that autoloader. You can also register multiple autoloaders. But you write a function, and whatever the function's called, you feed it into this method here, SPL autoloader register. This goes at the top of index.php or your bootstrap or whatever, and then every piece of code that runs after this will know how to load classes. Good. Another reason that I love object-oriented php is it's extendable. I am sure that I am not the only person who has had a situation where this piece of code kinda almost does what I need, but not quite. So you end up with either a copy of a module or an extra parameter to every function to say, turn on the special flag. So there's an extra optional parameter and probably defaults to false, but you can turn it on to make some special functionality happen because most of the time, we do it this way, but there's one client that needs it with spots on, and so we load some extra stuff for them. In BHP, we have this ability to do similar but different with inheritance. When your entities are represented in an object, and you need an object that's a bit like this object, but not quite, then we can use inheritance. We take what we started with, which is most of what we need, we leave it alone for the stuff that it's good enough for, and we extend it, either replacing something or adding something to make it more useful for our own needs. We call this inheritance. So here's a real-world example. I have a perfectly good clickable button interface. I go to a client meeting, and the client says that dreaded sentence. Wouldn't it be cool if? And you're like, oh, not the reindeer at Christmas again. You know, the ones that they want, the JavaScript across the page, lots of nodding, brilliant, yeah. Wouldn't it be awesome if this perfectly good functional clickable button went ping when we clicked it? And you're like, no, that would be terrible. So yes, certainly, we can do that. And so you take your perfectly good clickable button class, and you extend it. You create a pinging button class. It extends clickable button. It gets everything that clickable button had that you had made that was so awesome and just adds a ping. So we can either add an extra method or we can re-declare and override something to change what happens in this class. So we've got this concept of a thing and something else which is it's not the same, but it's much like it. We get to this idea of pluggable code. We have one object, we have another object. They're quite similar to each other. We can replace one with another. This object's been in here doing its thing, working perfectly well for ages. Something's happened and either I don't know, we want to change mailing libraries or we're changing something else. I need a better example. Good. We can unplug one and put another one in its place. That's cool. What's really cool, the calling code doesn't care. You just change which object you send into that code. The code does not care that you just it's something different from normal. As long as the same interfaces are available, you can just switch them out without changing everywhere that this object is used as long as you're offering the same methods, then you can just replace it with a new one in. That's what's magic about object-oriented programming. It's very user-will. It takes your existing functionality, groups the data in with it in nice, good, and all of contained units. When this one is only 80% of what you need and that's not enough, or when you use the same stuff all the time but one client has something extra, you can just plug that in on top. You're not copying and pasting. If something changes, you just change it in one place and all of those similar items will inherit that change through inheritance. Okay, so I'm going to show you how to do these things in programming terms. If you are sitting in a place where you can't see the screen, I think my Twitter account has or will tweet this. My slides are on speaker deck. My username is Lorna Jane. If you either can't see the screen or if you would rather have the code in front of you because you're miles away, some of you, then feel free just to download it and you'll have it in front of you. So, how do we do that? It's a logic that I've just promised you that I said wasn't rocket science. How do we do it? Well, we'll start with a class. We'll create a class. We're going to put properties in our class. We're going to put methods in our class. And I'm going to start with a user class. So we use the class keyword and we give it a name. Remember that you'll store this class in user.php. So we put one class in one file. I've got two properties. One is username, one is email. They are both protected, which just means that things outside this class can't read and change these values. The only changes that take place will be done from inside the class. Next, we'll declare what's called the constructor. Now, the constructor is pretty interesting, so I'm just going to pause and talk about it. Its method name begins with two underscores. In php underscore underscore anything is a magic method. It's not sparkly, although that would be amazing. It's a magic method, meaning php calls it by itself. It gets fired in response to an event. There are lots of them. But underscore underscore construct gets fired when we instantiate the object. So this is your init method, basically. Call it underscore underscore construct and it will get run. You can put whatever parameters you want in here. Whatever you declare here in the constructor is the values that need to be passed into the object when someone makes one. Here, I have a lookup table. You might put this in the database for a more advanced example, but for three values I felt you could handle an array. So I've got a lookup table which has got people's email addresses in. You pass in someone's username and you look up their email address, store their username, store their email address. That's all the constructor does. So now I have a user object which represents a user. It's not just something which contains where the user functions are. When I call the functions, I'm not going to pass in any user information because that's already stored in this object. So this is the object that represents me. If I want one to represent you, I'm going to make another object, and another one. This is the rest of the user class. I've got enough here to make a simple website. First of all, public function, getUsername. This just returns the username value because I marked that property as protected. You can't just access it from outside. We call them getters. This is a getter to expose the username. So code outside this object can read this value by calling getUsername, but can't write it because the property is protected. We've also got a function called getGravitar. You may or may not know what gravitar is. It's an online service which lets you register an image against your email address and then use it on various social media type sites. I used it in my example just so you've got something prettier to look at. So what this does is it takes your email address, MD5s it, passes it to gravitar, this is how gravitar works, and you get the image back. Awesome. So, we're in a class. But we're not all the way there. We need to actually use it. First of all, let's register our autoloader. SBL autoload register, the thing that does the autoloading. This is an anonymous function, so I've declared the function in the place where I'm actually using it. There's nothing more about PHP Features tomorrow, New Wave PHP, come and see me in the auditorium. Please come and see me because I'm going to feel really silly if there's 10 people there. So again, we have a function that accepts the class name. Whatever class name I pass into this function, PHP is going to use it to find where the code should be loaded from. And all we do is we require from this directory go up a level, go into the ink directory and look for classname.php. In this case, user.php. I'm just saying to PHP, look over there. I've got my autoloader. I don't need to include or require anything. I just instantiate the user. So create new user, Lorna Jane. So I've got an object now stored in dolly user that represents me. In my template file, I can just use the getGrabatar and getUserName methods to display some information about this user. Here is a quick overview of where all my files are because if you're not confused by now, you probably should be. In the ink directory, I have user.php. That's where my class is declared. In the public directory, that's my web root, I have index.php. I have a readme file and I have some templates. Those are HTML with the little PHP short tags that you've seen in. I'm in form. I'm not storing passwords for users so you can be anyone you want to be. You just type it in. Who are you? I'm Lorna Jane. Hi Lorna Jane. That's my gravatar pulled in. So we have this user object. We say, oh, the form post came in. The value was Lorna Jane. We pass that into the dolly user constructor. So we get a whole new user object and then we just pass that user object out to the template. My gravatar, please show the username. That's it. So we've taken that self-contained object and passed some stuff around. Well done, you just built your first object-oriented application. Time for a pause. Probably time for some questions if anyone has any for me so far. Never seen so many quiet people. I'm not sure I'm impressed or frightened. Good, let's just move on. Oh yes, one question. Go for it. Where does the autoloader live? It is at the top of index.php. So when you start to execute your php code, it kind of comes in and you have some kind of setup, the autoloader will be in there. Sets up some paths, maybe connects to some databases, whatever. It happens there. Great question, thank you. Okay, here are some other cool things that I want to tell you about object-oriented programming. I'm going to show you how to do inheritance. I am going to talk about namespaces. You're going to see this in Drupal 8 with actually a kind of cool feature so I want to show you around. We're going to talk about interfaces because they're really cool. I might be a bit geeky about this. I want to show you exceptions because they're a reality of life. All right, so we have the inheritance and they talked about how cool it is to take something which is almost there and extend it, make it just specific to the thing that you're trying to do. In this case, I've got a user class but sometimes there'll be an admin user. I want to be a bit more specific if they're an admin user. Here's my class admin user. It extends the user class. By using that extends keyword and extending the user class, I've instantly and for free got my properties and methods that I declared earlier. I get the constructor, I get the user name and email properties, I get gravitat and I get user name. I don't need to do anything else. This is the admin user and I wanted to be a bit more specific. So, I have redeclared the get user name function. There's a lot going on in the six lines of code so let's just take it nice and easy. Class admin user extends user. We're creating a new class based on the user class. So at the end of line one we have a whole working class that is identical to the user class and has a different name. Get user name. Get user name existed in the user class. So we have just replaced it by redeclaring it here. We needed a different get user name. We can get everything else for free but there's one piece which just needs to be replaced so we just redeclare in the class. Line three. I'm calling parent colon colon get user name. Which is I want you to call the version of the method that I would have inherited had you not just overridden it. So we call the get user name that's in user. This means that if we change how the get user name stuff works, if we suddenly decide that we're going to do initials only or something I don't know, we change it in the user class and all the dependent classes will still build on it. So, I'm keeping that. However, I'm going to append brackets admin. So whenever anywhere in the system I display the user name it will always say admin after it. I don't have every single place that I do that in the template if they're admin display this. The object knows how to tell you its name and we delegate that responsibility inside the object. If the user ticked the box we store that in the session and so we know when we come to instantiate the user object we need to check if they're in admin. If they are we're going to make an admin user class to make sure that behaves precisely as we need. Otherwise we'll just have a proper user class, a normal user class. So, let's say that we are Crel. He ticks the I want admin access box. What happens? Oh look hi Crel. Brackets admin because it loaded the other class for us. We instantiated a different type of object, inheriting everything else, inheriting the gravitas stuff, inheriting the constructor. We didn't re-declare anything, but we just changed that piece that we needed to change. So that's inheritance. Straight away you're starting to see the code reuse when you declare the classes and that ability to switch out one object. The template doesn't care that it passed something else completely. It's actually running different code but it doesn't care. I say here display this user type thing and it just calls the methods. The question I get a lot about objects in Drupal is what is standard class? So you've seen this a bunch in Drupal 7. You are not going to see it in Drupal 8. The standard class itself is the parent of all other objects in PHP. So the objects you declare, the classes that you declare and then instantiate are all themselves descended from standard class. It's just an internal implementation detail. You have seen them as a way of being array-like. What I would advocate is declaring a class and putting those values, those properties into a specific class and then if you need to extend that, put some functionality in later there's a place to put that. Whereas generic standard class doesn't give you a way of extending that you can use. Let's talk about namespaces. Namespaces were a game changer for PHP. In a sense they're not new. They came out in 5.3. In another sense, you're seeing for the first time in Drupal 8 because your minimum requirements have just gone above 5.3. I think you're 5.4 something now. So, this opens the door to using namespaces and I'm really pleased about that. In the wider PHP community use of namespaces has allowed the interoperability, the sharing of code, the way that you're using symphony components and contributing back to those to make a stronger community overall that all happens because of namespaces. The stuff that we have with the PSR standards agreeing how we're going to use these features that has opened the door to so many things and namespaces is really the key. When 5.3 was released I was a senior developer being more experienced than the other people at the creative agency I worked at and 5.3 solved a lot of problems. It brought a lot of features that solved problems I was having in my day-to-day life. It was a long wait for 5.3 and it's only a technicality that means it wasn't a major version release. It does have a lot of differences but they are mostly good. So I am oh my gosh you're going to love namespaces. Okay, so things you need to know about namespaces. You declare a namespace at the top of a file it is valid until the end of the file. You make up your own namespace names call them anything you like but we then need to use those namespace names in our code to qualify which object we need. This is to allow us to pick a mix between different frameworks. Every framework has a user class, a log class and audit class probably a database class and you can't re-declare them in PHP with namespaces you're not. All of your code will go in your own namespace and you'll be using code from other people that will be in their own namespaces and we can have as many namespaces as we like. We'd never have a collision. In my example where so far you've seen the user class and the admin user class we'll just switch it around. Those two classes are pretty closely related so I'm going to put them in the same namespace as each other. A namespace is kind of a module level or a package level feature. So instead of just user.php I'm going to put my user class into the user namespace making its path user.php user.user.php Similarly my admin user once I've put it in the user namespace is perfectly obvious what kind of an admin it is so it will be just user.admin.php so you declare the namespaces and move the files around so my project layout now looks something like this you've got a hint of what's about to come there's an animal namespace I have my cat class declared there there's a user namespace with both admin and user inside it public directory is the web root it's got index.php I chopped the templates they didn't change he told my back-end developer I just didn't list the templates here at all we need to update our autoloader so more than just what's the class called oh just include a file called that we now need to handle the namespaces and the namespace separator so line one exactly the same as before line two starts the same as before but line three is where things get interesting we do a stir replace on backslash escaped because that's how this works so that's one backslash, but it's escaped we replace that with directory separator which is a constant that has the slashes the right way around depending on your operating system I won't tell you which way I think is right but it'll be correct regardless of which platform you're running a code on and then the class name so it takes a whole class name for example user slash user puts a directory separator where the namespace separator was and then .php on the end and is able to find the code so we just update our autoloader to make it a little bit clever if you're importing other people's code you might find that you need a few different autoloaders because they have different naming conventions in their projects that's fine, you can call SPL autoloader register as many times as you need to and it'll just add another set of rules when we use our class we just need to say which class we mean so we proceed with the global namespace separator user slash and then the class name so my code now looks like this we can create new namespaces at will I just dropped the hint that the animal namespace might be incoming by showing you the file layout so here it is, I have a cat class in an animal namespace we don't need any arguments to the constructor because I only know one cat his name is orbit he's very handsome, he's not very clever so we've got our cat we've got our users some of them are admin users I'm going to add a new feature to our excellent object oriented website that we've been working on so far I'm going to show you an array of featured users and all I've done there is instantiate two objects and stick them in an array so dollar feature is an array it contains two objects the bottom half can you see it's two separate code samples maybe we have a heading saying other excellent users you know like you see people who have commented on this site recently it's a for each loop and for every object as it comes past we just call getGravitar and we show a list of those users so here we are Emma and orbit as featured users on my site those are not the same class one's a cat, one's a user it doesn't matter you just call getGravitar PHP doesn't care, the calling code the context does not care so if you need to extend that class change what getGravitar does go for it put a board around it template doesn't need to know we've made some assumptions here we've assumed that the getGravitar method will always be present quite safe when I just declared two classes and instantiate them feel pretty confident on a much bigger system we need to be a bit more careful so how could we check if that getGravitar method is actually there we could check what kind of object we have PHP has an instance of operator so you could say if this is either a user or a cat go ahead and call the getGravitar method but by the time you've added the dog, the fish and the squirrel that's going to be tedious in a template so what else could we do well let's talk about interfaces an interface is a contract it dictates the behavior that this object will support we declare an interface and it will lay out the method or methods that will be present in the class so if you declare three methods in an interface every class which implements them implements this interface must have those methods you don't actually write the code for those methods you just say what methods there will be whether they're public or protected what parameters they take that's it, there's no actual code so you can implement those methods really differently in different objects but you know that those methods will always be present here I've made an interface called picturesque I may have been writing these slides late at night it declares a single method getGravitar there's no code here, we just say in the picturesque interface there is getGravitar good news, autoloading understands interfaces so you can just use this now don't worry about it put it in the same place, follow the same naming rules that you did for classes and your autoloading will just work so if the cat class implements picturesque then it must implement getGravitar public function no parameters it must implement exactly that if it doesn't your syntax is invalid and your code will not run guaranteed your interface is you declare the interface and implement it your methods will be there they have to be there you know that the cat class already has the getGravitar method you just saw it so that's cool so I've shown you interfaces I've explained the problem of how can we know whether we can call getGravitar or not well we can only use objects which implement picturesque so that's the interface any object they're not related to each other that implements picturesque we know bang we can call getUserName, we can call getGravitar oh just getGravitar we can call getGravitar confidently we know it's going to be there because it's in the interface and so it's guaranteed to be there we can use the interface name typehint typehinting means please only pass me objects of a specific type now in PHP we like to be quite loose and relaxed about the definitions we use for things so when I say only pass me objects of a specific class I mean please pass me objects that are of this class that are descended from this class so if I typehint for user then admin user is fine because they one extends the other or you can also pass me typehint for the name of an interface and if I say I'll only accept a picturesque object we're not looking for a picturesque class it's any class that implements picturesque so suddenly we can typehint onability we don't care who your parents are it's about what you can do that makes you acceptable it's like a powerful social statement except in objects so when I go to display each of those featured users in turn well when I go to add them to the list I call the add featured user method which only accepts picturesque objects so I pass in a user great if I pass in a cat great if I pass in a tree well that doesn't implement picturesque PHP just won't accept it because it will fail the typehint so you can know that those objects all have that method and that it's okay to call it so the typehinting which identifies object relationships but also capability is really really key some people have told me I am crazy for trying to teach you interfaces it's a powerful tool it's not complicated it's so useful declare the capabilities in an interface then declare your classes but if you're looking for can this object do X typehint on the interface to be sure with these techniques you can take on almost all of the architectural design patterns and all the other big words that are out there they're all built of these relatively simple building blocks you're all coders you're all capable exceptions, let's talk about exceptions I love exceptions, they're weirdly awesome and elegant even though we mostly see them when something has gone wrong object oriented programming means we talked about objects, we talked about methods, we talked about properties we talked about inheritance we talked about exceptions they're a very elegant way of handling errors they give you the opportunity to decide is this a problem or not, should this be happening you know like oh somebody's avatar is missing, well okay fine I'll show you the anonymous man and move on you don't have to have your code grind to a fatal error halt you also don't have to do that thing where you pass a pointer with a ray of errors and if you return false you should check what you put into the variable that you referenced in the exception will instantly bubble back to its calling code and let you know when something has gone wrong so it's a really good way of passing messages around an application also exceptions are objects you can extend them you can call methods PHP itself throws exceptions Drupal does too for example here I've tried to instantiate a new PDO object which is the database connection stuff in PHP this is a new PDO object however this is not how you instantiate a PDO object it needs a data source name as the first argument so because I didn't catch this exception I see a PHP fatal error and that's your choice if you get an exception and it should be a fatal error bubble all the way up and cause your code to come to a complete halt exceptions are opportunities for you to find out oh something went wrong it's a database connection problem let's display a nice error to the user and work out what we should do next what I should have done here because I'm running code that can throw an exception is I should have run I should have wrapped my excellent code in a try, catch and capture so the code that you hope will run goes in the try block so ideally what will happen is you will run your application you'll hit the try block all of your code will run successfully and we will move on that's the success outcome if something goes wrong for example Lorna Puzz is completely the wrong arguments into the PDO constructor then an exception will be thrown if the exception is thrown immediately to the matching catch block so here I am catching PDO exception this is a type hint you know what a type hint is this is a type hint so I'm catching a PDO exception if some kind of string translation exception should occur in the same code it won't be caught by this catch block because it's not a PDO exception and it's not descended from a PDO exception it's a type hint you can have multiple catch blocks PHP will match the most specific first so if you know that there might be a database connection problem and you probably just want to retry because it's dodgy or whatever MySQL might have gone away and you might need to disconnect and reconnect you can catch specifically the PDO exception and then have a generic a second catch block which is just catch with an exception type hint and that will catch everything else so the most specific one goes first that goes wrong, you can write a second catch block so you can distinguish between which kinds of exceptions were thrown by using that type hint to check what kind of object it was here is a ridiculous example which is small enough to fit on my slide which is the problem with writing code examples so I have a function that adds two numbers we call the function three and two, we get five great and again we throw an exception because this function will throw an exception if you pass in zero because quite frankly that's not very interesting when I run this code I get the fatal error because I didn't catch the exception you need to catch the exception we can also extend exceptions this is cool this brings me back to my multiple catch blocks the type hinting, the interfaces so on we can extend exceptions and you will often see a code that looks like what I have here in lines one and two declaring a class that extends exception and does nothing else this allows me to if I throw this exception I know exactly that this went wrong and I can catch this exception if you always catch generic exception you will at some point think you know what has gone wrong and not know at all so I do advocate extend the exceptions you know all about inheritance extend the exceptions even if they're empty to allow you to distinguish between things that have gone wrong also look in the PHP SPL extension core in PHP it's always there it has a bunch of pre-made exception so there's like an out of range exception a logic exception an unexpected value exception there might be some stuff there that you can just really fit in and is there because we end up with this pattern with exceptions so exceptions extend them make your own exceptions handle the exceptions in the catch block there's nothing that says you have to cause your code to quit it's not a big problem feel free to use this opportunity to log that something went wrong and carry on with your application you're the developer you're the person in charge you decide how big this problem is and the exceptions are so cool they're not errors PHP doesn't say oh I'm not going to run anymore because you've got a problem you decide, you dictate in development mode we're going to screen to halt and set off all the alarms because that should not be happening and on live maybe we'll just sort of skate over that move on so that's your decision okay is everyone okay you're very quiet do you have any questions okay let me repeat that this previous slide where I had literally an empty exception I just made this exception so that I could use it here and know whether it was a don't be daft exception or a generic one yes yes yes would it make sense to have a naming convention yes please namespace it along with the other classes that it relates to and probably is used in so probably this would be way down in a namespace somewhere I've got this without namespaces just so I'm not confusing you I confused you anyway so that's fine another question no I just put it all in one code sample so sorry his question was is this an exception to my rule about having all the code in one file no this should be two files so I've just put it all on one slide but that don't be daft exception would be in its own file called don't be daft dot php whatever probably in a nested namespace so this is the same question as this really probably nested in a namespace and therefore nested in your file and directory structure accordingly so all the rules about classes about auto-loading those all work so auto-loading doesn't care that an exception is an exception it's just a class the exception object is built into php and you can extend it but everything else is as normal interfaces will follow auto-loading as well yes you're gonna have to shout people at the back yes can you extend an interface you can have interfaces that implement other interfaces so they can build on each other also each of your classes can implement multiple interfaces just stick commas between the names okay another question right at the back I hope you're loud no I can't hear you can you nest namespaces yes and I would expect you to so this example was really really simple but I would expect to see namespaces that went something like company or vendor name project or module name subproject or module name class name so exactly as you would normally have a nested directory structure if you're already working with classes you are accustomed to having long winded prefixed classes I would expect to see all of those levels translate over to namespace code really good questions thank you okay one more thing and if you can hang on through this well you're rock stars so duplicate functionality you have just watched me copy and paste the get gravitar method from the user class to the cat class they're exactly the same code I literally copied and pasted this method now we've got some choices we could make them both extend from some common parent this is a really common pattern and I call it the false parent the cat is not related to the user okay they really are not the same thing they have some similar capabilities but as we build our application those two classes will start to diverge they really are not the same thing at all they do both have this same small piece of functionality so I copied and pasted the functionality between the classes but we can do better than that because as of pitchp5.4 we have a feature called traits and straight from the words of the man himself traits are compiler assisted copy paste you put the function that you method objectority programming big words the method into something we call a trait looks like a class because it's half a one and we say right see this in my class use it here and in this other class use it here literally compiler assisted copy paste php will assemble these pieces for you at runtime a trait looks like a class my trait is called gravitar it contains a single public function get gravitar guess what auto loading works for traits may just name your trait and put it in a file exactly like you do for classes exactly like you do for interfaces the stuff that the hard work that we did about auto loading right at the beginning is done we've got our trait it's called gravitar and it has that method in it in my user class all I need to do is put look at line 7 use gravitar that imports that method if there were multiple methods in the trait it would bring all of them in into my class so I can create these small snippets of reusable code and use them throughout my application in unrelated classes you often see this for things like um observer patterns strategy patterns things where you need to have different classes doing the same thing you will also see it for things like an audit trail if you always need to be able to add an audit trail for something that just happened you can put that function in every class that needs it question is the trait part of an object this trait no this trait is just a trait and then here in my class I've brought it in so the method that's declared here this get gravitar method the use statement that's on line 7 means that that method is now as if I had declared it in this class that's a really good description he says it's a loose method can I trait have properties? yes I didn't want to blind you with science traits can have properties they can also use other traits so you can make a trait that's made of some other traits if you might need some of these pieces here and then two always together so anything that goes in a class not quite, most things that go in a class can go in a trait and then be applied to other classes as needed so they're a partial class kind of how do you set the values of the properties? well you'll never instantiate a trait on its own a class will have the trait in it so when you instantiate an object from that class you'll do the initialization there so it will still be a class as usual but some of the methods that are in it are reused yeah awesome yes you can't declare a trait private protected or public but you can declare the stuff that's in it private protected or public as you usually would so the way that you would normally declare a property or normally declare a method is absolutely the same in traits when you use it in a class it will come in however you declared it in a trait yeah okay yes right if you declare a property in a trait and in a class what happens? is that your question? okay you can declare it in both places there are rules about resolution so for example if you have a method in a trait and in a class there's pages and pages of examples on PHP.net about how all the resolution works somebody has thought of this problem and it will resolve in the same way promise I've never had a weird problem with trait resolution that hasn't made me go oh that's really backwards I've always gone oh yeah okay that makes sense so don't worry too much about the conflicts it seems weird because you're putting together lots of pieces typically when you do it in a real world application it will make sense probably yes another question what's the advantage over just instantiating another class? here I'm writing methods which is applied to two different classes so if I need the audit trail is the example that I usually use so if you need the ability to log that a value was changed that code is boilerplate it's going to look the same this user changed this object on this date it's going to look the same in every class that you make even those classes are not related and so you can put that code, that single method into a trait and just apply it to the classes that need that capability if you need to change how your audit trail works it's only in one place all the classes will just then use that so it's more about maintainability than it doesn't make much difference when you write it the first time but it does make difference three years down the line when you're still maintaining it so for the code that you've seen this is where we now are the picturesque interface and the gravatar trait are both just there they're in the global namespace because I put them in the global namespace the animal and the user are namespaces they have classes inside them and that's basically it if you napped at any point really this is all you need to know the class is the recipe, the object is the thing and at its most basic level every object will represent a thing so if you are passing any kind of identifying values into methods you probably want to revisit how that's going because each object should have values stored inside it that allows you to access that the methods can access the data inheritance using a class as a basis for a similar but slightly better class the interface is a direct agreement about abilities and available features the type hinting to say what can this class do are you the right kind of object am I going to know what's going to happen is my code going to run okay and finally the trait how to use the same functionality in two unrelated classes without making that without either copy and pasting or making that false parent I'm pretty much bang on time I'm going to take some questions my slides are online I hope my twitter account has tweeted them if not I will fix that I wanted to mention a video that I made for O'Reilly which covers a bunch of the object oriented theory some of the modern PHP stuff composer, PSRs and just tries to clean up PHP for those people who are self-taught or updating their skills which is all of you because you're in a brave new world of Drupal 8 I have no solid information but I'm going to start this rumor anyway despite the fact that the room is packed I think if you are here in person at Drupal Khan O'Reilly are going to give you a voucher for a free ebook I believe you may be able to get the video instead so just look out for that because I made it with basically you in mind and you might find it helpful alright who else has a question for me absolutely nobody I'm getting off very lightly today I'm here today and tomorrow speaking tomorrow new wave PHP so if you want more code please drop in. Thank you so much for coming this was fun