Skip to content

Instantly share code, notes, and snippets.

@rgantt
Created August 18, 2011 20:51
Show Gist options
  • Save rgantt/1155168 to your computer and use it in GitHub Desktop.
Save rgantt/1155168 to your computer and use it in GitHub Desktop.
php 5.4 traits
<?php
/**
* This gives a fatal error
*/
class AbsTest {
abstract public function saySomething( $something );
public function saySomething( $something ) {
echo "{$something}\n";
}
}
$abs = new AbsTest;
$abs->saySomething("anything");
<?php
trait AbsTrait {
abstract public function saySomething( $something );
}
/**
* This runs without a hitch
*/
class AbsTest {
use AbsTrait;
public function saySomething( $something ) {
echo "{$something}\n";
}
}
$abs = new AbsTest;
$abs->saySomething("anything");
<?php
/**
* ===========
* Originally: duplicate function in subclasses--smells bad!
* ===========
*/
/** code inherited from elsewhere */
class Super { /* stuff */ }
class Sub1 extends Super { /* great stuff */ }
class Sub2 extends Super { /* fantastic stuff */ }
/** your own code */
class MySub1 extends Super {
public function someFunction() {
/* do someFunction() stuff */
}
}
class MySub2 extends Super {
public function someFunction() {
/* COPYPASTA! */
}
}
<?php
/**
* A trait that will add logging capability to any class
*/
trait Logging {
public static function initLogger( $logger = null ) {
static $logger = null;
if( $logger === null ) {
$logger = LoggerFactory::createLogger();
}
return $logger;
}
public function log( $message ) {
self::initLogger()->logMessage( $message );
}
}
/**
* A class that is desperately crying out for some loggin'
*/
class NeedSomeLoggin {
use Logging;
public function amazingAlgorithm() {
$this->log("entering algorithm");
/**
* Patented, I dare you to use it
*/
$this->log("leaving algorithm");
}
}
$nsl = new NeedSomeLoggin;
$nsl->amazingAlgorithm();
<?php
/**
* =======
* Case 1: refactor duplicate someFunction() code into superclass
* =======
*/
/** code inherited from elsewhere, editable by you */
class Super {
public function someFunction() {
/* do incredible things */
}
}
class Sub1 extends Super { /* awesome stuff */ }
class Sub2 extends Super { /* no touchy */ }
/** your own code */
class MySub1 extends Sub1 {
/* has access to someFunction() */
}
class MySub2 extends Sub2 {
/* has access to someFunction() */
}
<?php
/**
* ============
* Application: add trait to a class to give it singleton capability
* ============
*/
trait Singleton {
public static function instance() {
static $instance = null;
if( $instance === null ) {
$instance = new self;
}
echo get_class( $instance )."\n";
return $instance;
}
}
class Super {
public function someEssentialMethod() {
echo "this is so essential\n";
}
}
/**
* requires an instance of Super in its method
*/
class UsefulClass {
public function doSomethingAmazing( Super $super ) {
echo "this is so amazing\n";
}
}
class MyClass extends Super {}
/**
* These classes will satisfy the "Super" subclass requirement of the
* doSomethingAmazing method in UsefulClass, but will also implement
* Singleton functionality (although they will not be of type "Singleton")
*/
class MyTraitClass extends Super {
use Singleton;
}
class MySecondTraitClass extends Super {
use Singleton;
public function someEssentialMethod() {
echo "this isn't quite so amazing\n";
}
}
$mc = new MyClass;
$mtc = MyTraitClass::instance(); // "MyTraitClass"
$mtc->someEssentialMethod(); // "this is so essential"
if( $mtc instanceof Singleton ) {
echo "mtc was an instance of Singleton";
}
$suc = new UsefulClass;
$suc->doSomethingAmazing( $mtc ); // "this is so amazing"
$suc->doSomethingAmazing( $mc ); // "this is so amazing"
$mstc = MySecondTraitClass::instance(); // "MySecondTraitClass"
$mstc->someEssentialMethod(); // "this isn't quite so amazing"
<?php
/**
* =======
* Case 2: unalterable class hierarchy
* =======
*/
/** code inherited from elsewhere, UNeditable by you */
class Super { /* stay out */ }
class Sub1 extends Super { /* no touchy */ }
class Sub2 extends Super { /* no touchy */ }
/** your own code */
trait MyTrait {
public function someFunction() {
/* doing incredible things */
}
}
class MySub1 extends Sub1 {
use MyTrait;
/* has access to someFunction() */
}
class MySub2 extends Sub2 {
use MyTrait;
/* has access to someFunction() */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment