Skip to content

Instantly share code, notes, and snippets.

@philbirnie
Last active November 11, 2015 02:31
Show Gist options
  • Save philbirnie/1739541c619940a9bbda to your computer and use it in GitHub Desktop.
Save philbirnie/1739541c619940a9bbda to your computer and use it in GitHub Desktop.
PHP Book - The Trait
<?php
/**
*
* Traits
*
* 1. PHP does not allow for multiple inheritance
* 2. A class can implement many interfaces, but interfaces only provide a template.
* 3. Traits allow us to share implementation across class hierarchies.
*
* Characteristics:
*
* 1. Like an abstract class, a trait cannot itself be instantiated
* but can be incorporated into classes.
*
* 2. Any methods defined in a trait become available as part of any class that uses it.
*
* 3. A trait changes the structure of a class, but doesn't change its type -
* it's like an include for classes! This can prevent duplication
*
* 4. Like interfaces (and inline with the include comparison), you can use as many as
* necessary within a class.
*
* 5. You can also use abstract classes, static classes and even access host
* class proprties (though this is poor design from within a trait
*
* 6. You can even change a method's access level from within the host class.
*
*
* Reference: PHP Objects, Patterns and Practice, ed 4. pp. 45-49, 52-53
**/
trait PriceUtilities {
private $taxRate = 0.0750;
function calculateTax($price) {
return $price * (1 + $taxRate);
}
...
}
///
/**
* Both of these classes have access to the calculateTax method
**/
class Product {
use PriceUtilities;
...
}
class Register {
//use PriceUtilities;
/** Example of changing scope of method **/
use PriceUtilities {
PriceUtilities::calculateTax as private;
}
...
}
$r = new Register();
$p = new Product();
/** this would not work because method is now private **/
echo $r->calculateTax(16.55);
echo $p->calculateTax(15.55);
/**
* Combining Traits with Interfaces.
*
* Traits don't change the type of the class to which they are applied.
* So when you apply the IdentityTrait to multiple classes, they won't share
* a type.
*
* So if an interface requires a method, you can use a trait to include this method
* rather than putting into the class directly. -- Allows type hinting to continue
**/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment