Day one of a two day seminar on object-oriented PHP. Designed to cover a basic level of familiarity with the concepts in general, and some PHP-specific implementation details and examples.
2. Intro to OOP Concepts What are objects (classes)? Properties Methods
3. Advantages of OOP Modular Easy code re-use w/o copy & paste Layers mean less to understand at once Code is more likely to match design More self-documenting than procedural code Free code!
5. Main differences in PHP5 (briefly) Objects were completely redone in PHP5 All objects are automatically passed by reference Constructors are named differently New visibility options A few other, less important things (RTM)
7. Objects Objects are instances of classes Can have many objects per class $this Access properties and methods with “->” With parentheses at the end, it’s a method $this->sleep() No parentheses, it’s a property $this->status Bears!
8. Object Properties Properties are variables What an object “has” or “knows” Can be any type, even other objects Example Bear properties gender color name weight status
11. Inheritance (pt. 1) Classes inherit properties/methods from their parents Depends on visibility (next topic) Source of the “no copy/paste” code reuse
12. Inheritance (pt. 2) Uses “extends” keyword PolarBear (child) extends Bear (parent) Only one parent allowed, choose wisely Child classes can redo old stuff or add new things PolarBear can swim()
13. Visibility (pt. 1) Applies to properties and methods 3 choices: public – visible/editable inside and out protected – visible inside class and descendents only private – visible inside original class only Go for private to start, then protected if children need it too
14. Visibility (pt. 2) Private/protected names often start with an underscore Well-supported convention Applies to properties and methods Being phased out due to IDE support Example: Shy Bear is shy Protecting Bear’s properties/methods PolarBear needs them too
15. Getters/Setters (pt. 1) How do we use properties that aren’t visible? Advantages More formatting options Clear, explicit interface Allows for read-only properties (getter only) Allows for “virtual” properties
16. Getters/Setters (pt. 2) Disadvantages More code to write/maintain But… a decent IDE can write it all for you Examples: $bear->getStatus() vs. $bear->status $bear->setName(‘Steve’) vs. $bear->name = ‘Steve’
17. Constructors A “magic method” that runs when an object is created with the “new” keyword Accepts parameters passed to new $bear = new Bear(‘Steve’); In PHP5 these are named “__construct()” Best practice is to only use these to assign property values IDEs can generate these for you
18. Destructors Much less commonly-used Runs automatically when the object goes out of scope or is forcibly “unset” Primarily used to close db connections Make sure they’re not still in use, if shared __destruct()
19. Practical example: DateTime Encapsulates many of the date_* functions DateTime::format() DateTime::modify() DateTime::setTimeZone() Requires a DateTimeZone object
21. Exercise (yes, there’s a quiz) Write your own class that extends DateTime Must have the following methods: getMonth() getDayOfWeek() getYear()
22. Passing objects by reference What references are Automatic in PHP5 Using & will actually reverse this and copy the full object Main source of OOP speed boost in PHP5 Moral: don’t try to outsmart the compiler
23. Class constants (pt. 1) Like regular PHP constants, just tied to a class Uses const keyword instead of define() PHP 5.3 can use const outside of classes Can’t be changed in child classes Which is clearer? $result->fetch_array(MYSQL_ASSOC) $result->fetch_array(1)
24. Class constants (pt. 2) Outside the class: ClassName::CONSTANT Inside: self::CONSTANTor parent::CONSTANT Examples: $bear = new Bear(‘Steve’, Bear::GENDER_MALE); $this->_gender(self::GENDER_MALE);
25. Type Hinting PHP will enforce a param’s type for you Great feature, use it whenever you can Works for arrays and objects See SplTypeson php.net for more IDEs use type hints for auto-complete Bear example (PoohBear will only eat() Honey)
26. You made it! Questions? Comments? Death threats?
27. Resources http://www.php.net/ Try php.net/%function_name% for a shortcut http://devzone.zend.com/article/638-PHP-101-part-7-The-Bear-Necessities Source of blatant theft http://net.tutsplus.com/tutorials/php/object-oriented-php-for-beginners/
Notas del editor
Objects (and I really mean classes here, more on the difference later) are containers. For now you can think of them like associative PHP arrays that can also have functions in them. That will change later but it’s a good starting point.Properties = variables (or array keys => values)Methods = functions
Since objects are designed to be self-contained, it’s easier to build software in small pieces, or even spread work out among multiple people (if you’re that lucky)Inheritance lets you write code once and reuse that exact same code elsewhere without duplicating it. More in a later slide.Object-oriented code is built around abstraction and information hiding. If I tell a Mail object to send an email, I don’t care how it does it and I don’t have to know. A user of the system is likely to be represented as an object called User, etc… so the logical flow is easier to verifyIf you name your objects and methods well the code will read more naturallyFinally, lots of OO code has already been written, and since it’s modular, you can just drop it into your app. Examples: Zend Framework, PEAR, etc…
Much of the power of OOP comes from the ability to hide complexity and implementation details from the developer. A classic example of this is a database abstraction layer. If you use one of these you can interact with any supported database in the same way, and the DBAL takes care of the differences between systems. It helps free up more brainpower for coding and less for remembering what that variable meant 80 lines ago.Objects should also only be responsible for one thing. If you pack your entire app into one object you’re not really gaining much since you still have to remember everything. Small objects make it easy to find the code you need, when you need it.Because of this segmented development, when I refer to a “user” of an object I usually mean you or another developer, not an end-user of the app
Since we only use PHP5 here, the differences shouldn’t matter much unless you’re trying to pass your PHP certification exam or reading old OO code. That being said, a lot of PEAR code is written for PHP 4, so knowing these things might make it easier to read. One of the biggest things is that objects are automatically passed by reference, which makes them much faster. I’ll point out the other differences as we come to them.
Classes are containers, like templates for creating objects. You design classes, but you use objects in your code.A class is like a blueprint for a house, whereas an object is the actual house.
Classes are the templates used to create objects. You can create as many objects as you want per class. “Bear” is a class, while a particular Bear (like Smokey) is an object. Many people starting out with objects will try to only make one object per class in their code, and that’s not necessary.$this is a special reference to the current object. It’s only valid to use inside an object, you’ll get an error otherwise.
You don’t have to define your properties when you write your class, but it’s a very good idea. It’s also a good idea to set a default value for all of your properties, just like if you were defining variables outside of the class. Objects inside of other objects is common.
This is where object behavior comes from, i.e. the main thing that make objects different from PHP arrays. You can also redefine behavior in child classes, which I’ll talk about in the next slide.
Everything continues to build on these themes, so I want to make sure everyone is clear. I’ll be happy to design an object from scratch for the group if it’d be helpful.
This is one of the most powerful features of OOP. Greatly reduces code duplication. “DRY” principle -> Don’t Repeat YourselfSince Bear knows how to sleep(), all child classes of Bear also know how to sleep() for free
Some languages allow for multiple inheritance, PHP doesn’t (yet). If you have questions about multiple inheritance, mix-ins, traits, etc… ask me afterwards. Child classes are intended to be more specific than their parents, and if multiple child classes share the same functionality they should be pushed higher up the tree into the parent. It wouldn’t make sense to write PolarBear::eat() and GrizzlyBear::eat() if they’re the same… if they are then eat() should be pushed up into the parent class
This ties in directly to inheritance. Visibility is like scope for properties and methods. It determines what can see/affect different parts of the class.Code defensively… if your properties are public you never know what can happen to them. Properties should basically never be public, only (some) methods.Examples after next slide.
The underscore naming convention comes from both the PEAR and Zend coding standards, and we highly recommend that you follow them. PEAR says that protected things shouldn’t have an underscore but we don’t follow that here.The newest versions of PHP coding standards (Symfony2, Zend Framework2, etc…) do not add underscores to non-public methods/properties.Old code may not have visibility specified. PHP4 did not have visibility (everything was public).
This is where objects start to deviate even further from arrays. Getters and setters (sometimes called accessors and mutators) are class methods that either return or change the values of class properties.If you want a property to be available but read-only from outside the class, you can define just a getter and then the users won’t be able to change it.If you always want a phone number to come back a certain way, you can have your getPhoneNumber() method format the output before returning it to ensure consistencyThis also lets you create “virtual” properties that don’t actually exist in the class, but your users don’t have to know that. An example would be getName() when the class has separate properties for firstName, lastName, and middleInitial. getName could return them in a certain order
One of many reasons to use an IDE instead of a text-editor. IDEs are very well-suited to writing OO code and have built-in generators for many common OO methods. They’re not always perfect but they’re usually a good start.A note here: NetBeans 6.9 has a few open bugs on their generators. Most have workarounds, so if you have specific concerns let me know and I’ll tell you how I deal with them.
First thing about this slide. We’ll cover magic methods in day 2, but __construct() is by far the most important so we’re covering it early. In PHP4 the class constructor is always a method named the same as the class name. So if I had a PHP4-style constructor for my Bear class, it would be a method called Bear()If you override a constructor in a child class, you should also call parent::__construct() to make sure you don’t miss anythingWhen the constructor finishes, the object should be complete and ready to use. It doesn’t have to contain useful data, but it should only contain valid data, and enough valid data to do its job
These aren’t nearly as important. I’m only really covering them here because they make a matched set with __construct(). They also always run automatically, but you don’t usually need to specify any special behavior. One gotcha: if you’re sharing a reference to a database connection between multiple objects and you want to close it, make sure all the other objects are done with it too. Easiest thing is to just not implement these at all, but they’re there if you need ‘em.
DateTime is a very useful object that comes built into PHP. Most of the date functions in PHP can also be done via DateTime. DateTime will format a date basically however you want, using the same format strings as the PHP date() function.DateTime::modify() takes all sorts of commands. You can give it a string like “+1 week” and it won’t even flinchsetTimeZone requires a DateTimeZone object, but it’s smart enough to handle daylight savings time for you transparently. It takes 3 letter time zone codes or locations like “America/Chicago”. php.net has a full list
This is the end of the second leg of day 1 of our OOP training. Things actually get easier from here on out but I want to make sure everyone is with me so far.
If anyone programs in C++, references are like pointers for dummies. For the rest of us, a reference is a way for multiple variables to point to the same thing in the computer’s memory, whether it’s an object, an integer, a string, or whatever. When objects are sent to a function as a parameter, by default, PHP5 will only send a reference to that object instead of copying the whole thing. This lets you (for instance) make one database connection object and send it 5 different places, but still only need one db object instead of 5 copies of the same one. In PHP4 you had to explicitly pass the object by reference to get that efficiency gain, so if you see a lot of ampersands by your parameters the code was probably written for PHP4
I like these but I don’t see them used very often. They’re valuable for all the reasons that regular constants are, and I think those are underused too. Constants help avoid “magic” numbers or strings in your code. Just another way of making your code easier to understand.
You can also use them to create objects that mimic sets or enums in other languages (structs in C++). An example of an object with just constants might be a Days object with constants for the days of the week instead of numbers (does Sunday start on 0 or 1? Etc…)
Type hinting is wonderful and it will make your life easier. It lets you tell PHP what type of input you’re expecting and then PHP will do the work of enforcing it for you. It only works for arrays and objects so far, but there are ways around that.Type hinting also provides information that your IDE can use to help you with code completion.Since it’s enforced by the compiler, it’s really “strict typing” but “hinting” sounds more friendly