predictable mapping from namespaced classname to file location • e.g. \MyLib\User lives in lib/MyLib/User.php For more details, see PSR4: http://www.php-fig.org/psr/psr-4/
little more specific? 1 class AdminUser extends User { 2 public function getUsername() { 3 $name = parent::getUsername(); 4 return $name . " (admin)"; 5 } 6 }
we stored that too 1 if($_SESSION['admin']) { 2 $user = new AdminUser($_SESSION['username']); 3 } else { 4 $user = new User($_SESSION['username']); 5 }
inc/User.php becomes inc/User/User.php namespace User; class User { inc/AdminUser.php becomes inc/User/Admin.php namespace User; class Admin extends User {
featured users $featured = array( new \User\User("emmajanehw"), new \Animal\Cat()); <h2>Other Excellent Users Of This Site:</h2> <?php foreach($featured as $user): ?> <?=$user->getGravatar()?> <?php endforeach; ?>
object can do. We could make a Picturesque interface interface Picturesque { public function getGravatar(); } Good news: autoloading works for interfaces!
a getGravatar() method? Check the object type with instanceof • but one is a Cat and one is a User, and what if we add more types? Only accept objects which implement the Picturesque interface
function addFeaturedUser(Picturesque $user) { return $user; } Adapt our code to use this function // featured users $featured[] = addFeaturedUser(new \User\User("emmajanehw")); $featured[] = addFeaturedUser(new \Animal\Cat());
a bit of one 1 trait Gravatar { 2 public function getGravatar() { 3 $url = "http://www.gravatar.com/avatar/" 4 . md5($this->email); 5 return "<img src=\"$url\">"; 6 } 7 } Good news: autoloading works for traits!
an item with properties and methods • inheritance use one class as basis for another • interface contract agreeement for classes • typehinting how to identify a class • trait how to use the same functionality in two unrelated classes