Advanced PHP Simplified
Mark Niebergall
https://joind.in/talk/8887c
About Mark Niebergall
● PHP since 2005
● Masters degree in MIS
● Senior Software Engineer
● Drug screening project
● UPHPU President, Speaker
● CSSLP, SSCP Certified and SME
● Drones, fishing, skiing, father, husband
Advanced PHP Simplified
Advanced PHP Simplified
Disclaimer
● Breadth not depth
● Think about your current coding style and
architecture
● Leverage topics covered
● Ask questions along the way
Objective
● Discuss some advanced PHP concepts
● Cover technical implementation
● Understand when and how to use features
○ Code during the talk
Topics to Cover
● Abstract
● Interface
● Trait
● Namespace
● Dependency Injection
Abstract
Abstract
● Abstract Art
● Abstract of text
● Abstract thought or idea
Abstract Class
● abstract class X {
abstract public function doSomething();
}
● class Y extends X {
public function doSomething() {...}
}
Abstract Class
● abstract public function doSomething($a);
● protected function somethingElse() {...}
Abstract Class
● Implemented abstract method signatures
must match
○ Visibility modifier
○ Name
○ Parameters
○ Return type
Abstract Class
● Can have methods with functionality
● Can have class properties
● Can have class constants
● Can extend one abstract class
○ Can have multiple levels
● Cannot be instantiated
Abstract Uses
● X "is a" Y (NOT "has a")
Abstract Uses
● Represents an idea or base concept
● Composition over Inheritance
● Centralizing logic
● Reducing duplicate code
● Avoid a maze - keep code readable
Abstract Examples
● Truck extends Vehicle
● Laptop extends Computer
● Email extends Communication
Abstract Examples
● abstract class Animal
● abstract class Mammal extends Animal
● abstract class Canine extends Mammal
● abstract class Dog extends Canine
● class GermanSheperd extends Dog
abstract class Animal {
abstract public function breathe(Lungs $lungs) : Lungs;
protected function beAlive() : Animal {…}
}
abstract class Mammal extends Animal {
protected function warmBlood(Blood $blood) : Blood {...}
abstract public function growHair();
}
abstract class Canine extends Mammal {
abstract public function wagTail(Tail $tail);
}
abstract class Dog extends Canine {
abstract protected function bark();
}
class GermanSheperd extends Dog {...}
abstract class Pen
{
protected $length;
abstract public function usePen();
abstract public function refuel();
protected function setLength($length)
{
$this->length = (float) $length;
return $this;
}
public function getLength()
{
return $this->length;
}
}
abstract class Bird
{
protected $beak;
abstract public function walk();
abstract private function eat();
protected function fly(Wings $wings)
{
$wings->flap();
}
}
class Flamingo extends Bird {
public function walk() {...}
private function eat() {...}
}
Abstract
Interface
Interface
● User Interface
● System Interface
● Provides a way for communication or
control
● Connect two things together
Interface
● interface X {
public function doStuff(Thing $thing);
public function other() : Thing;
}
● class Y implements X {...}
● abstract Z implements V, W, X {...}
Interface
● Methods must be implemented
● Method signatures must match
● Methods are left empty in the interface
Interface Uses
● When no logic is required but method
signatures can be reused
● Contract between concept and
implementation
Interface Uses
● Class can implement multiple interfaces
● Leaves implementation to be handled in
the class
● Can be used with abstract and class
● Cannot be used with a trait
Interface Uses
● All methods must be public
● No properties allowed
● Can have public class constants
Interface Examples
● Auditing
● Sea Creatures (mammal, fish, etc)
● USB
Interface Examples
● Authentication methods
● Responses to a request
● Orders from vendors and customers
interface LightInterface
{
const LIGHT_SPEED = 299792458;
public function shine(Energy $energy) : Light;
public function travel(float $x, float $y, float $z);
}
interface ProcessSomething
{
public function process(Something $something);
}
Interface
Traits
Traits
● Characteristics of something
● Attributes possessed
Trait
● trait X {
public $property;
protected function doStuff() {...}
}
● class Something {
use X;
}
Trait
● PHP 5.4+
● Can have methods and properties
● "Looks" like a concrete class
● Horizontal Inheritance
● Cannot be instantiated
Trait
● Promotes code reuse
● Unrestricted by inheritance hierarchies
● Pulls together grouped functionality
● Multiple traits allowed
Trait
● Used alongside abstracts and interfaces
● Used in abstract, concrete class, and trait
● Cannot implement an interface
● Cannot extend a class
● Cannot have class constants
Trait
● Awareness concept
○ ContainerAware
○ AuditAware
○ AdapterAware
Trait
● Naming collisions
○ First the current class
○ Then the trait
○ Last the parent class
Trait
● Fatal error if trait method collisions are not
resolved
● ‘insteadof’ for one, ‘as’ for multiples
abstract class TheAbstract {
public function hello() { echo ‘Hello from the abstract.’; }
}
trait TheTrait {
public function hello() { echo ‘Hello from the trait.’; }
}
class TheClass extends TheAbstract {
use TheTrait;
public function hello() { echo ‘Hello from the class.’; }
}
abstract class TheAbstract {
public function hello() { echo ‘Hello from the abstract.’; }
}
trait TheTrait {
public function hello() { echo ‘Hello from the trait.’; }
}
class TheClass extends TheAbstract {
use TheTrait {
TheTrait insteadof TheAbstract;
}
public function hello() { echo ‘Hello from the class.’; }
public function helloAbstract() { parent::hello(); }
}
abstract class TheAbstract {
public function hello() { echo ‘Hello from the abstract.’; }
}
trait TheTrait {
public function hello() { echo ‘Hello from the trait.’; }
}
class TheClass extends TheAbstract {
use TheTrait {
TheTrait::hello as helloTrait;
}
public function hello() { echo ‘Hello from the class.’; }
public function helloAbstract() { parent::hello(); }
}
Trait
● Property collisions
○ Same visibility and initial value
Trait
● Can change visibility modifier
○ use TheTrait {
TheTrait::hello as protected;
}
Trait
● Can have abstract methods
○ Not recommended
Trait
● Can have static methods
○ trait TheTrait {
public static function thing() {...}
}
Trait Usage
● Common attributes and functionality
● Consider: required for functionality within
this class?
Trait Usage
● Keep vertical inheritance in mind,
especially when making changes
● Reduces some limitations of single
inheritance
Trait Examples
● Car tire
● Sea creature
trait Circular
{
protected $radius;
public function getDiameter()
{
return bcmul($this->radius, 2);
}
public function getArea()
{
return bcmul(pi(), bcpow($this->radius, 2));
}
}
class Pie { use Circular; }
class Tire { use Circular; }
trait Wave
{
protected $length;
protected $amplitude;
protected $frequency;
public function setLength($length) {
$this->length = (float) $length;
return $this;
}
public function getLength() {
return $this->length;
}
public function setAmplitude($amplitude) {
$this->amplitude = (float) $amplitude;
return $this;
}
public function getAmplitude() {
return $this->amplitude;
}
}
Trait
Namespaces
Namespaces
● Container for identification
● Encapsulate items
Namespace
● namespace
CompanyDomainTopicSubgroup;
use OtherAreaZ;
class A {
protected function doStuff() {
$z = new Z;
}
}
Namespace
● PHP 5.3+
● Grouping related classes together
Namespace Uses
● Shorten_Up_Really_Long_Class_Names_
In_Your_Application
● Avoid naming collisions
Namespace Uses
● Autoloader with file structure built around
namespaces
○ Can have multiple
○ Often one for composer, one for project
Namespace Uses
class Autoloader
{
public static function registerAutoloader() {
spl_autoload_register(array('self', 'loader'), false);
}
public static function loader($className) {
require __DIR__ . ‘/../../’ . $className . ‘.php’;
}
}
require_once __DIR__ . ‘/../vendor/autoload.php’;
Autoloader::registerAutoloader();
Namespace Uses
● Must be first code in file
● Aliasing: use WidgetXyz as X;
Namespace Uses
● Watch out for keywords
○ Trait
○ Case
○ Switch
○ Int
○ Bool
Namespace Uses
● Avoid collisions
○ use BobCat as BobCat;
○ use JaneCat as JaneCat;
Namespace Examples
● Last name
○ namespace Smith;
○ class John {...}
Namespace Examples
● Just_About_Any_Long_Name
○ namespace JustAboutAnyLong;
○ class Name {...}
Namespace Examples
Domain/Subject/Science.php:
<?php
namespace DomainSubject;
use OtherDomainSubjectThing;
use OtherDomainArea;
class Science {
protected function doSomething(Thing $thing) {
$thing->doWhatItDoes();
}
public function otherStuff(AreaNorth $north) {
$north->head(AreaSouth::getPole());
}
}
Namespace
Dependency Injection
● Send object dependencies into an object
from outside
● Pass class as parameter into a method
rather than method building the class
Dependency Injection Uses
● Constructor: __construct(X $x, ...)
● Setter: setX(X $x) { $this->x = $x; }
● Interface: setX(X $x);
● Method: doSomething(Thing $thing) {...}
Dependency Injection
● Big help for unit tests
● Allows for use of mock objects
● See PHPUnit documentation for
getMockBuilder,
getMockForAbstractClass, and other
PHPUnit methods
Dependency Injection
● Does add more lines of code
● Composition over Inheritance
Dependency Injection Uses
● Service locator
● Factories
Dependency Injection Examples
● Desktop computer parts from different
manufacturers
● Lamp light bulbs: colors, types
namespace Pen;
use LightLight as LightLaser;
require_once __DIR__ . '/../Autoloader.php';
Autoloader::registerAutoloader();
class Laser extends Pen
{
protected $lightLaser;
public function __construct(LightLaser $lightLaser = null) {
$this->lightLaser = $lightLaser;
}
protected function getLightLaser() {
if (is_null($this->lightLaser)) {
$this->lightLaser = new LightLaser;
}
return $this->lightLaser;
}
public function usePen() {
$this->getLightLaser()->shine();
}
public function refuel() {
$this->getLightLaser()->replaceBatteries();
}
}
Dependency Injection
Things to Consider
● Open group discussion
Things to Consider
● Why need for abstract vs interface vs
trait?
● Benefits of vertical vs horizontal
inheritance?
Things to Consider
● Traits vs dependency injection?
● Tradeoffs of complexity vs code reuse
(think of database normalization)
Things to Consider
● Implementation considerations
● Code consolidation
Conclusion
● Goals for using concepts
● Evaluate current architectural approach
● Just scratched the surface on topics
covered
● Consider how concepts all come together
for solution
Questions?
● https://joind.in/talk/8887c

Advanced PHP Simplified - Sunshine PHP 2018