SlideShare a Scribd company logo
1 of 71
Download to read offline
PHP traits,
   treat or threat?
Nick Belhomme
January 28th, PHPBenelux Conference 2012, Belgium
Software Architect / Project Lead

Author of the
Zend Framework 2.0 Cookbook

International Conference Speaker

Contributor to various Open Source Projects

Freelance PHP Consultant
Market positions




                   http://w3techs.com/
Market positions




●   Python 0.3%
Market positions




●   Ruby 0.6%
●   Python 0.3%
Market positions




●   Perl 1.0%
●   Ruby 0.6%
●   Python 0.3%
Market positions




●   ColdFusion 1.2%
●   Perl 1.0%
●   Ruby 0.6%
●   Python 0.3%
Market positions




●   Java 1.2%
●   ColdFusion 1.2%
●   Perl 1.0%
●   Ruby 0.6%
●   Python 0.3%
Market positions




●   ASP.NET 21.6%
●   Java 1.2%
●   ColdFusion 1.2%
●   Perl 1.0%
●   Ruby 0.6%
●   Python 0.3%
Market positions



●   PHP 77.4%
●   ASP.NET 21.6%
●   Java 1.2%
●   ColdFusion 1.2%
●   Perl 1.0%
●   Ruby 0.6%
●   Python 0.3%
PHP Market Position, 11 Jan 2012
Used by high traffic sites




                                              Java


                                    ColdFusion

                                   Perl
                                                     ASP.NET
                                                                           PHP
Used by low traffic sites




                             Used by fewer sites               Used by many sites
PHP Version Adoption

    ●   PHP 5 93.9%
    ●   PHP 4 6.1%
    ●   PHP 3 < 0.1%
    ●   PHP 6 < 0.1%
PHP 5 usage
     ●   Version 5.2 73.8%
     ●   Version 5.3 20.2%
     ●   Version 5.1 5.8%
     ●   Version 5.0 0.2%
     ●   Version 5.4 < 0.1%
Slow 5.3 Adoption?
●   Shared hosting
●   Companies refrain from updating stable
    systems / distributions
●   You
Adopt now
●   More stability
●   Security
●   Better engine (ie garbage collection)
●   New language features
●   Cleaner code because of more elegant ways of
    solving problems
PHP 5.4

●   Array short syntax (javascript notation)
●   Array dereferencing
●   Class access on instantiation
●   Indirect method call by array variable
●   Engine processes OO code faster
●   <?=
●   JSONSerializable interface
●   ...
Traits
ZF Use Case
ZF Code base used is for illustration purposes only and do
     –not-- express future possible implementations.

ZF2.0 is not yet released so giving ZF3.0 implementations
           illustrates only my own assumptions.


      PHP5.4 stable is not yet released so no real world projects are
      and should be running this version.

      Because of this no real best practices have been defined.
namespace ZendView;
class TemplatePathStack implements TemplateResolver {
    public function setOptions($options = array()) {
        if (!is_array($options) && !$options instanceof Traversable) {
            throw new ExceptionInvalidArgumentException(
                __METHOD__ . ' expects an array or Traversable'
            );
        }

        foreach ($options as $key => $value) { $this->setOption($key, $value); }
        return $this;
    }

    public function setOption($key, $value) {
        switch (strtolower($key)) {
            case 'lfi_protection': $this->setLfiProtection($value);
                break;
            case 'script_paths': $this->addPaths($value);
                break;
            default: break;
        }
    }
}
namespace ZendMvcRouter;
class RouteBroker implements Broker
{
    public function setOptions($options) {
       if (!is_array($options)
           && !$options instanceof Traversable) {
            throw new ExceptionInvalidArgumentException(sprintf(
                'Expected an array or Traversable; received "%s"',
                (is_object($options) ? get_class($options) :
                     gettype($options))
            ));
        }

        foreach ($options as $key => $value) {
            switch (strtolower($key)) {
                case 'class_loader': // handle this case
                Default: break;// ignore unknown options
            }
        }
        return $this;
    }
}
Problem: Code Duplication

if (!is_array($options) && !$options instanceof Traversable) {
    throw new ExceptionInvalidArgumentException(sprintf(
        'Expected an array or Traversable; received "%s"',
        (is_object($options) ? get_class($options) : gettype($options))
    ));
}

foreach ($options as $key => $value) {
  //handle each case
}

return $this;
Solution in PHP5.4?
             Multiple Inheritance


●   Would provide the setOptions in all child
    classes needed
●   Introduces the diamond problem
NOT an Option!
     A better solution called Traits


●   Would provide the setOptions in all classes that
    use the trait
●   Eliminates the diamond problem
trait Options
{
      public function setOptions($options)
      {
           if (!is_array($options) && !$options instanceof Traversable)
      {
               throw new ExceptionInvalidArgumentException(sprintf(
                   'Expected an array or Traversable; received "%s"',
                   (is_object($options) ? get_class($options) : gettype($options))
               ));
           }

         foreach ($options as $key => $value) {
           $this->setOption($key, $value);
         }

         return $this;
    }
}
namespace ZendView;
class TemplatePathStack implements TemplateResolver
{
   use Options;

  public function setOption($key, $value) {
    switch (strtolower($key)) {
      case 'lfi_protection':
         $this->setLfiProtection($value);
         break;
      case 'script_paths':
         $this->addPaths($value);
         break;
      default:
         break;
    }
  }
}
$templateStack = new TemplatePathStack();
$templateStack->setOptions(['lfi_protection' => true]);
namespace ZendMvcRouter;
class RouteBroker implements Broker
{
    use Options;


    public function setOption($key, $value) {
        switch (strtolower($key)) {
            case 'class_loader':
              // handle this case
            default:
              // ignore unknown options
              break;
        }
    }
}


$routeBroker = (new RouteBroker)->setOptions(['class_loader'=>'SomeLoader']);
You have just seen traits
Lets dive deeper

get your chest wet
namespace ZendLoader {
use RuntimeException;
   trait SplRegister {
          public function register()
          { spl_autoload_register(array($this, 'autoload')); }

        public function unregister() {
            spl_autoload_unregister(array($this, 'autoload'));
        }
   }

   class StandardAutoloader {
        use SplRegister;

        public function unregister() {
            throw new RuntimeException(
                'you should not unregister the standard autoloader once registered'
            );
        }
   }
}
namespace {
    $loader = new ZendLoaderStandardAutoloader();
    $loader->register();
    $loader->unregister(); // will throw the exception
}
Precedence Order


 The precedence order is that
members from the current class
   override Trait methods.
namespace ZendLoader {
use RuntimeException;
     class StandardAutoloader {
        public function unregister() {
          throw new RuntimeException(
             'you should not unregister the standard autoloader once registered'
          );
        }
    }
}
namespace NbeZfLoader {
use ZendLoader as ZendLoader;
     class StandardAutoloader extends ZendLoaderStandardAutoloader
     {
        use ZendLoaderSplRegister;
     }
}
namespace {
  $loader = new NbeZfLoaderStandardAutoloader();
  $loader->register(); //will register (trait)
  $loader->unregister(); // will unregister (trait)
}
Precedence Order


An inherited member from a
base class is overridden by a
 member inserted by a Trait
Distil Methods!
namespace ZendLoader {
use RuntimeException;
  class StandardAutoloader {
     public function unregister() {
       throw new RuntimeException(
          'you should not unregister the standard autoloader once registered'
       );
     }
  }
}
namespace NbeZfLoader {
use ZendLoader as ZendLoader;
  class StandardAutoloader extends ZendLoaderStandardAutoloader {
     use ZendLoaderSplRegister {
       ZendLoaderStandardAutoloader::unregister insteadof ZendLoaderSplRegister;
     }
  }
}
namespace {
  $loader = new NbeZfLoaderStandardAutoloader();
  $loader->register(); //will register (trait)
  $loader->unregister(); // will throw RuntimeException (base class)
}
insteadof



Can be used to say which method
to use instead of the trait method.
Multiple Traits
namespace ZendFilter {
  trait Locale {
          protected $locale;

            public function getLocale() { return $this->locale; }

            public function setLocale($locale = null) {
                $this->locale = ZendLocale::findLocale($locale);
                return $this;
            }
    }

    trait WhiteSpace {
            protected $allowWhiteSpace;

            public function getAllowWhiteSpace() { return $this->allowWhiteSpace; }

            public function setAllowWhiteSpace($allowWhiteSpace) {
                $this->allowWhiteSpace = (boolean) $allowWhiteSpace;
                return $this;
            }
    }

        class Alpha extends AbstractFilter { use Locale, WhiteSpace; }
}
Multiple Conflicting Traits

     The Diamond Problem

(Not yours or a girls best friend!)
namespace ZendFilter {
    trait Locale {
          protected $locale;
          public function getLocale() { return $this->locale; }
          public function setLocale($locale = null) {
               $this->locale = ZendLocale::findLocale($locale);
               return $this;
          }
    }

    trait SecondLocale {
          protected $locale;
          public function setLocale($locale = null) {
              if (is_string($locale)) {
                  $locale = array($locale);
              } elseif ($locale instanceof Locale) {
                  $locale = array($locale->toString());
              } elseif (!is_array($locale)) {
                  throw new ExceptionInvalidArgumentException(
                       'Locale has to be string, array or an instance of Zend_Locale'
                  );
              }
              foreach ($locale as $single) {
                  if (!Locale::isLocale($single)) {
                       throw new ExceptionInvalidArgumentException("Unknown locale '$single'");
                  }
              }
              $this->_locale = $locale;
              return $this;
          }
    }
    class Alpha { use Locale, SecondLocale; }
}
namespace {
    (new ZendFilterAlpha)->setLocale('nl_be');
}
Fatal error: Trait method getLocale
has not been applied, because there
    are collisions with other trait
               methods
Insteadof

to the rescue
namespace ZendFilter {
  trait Locale {
          protected $locale;

        public function getLocale()

        public function setLocale($locale = null)
  }

  trait SecondLocale {
          protected $locale;

        public function setLocale($locale = null)
  }

  class Alpha {
        use Locale, SecondLocale {
          SecondLocale::setLocale insteadof Locale;
        }
  }
}
namespace {
    $alpha = new ZendFilterAlpha();
    $alpha->setLocale('nl_be');
}
WIN!
BUT
Strict Standards: ZendFilterLocale
   and ZendFilterSecondLocale
define the same property ($locale)
         in the composition of
 ZendFilterAlpha. This might be
       incompatible, to improve
   maintainability consider using
accessor methods in traits instead.
namespace ZendFilter {
  trait Locale {
           protected $locale = 'nl_BE';
           public function getLocale()
           public function setLocale($locale = null)
  }

  trait SecondLocale {
          protected $locale = 'en_US';
          public function setLocale($locale = null)
  }

  class Alpha {
        use Locale, SecondLocale {
          SecondLocale::setLocale insteadof Locale;
        }
  }
}
namespace {
    $alpha = new ZendFilterAlpha();
    $alpha->setLocale('nl_BE');
}
Fatal error: ZendFilterLocale and
ZendFilterSecondLocale define the
   same property ($locale) in the
 composition of ZendFilterAlpha.
However, the definition differs and is
     considered incompatible.
namespace ZendFilter {
  trait Locale {
          static public $locale = 'en_US';
          public function getLocale() { return self::$locale; }
          public function setLocale($locale = null)
          { self::$locale = $locale; }
  }

  class Alpha {
        use Locale;
        public function get() { return self::$locale; }
  }
}
namespace {
    $alpha = new ZendFilterAlpha();
    echo $alpha->getLocale(); // en_US
    echo $alpha->get(); // en_US
    $alpha->setLocale('nl_be');
    echo $alpha->getLocale(); // nl_be
    echo $alpha->get(); // nl_be
}
namespace ZendFilter {
  trait Locale {
          static public $locale = 'en_US';
          public function getLocale() { return self::$locale; }
          public function setLocale($locale = null)
          { self::$locale = $locale; }
  }

  class Alpha {
        use Locale;
        public function get() { return self::$locale; }
  }
  class Beta { use Locale; }
}
namespace {
    $alpha = new ZendFilterAlpha();
    echo $alpha->getLocale(); // en_US
    $alpha->setLocale('nl_be');
    echo $alpha->getLocale(); // nl_be
    $beta = new ZendFilterBeta(); echo $beta->getLocale(); //en_US
}
Aliassing, useful to replace the
       parent:: construct
namespace ZendMvcController {
Use ...
    trait StdlibDispatch {
             public function dispatch(Request $request, Response $response = null) {
                $this->request = $request;
                if (!$response) { $response = new HttpResponse(); }
                $this->response = $response;
                ...
                if ($result->stopped()) { return $result->last(); }
                return $e->getResult();
            }
    }

        abstract class ActionController implements Dispatchable, InjectApplicationEvent, LocatorAware {
            use StdlibDispatch;
        }

        abstract class RestfulController implementsDispatchable, InjectApplicationEvent, LocatorAware {
            use StdlibDispatch {StdlibDispatch::dispatch as dispatchTrait};


            public function dispatch(Request $request, Response $response = null) {
                if (!$request instanceof HttpRequest) {
                    throw new InvalidArgumentException('Expected an HTTP request');
                }
                return $this->dispatchTrait($request, $response);
            }
        }
}
Aliasing could potentially be a
    refactoring nightmare
namespace ZendView;
class TemplatePathStack implements
TemplateResolver
{
    use Options {
        Options::setOptions as setConfig
    }
}
$templateStack = (new TemplatePathStack)
->setConfig(['lfi_protection' => true]);

//$templateStack = (new TemplatePathStack)
->setOptions(['lfi_protection' => true]);
Visibility
namespace ZendView;
class TemplatePathStack implements
TemplateResolver
{
    use Options {Options::setOptions as protected}


    public function __construct($options = array())
    { $this->setOptions($options); }


}
new TemplatePathStack(['lfi_protection' => true]);
Interface compliance
namespace ZendView;
trait Options {
    public function setOptions($options) {
         //set the options
    }
}
interface TemplateResolver {
    public function setConfig($options);
}


class TemplatePathStack implements TemplateResolver {
    use Options {Options::setOptions as setConfig;}
}
(new TemplatePathStack)->setConfig(['lfi_protection' => true]);
namespace ZendView;
trait Options {
    public function setOptions($options) { }
}

class TemplatePathStack {
    use Options {
         Options::setOptions as setConfig;
    }
}
$templateStack = (new TemplatePathStack)
->setConfig(['lfi_protection' => true]);
var_dump($templateStack instanceof Options);
// false
namespace ZendView;
trait Options {
    abstract public function setOptions($options);
}

class TemplatePathStack {
    use Options;
    public function setOptions($options)
    { echo 'implementation enforced by trait'; }
}
$templateStack = (new TemplatePathStack)
->setOptions(['lfi_protection' => true]);
var_dump($templateStack instanceof Options); // false
namespace ZendView;
trait Options {
    abstract public function setOptions($options);
}

class TemplatePathStack {
    use Options {Options::setOptions as setConfig;}

    public function setConfig($options)
    { echo 'implementation enforced by trait'; }
}
// Fatal error: Class ZendViewTemplatePathStack
contains 1 abstract method and must therefore be
declared abstract or implement the remaining methods
(ZendViewTemplatePathStack::setOptions)
Magic Constants
<?php
trait Id {
     public function getClass() {
         echo __CLASS__;
     }
     public function getTrait() {
         echo __TRAIT__;
     }
 }

class Foo {
     use Id;
 }

(new Foo)->getClass(); //Foo
(new Foo)->getTrait(); //Id
Autoloading
<?php
namespace NbeZfLoader{
    class foo {
        use Id;
    }
}
namespace {
    function __autoload($class) {
        var_dump($class);
        die();
    }
}
// string(15) "NbeZfLoaderId"
Good things about
                 traits

●   Removes code duplication
●   Helps keeping your code cleaner
●   Maintainability
●   Aliassing works for interfaces
●   Property handling
●   Easy Autoloading
Bad things
    about traits
●   Adds code complexity /
    understandability with the
    insteadof operator.
●   Duck typing
●   Aliassing Fails for Abstract
    Classes
●   Property handling
Benchmarks 5.3 vs 5.4
●   ZF project: http://nickbelhomme.com
●   Benchmark / Profiling tool: xhprof
●   How: 2 VirtualBox Machines - debian clones,
    with only PHP upgrade (5.4.0RC3)
5.3.3

●   Total Incl. Wall Time (microsec): 674,842 ms
●   Total Incl. CPU (microsecs): 672,042 ms
●   Total Incl. MemUse (bytes): 13,827,864 bytes
●   Total Incl. PeakMemUse (bytes): 13,865,976
    bytes
●   Number of Function Calls: 14,524
5.4.0RC3
    Total Incl. Wall Time (microsec): 166,813 ms
●   Total Incl. CPU (microsecs): 168,011 ms
●   Total Incl. MemUse (bytes):7,969,928 bytes
●   Total Incl. PeakMemUse (bytes):8,015,944
    bytes
●   Number of Function Calls: 14,520
Who runs PHP5.4 today for testing?
YOU WIN




  6
Please rate my talk
https://joind.in/4774
The End!

                   THANK YOU
          Please rate my talk
          https://joind.in/4774
contact@nickbelhomme.com

Slideshare, Twitter, IRC: NickBelhomme

http://blog.nickbelhomme.com
Flickr Photo Credits
●   Helico
●   donkeyhotey
●   jannem
●   Thomas.constantin
●   SJ photography
●   davidagalvan
●   stev.ie
●   Mosman Council
●   DeaPeaJay

More Related Content

What's hot

Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)James Titcumb
 
Fighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnitFighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnitJames Fuller
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterZendCon
 
How to deploy node to production
How to deploy node to productionHow to deploy node to production
How to deploy node to productionSean Hess
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4Wim Godden
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPANcharsbar
 
CLI, the other SAPI
CLI, the other SAPICLI, the other SAPI
CLI, the other SAPICombell NV
 
PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)Win Yu
 
Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Wim Godden
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPDoctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPGuilherme Blanco
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
30 Minutes To CPAN
30 Minutes To CPAN30 Minutes To CPAN
30 Minutes To CPANdaoswald
 
2021.laravelconf.tw.slides2
2021.laravelconf.tw.slides22021.laravelconf.tw.slides2
2021.laravelconf.tw.slides2LiviaLiaoFontech
 
DevOps in PHP environment
DevOps in PHP environment DevOps in PHP environment
DevOps in PHP environment Evaldo Felipe
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Damien Seguy
 

What's hot (20)

Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
 
Fighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnitFighting Fear-Driven-Development With PHPUnit
Fighting Fear-Driven-Development With PHPUnit
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
PHP 5.3
PHP 5.3PHP 5.3
PHP 5.3
 
How to deploy node to production
How to deploy node to productionHow to deploy node to production
How to deploy node to production
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4
 
PHP7 is coming
PHP7 is comingPHP7 is coming
PHP7 is coming
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPAN
 
CLI, the other SAPI
CLI, the other SAPICLI, the other SAPI
CLI, the other SAPI
 
Modern PHP
Modern PHPModern PHP
Modern PHP
 
PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)
 
Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011
 
Php mysql ppt
Php mysql pptPhp mysql ppt
Php mysql ppt
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPDoctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHP
 
Spl in the wild
Spl in the wildSpl in the wild
Spl in the wild
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
30 Minutes To CPAN
30 Minutes To CPAN30 Minutes To CPAN
30 Minutes To CPAN
 
2021.laravelconf.tw.slides2
2021.laravelconf.tw.slides22021.laravelconf.tw.slides2
2021.laravelconf.tw.slides2
 
DevOps in PHP environment
DevOps in PHP environment DevOps in PHP environment
DevOps in PHP environment
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)
 

Viewers also liked

Php basics
Php basicsPhp basics
Php basicshamfu
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6Wim Godden
 
Php tutorial
Php tutorialPhp tutorial
Php tutorialNiit
 
Object Relational Mapping in PHP
Object Relational Mapping in PHPObject Relational Mapping in PHP
Object Relational Mapping in PHPRob Knight
 
Healthcare management powerpoint
Healthcare management powerpointHealthcare management powerpoint
Healthcare management powerpointKorrin Wiggins
 
SMS il RE della comunicazione
SMS il RE della comunicazioneSMS il RE della comunicazione
SMS il RE della comunicazioneDavide Ricca
 
Kuidas Targad Juhid Tegutsevad 2007
Kuidas Targad Juhid Tegutsevad 2007Kuidas Targad Juhid Tegutsevad 2007
Kuidas Targad Juhid Tegutsevad 2007Fastleader
 
Presentation 1112 for blog 2
Presentation 1112 for blog 2Presentation 1112 for blog 2
Presentation 1112 for blog 2katie_higson
 
Personal Branding &amp; You-How to use social Media to create tour own person...
Personal Branding &amp; You-How to use social Media to create tour own person...Personal Branding &amp; You-How to use social Media to create tour own person...
Personal Branding &amp; You-How to use social Media to create tour own person...David Wesson
 
新浪微博的BigPipe后端实现技术分享——11月26日淘宝aDev技术沙龙
新浪微博的BigPipe后端实现技术分享——11月26日淘宝aDev技术沙龙新浪微博的BigPipe后端实现技术分享——11月26日淘宝aDev技术沙龙
新浪微博的BigPipe后端实现技术分享——11月26日淘宝aDev技术沙龙slawdan
 
Transformation or Transition
Transformation or TransitionTransformation or Transition
Transformation or TransitionMike Pounsford
 
صداقت حضرت مسیح موعود علیہ السلام از احادیث
صداقت حضرت مسیح موعود علیہ السلام از احادیثصداقت حضرت مسیح موعود علیہ السلام از احادیث
صداقت حضرت مسیح موعود علیہ السلام از احادیثmuzaffertahir9
 

Viewers also liked (20)

Php basics
Php basicsPhp basics
Php basics
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6
 
Php
PhpPhp
Php
 
PHP slides
PHP slidesPHP slides
PHP slides
 
Php tutorial
Php tutorialPhp tutorial
Php tutorial
 
Object Relational Mapping in PHP
Object Relational Mapping in PHPObject Relational Mapping in PHP
Object Relational Mapping in PHP
 
Healthcare management powerpoint
Healthcare management powerpointHealthcare management powerpoint
Healthcare management powerpoint
 
ספר וטהר לבנו השלם.
ספר וטהר לבנו השלם.ספר וטהר לבנו השלם.
ספר וטהר לבנו השלם.
 
SMS il RE della comunicazione
SMS il RE della comunicazioneSMS il RE della comunicazione
SMS il RE della comunicazione
 
Suzuki adferdin god_uppskrift
Suzuki adferdin  god_uppskriftSuzuki adferdin  god_uppskrift
Suzuki adferdin god_uppskrift
 
Kuidas Targad Juhid Tegutsevad 2007
Kuidas Targad Juhid Tegutsevad 2007Kuidas Targad Juhid Tegutsevad 2007
Kuidas Targad Juhid Tegutsevad 2007
 
Presentation 1112 for blog 2
Presentation 1112 for blog 2Presentation 1112 for blog 2
Presentation 1112 for blog 2
 
cv pdf
cv pdfcv pdf
cv pdf
 
ΒΑΚΑΛΟΥΔΗ - ΠΡΟΣΚΛΗΣΗ
ΒΑΚΑΛΟΥΔΗ - ΠΡΟΣΚΛΗΣΗΒΑΚΑΛΟΥΔΗ - ΠΡΟΣΚΛΗΣΗ
ΒΑΚΑΛΟΥΔΗ - ΠΡΟΣΚΛΗΣΗ
 
Retallos 2008
Retallos 2008Retallos 2008
Retallos 2008
 
Tautas ataudzes mērķi NAP2020 un to sasniegšanas gaita
Tautas ataudzes mērķi NAP2020 un to sasniegšanas gaitaTautas ataudzes mērķi NAP2020 un to sasniegšanas gaita
Tautas ataudzes mērķi NAP2020 un to sasniegšanas gaita
 
Personal Branding &amp; You-How to use social Media to create tour own person...
Personal Branding &amp; You-How to use social Media to create tour own person...Personal Branding &amp; You-How to use social Media to create tour own person...
Personal Branding &amp; You-How to use social Media to create tour own person...
 
新浪微博的BigPipe后端实现技术分享——11月26日淘宝aDev技术沙龙
新浪微博的BigPipe后端实现技术分享——11月26日淘宝aDev技术沙龙新浪微博的BigPipe后端实现技术分享——11月26日淘宝aDev技术沙龙
新浪微博的BigPipe后端实现技术分享——11月26日淘宝aDev技术沙龙
 
Transformation or Transition
Transformation or TransitionTransformation or Transition
Transformation or Transition
 
صداقت حضرت مسیح موعود علیہ السلام از احادیث
صداقت حضرت مسیح موعود علیہ السلام از احادیثصداقت حضرت مسیح موعود علیہ السلام از احادیث
صداقت حضرت مسیح موعود علیہ السلام از احادیث
 

Similar to PHP traits, treat or threat?

PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overviewjsmith92
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic ComponentsMateusz Tymek
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaPatrick Allaert
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony TechniquesKris Wallsmith
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developersAndrew Eddie
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Shinya Ohyanagi
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5Wim Godden
 
The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5Wim Godden
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 

Similar to PHP traits, treat or threat? (20)

PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
 
Fatc
FatcFatc
Fatc
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic Components
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developers
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
Slide
SlideSlide
Slide
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
php AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdfphp AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdf
 
Php Tutorials for Beginners
Php Tutorials for BeginnersPhp Tutorials for Beginners
Php Tutorials for Beginners
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Solid principles
Solid principlesSolid principles
Solid principles
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5
 
The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Zend Framework 2 Patterns
Zend Framework 2 PatternsZend Framework 2 Patterns
Zend Framework 2 Patterns
 

More from Nick Belhomme

Vagrant move over, here is Docker
Vagrant move over, here is DockerVagrant move over, here is Docker
Vagrant move over, here is DockerNick Belhomme
 
Mastering selenium for automated acceptance tests
Mastering selenium for automated acceptance testsMastering selenium for automated acceptance tests
Mastering selenium for automated acceptance testsNick Belhomme
 
PHP Quality Assurance Workshop PHPBenelux
PHP Quality Assurance Workshop PHPBeneluxPHP Quality Assurance Workshop PHPBenelux
PHP Quality Assurance Workshop PHPBeneluxNick Belhomme
 
Zend Framework Form: Mastering Decorators
Zend Framework Form: Mastering DecoratorsZend Framework Form: Mastering Decorators
Zend Framework Form: Mastering DecoratorsNick Belhomme
 
Zend Framework 1.8 workshop
Zend Framework 1.8 workshopZend Framework 1.8 workshop
Zend Framework 1.8 workshopNick Belhomme
 

More from Nick Belhomme (6)

Vagrant move over, here is Docker
Vagrant move over, here is DockerVagrant move over, here is Docker
Vagrant move over, here is Docker
 
Mastering selenium for automated acceptance tests
Mastering selenium for automated acceptance testsMastering selenium for automated acceptance tests
Mastering selenium for automated acceptance tests
 
PHP Quality Assurance Workshop PHPBenelux
PHP Quality Assurance Workshop PHPBeneluxPHP Quality Assurance Workshop PHPBenelux
PHP Quality Assurance Workshop PHPBenelux
 
Cursus phpunit
Cursus phpunitCursus phpunit
Cursus phpunit
 
Zend Framework Form: Mastering Decorators
Zend Framework Form: Mastering DecoratorsZend Framework Form: Mastering Decorators
Zend Framework Form: Mastering Decorators
 
Zend Framework 1.8 workshop
Zend Framework 1.8 workshopZend Framework 1.8 workshop
Zend Framework 1.8 workshop
 

Recently uploaded

KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxGDSC PJATK
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UbiTrack UK
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdfJamie (Taka) Wang
 
Babel Compiler - Transforming JavaScript for All Browsers.pptx
Babel Compiler - Transforming JavaScript for All Browsers.pptxBabel Compiler - Transforming JavaScript for All Browsers.pptx
Babel Compiler - Transforming JavaScript for All Browsers.pptxYounusS2
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
Things you didn't know you can use in your Salesforce
Things you didn't know you can use in your SalesforceThings you didn't know you can use in your Salesforce
Things you didn't know you can use in your SalesforceMartin Humpolec
 
Spring24-Release Overview - Wellingtion User Group-1.pdf
Spring24-Release Overview - Wellingtion User Group-1.pdfSpring24-Release Overview - Wellingtion User Group-1.pdf
Spring24-Release Overview - Wellingtion User Group-1.pdfAnna Loughnan Colquhoun
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaborationbruanjhuli
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
Do we need a new standard for visualizing the invisible?
Do we need a new standard for visualizing the invisible?Do we need a new standard for visualizing the invisible?
Do we need a new standard for visualizing the invisible?SANGHEE SHIN
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 

Recently uploaded (20)

KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptx
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
20200723_insight_release_plan_v6.pdf20200723_insight_release_plan_v6.pdf
 
Babel Compiler - Transforming JavaScript for All Browsers.pptx
Babel Compiler - Transforming JavaScript for All Browsers.pptxBabel Compiler - Transforming JavaScript for All Browsers.pptx
Babel Compiler - Transforming JavaScript for All Browsers.pptx
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
Things you didn't know you can use in your Salesforce
Things you didn't know you can use in your SalesforceThings you didn't know you can use in your Salesforce
Things you didn't know you can use in your Salesforce
 
Spring24-Release Overview - Wellingtion User Group-1.pdf
Spring24-Release Overview - Wellingtion User Group-1.pdfSpring24-Release Overview - Wellingtion User Group-1.pdf
Spring24-Release Overview - Wellingtion User Group-1.pdf
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
Do we need a new standard for visualizing the invisible?
Do we need a new standard for visualizing the invisible?Do we need a new standard for visualizing the invisible?
Do we need a new standard for visualizing the invisible?
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 

PHP traits, treat or threat?

  • 1. PHP traits, treat or threat? Nick Belhomme January 28th, PHPBenelux Conference 2012, Belgium
  • 2. Software Architect / Project Lead Author of the Zend Framework 2.0 Cookbook International Conference Speaker Contributor to various Open Source Projects Freelance PHP Consultant
  • 3. Market positions http://w3techs.com/
  • 4. Market positions ● Python 0.3%
  • 5. Market positions ● Ruby 0.6% ● Python 0.3%
  • 6. Market positions ● Perl 1.0% ● Ruby 0.6% ● Python 0.3%
  • 7. Market positions ● ColdFusion 1.2% ● Perl 1.0% ● Ruby 0.6% ● Python 0.3%
  • 8. Market positions ● Java 1.2% ● ColdFusion 1.2% ● Perl 1.0% ● Ruby 0.6% ● Python 0.3%
  • 9. Market positions ● ASP.NET 21.6% ● Java 1.2% ● ColdFusion 1.2% ● Perl 1.0% ● Ruby 0.6% ● Python 0.3%
  • 10. Market positions ● PHP 77.4% ● ASP.NET 21.6% ● Java 1.2% ● ColdFusion 1.2% ● Perl 1.0% ● Ruby 0.6% ● Python 0.3%
  • 11. PHP Market Position, 11 Jan 2012 Used by high traffic sites Java ColdFusion Perl ASP.NET PHP Used by low traffic sites Used by fewer sites Used by many sites
  • 12. PHP Version Adoption ● PHP 5 93.9% ● PHP 4 6.1% ● PHP 3 < 0.1% ● PHP 6 < 0.1%
  • 13. PHP 5 usage ● Version 5.2 73.8% ● Version 5.3 20.2% ● Version 5.1 5.8% ● Version 5.0 0.2% ● Version 5.4 < 0.1%
  • 14. Slow 5.3 Adoption? ● Shared hosting ● Companies refrain from updating stable systems / distributions ● You
  • 15. Adopt now ● More stability ● Security ● Better engine (ie garbage collection) ● New language features ● Cleaner code because of more elegant ways of solving problems
  • 16. PHP 5.4 ● Array short syntax (javascript notation) ● Array dereferencing ● Class access on instantiation ● Indirect method call by array variable ● Engine processes OO code faster ● <?= ● JSONSerializable interface ● ...
  • 18. ZF Use Case ZF Code base used is for illustration purposes only and do –not-- express future possible implementations. ZF2.0 is not yet released so giving ZF3.0 implementations illustrates only my own assumptions. PHP5.4 stable is not yet released so no real world projects are and should be running this version. Because of this no real best practices have been defined.
  • 19. namespace ZendView; class TemplatePathStack implements TemplateResolver { public function setOptions($options = array()) { if (!is_array($options) && !$options instanceof Traversable) { throw new ExceptionInvalidArgumentException( __METHOD__ . ' expects an array or Traversable' ); } foreach ($options as $key => $value) { $this->setOption($key, $value); } return $this; } public function setOption($key, $value) { switch (strtolower($key)) { case 'lfi_protection': $this->setLfiProtection($value); break; case 'script_paths': $this->addPaths($value); break; default: break; } } }
  • 20. namespace ZendMvcRouter; class RouteBroker implements Broker { public function setOptions($options) { if (!is_array($options) && !$options instanceof Traversable) { throw new ExceptionInvalidArgumentException(sprintf( 'Expected an array or Traversable; received "%s"', (is_object($options) ? get_class($options) : gettype($options)) )); } foreach ($options as $key => $value) { switch (strtolower($key)) { case 'class_loader': // handle this case Default: break;// ignore unknown options } } return $this; } }
  • 21. Problem: Code Duplication if (!is_array($options) && !$options instanceof Traversable) { throw new ExceptionInvalidArgumentException(sprintf( 'Expected an array or Traversable; received "%s"', (is_object($options) ? get_class($options) : gettype($options)) )); } foreach ($options as $key => $value) { //handle each case } return $this;
  • 22. Solution in PHP5.4? Multiple Inheritance ● Would provide the setOptions in all child classes needed ● Introduces the diamond problem
  • 23. NOT an Option! A better solution called Traits ● Would provide the setOptions in all classes that use the trait ● Eliminates the diamond problem
  • 24. trait Options { public function setOptions($options) { if (!is_array($options) && !$options instanceof Traversable) { throw new ExceptionInvalidArgumentException(sprintf( 'Expected an array or Traversable; received "%s"', (is_object($options) ? get_class($options) : gettype($options)) )); } foreach ($options as $key => $value) { $this->setOption($key, $value); } return $this; } }
  • 25. namespace ZendView; class TemplatePathStack implements TemplateResolver { use Options; public function setOption($key, $value) { switch (strtolower($key)) { case 'lfi_protection': $this->setLfiProtection($value); break; case 'script_paths': $this->addPaths($value); break; default: break; } } } $templateStack = new TemplatePathStack(); $templateStack->setOptions(['lfi_protection' => true]);
  • 26. namespace ZendMvcRouter; class RouteBroker implements Broker { use Options; public function setOption($key, $value) { switch (strtolower($key)) { case 'class_loader': // handle this case default: // ignore unknown options break; } } } $routeBroker = (new RouteBroker)->setOptions(['class_loader'=>'SomeLoader']);
  • 27. You have just seen traits
  • 28. Lets dive deeper get your chest wet
  • 29. namespace ZendLoader { use RuntimeException; trait SplRegister { public function register() { spl_autoload_register(array($this, 'autoload')); } public function unregister() { spl_autoload_unregister(array($this, 'autoload')); } } class StandardAutoloader { use SplRegister; public function unregister() { throw new RuntimeException( 'you should not unregister the standard autoloader once registered' ); } } } namespace { $loader = new ZendLoaderStandardAutoloader(); $loader->register(); $loader->unregister(); // will throw the exception }
  • 30. Precedence Order The precedence order is that members from the current class override Trait methods.
  • 31. namespace ZendLoader { use RuntimeException; class StandardAutoloader { public function unregister() { throw new RuntimeException( 'you should not unregister the standard autoloader once registered' ); } } } namespace NbeZfLoader { use ZendLoader as ZendLoader; class StandardAutoloader extends ZendLoaderStandardAutoloader { use ZendLoaderSplRegister; } } namespace { $loader = new NbeZfLoaderStandardAutoloader(); $loader->register(); //will register (trait) $loader->unregister(); // will unregister (trait) }
  • 32. Precedence Order An inherited member from a base class is overridden by a member inserted by a Trait
  • 34. namespace ZendLoader { use RuntimeException; class StandardAutoloader { public function unregister() { throw new RuntimeException( 'you should not unregister the standard autoloader once registered' ); } } } namespace NbeZfLoader { use ZendLoader as ZendLoader; class StandardAutoloader extends ZendLoaderStandardAutoloader { use ZendLoaderSplRegister { ZendLoaderStandardAutoloader::unregister insteadof ZendLoaderSplRegister; } } } namespace { $loader = new NbeZfLoaderStandardAutoloader(); $loader->register(); //will register (trait) $loader->unregister(); // will throw RuntimeException (base class) }
  • 35. insteadof Can be used to say which method to use instead of the trait method.
  • 37. namespace ZendFilter { trait Locale { protected $locale; public function getLocale() { return $this->locale; } public function setLocale($locale = null) { $this->locale = ZendLocale::findLocale($locale); return $this; } } trait WhiteSpace { protected $allowWhiteSpace; public function getAllowWhiteSpace() { return $this->allowWhiteSpace; } public function setAllowWhiteSpace($allowWhiteSpace) { $this->allowWhiteSpace = (boolean) $allowWhiteSpace; return $this; } } class Alpha extends AbstractFilter { use Locale, WhiteSpace; } }
  • 38. Multiple Conflicting Traits The Diamond Problem (Not yours or a girls best friend!)
  • 39. namespace ZendFilter { trait Locale { protected $locale; public function getLocale() { return $this->locale; } public function setLocale($locale = null) { $this->locale = ZendLocale::findLocale($locale); return $this; } } trait SecondLocale { protected $locale; public function setLocale($locale = null) { if (is_string($locale)) { $locale = array($locale); } elseif ($locale instanceof Locale) { $locale = array($locale->toString()); } elseif (!is_array($locale)) { throw new ExceptionInvalidArgumentException( 'Locale has to be string, array or an instance of Zend_Locale' ); } foreach ($locale as $single) { if (!Locale::isLocale($single)) { throw new ExceptionInvalidArgumentException("Unknown locale '$single'"); } } $this->_locale = $locale; return $this; } } class Alpha { use Locale, SecondLocale; } } namespace { (new ZendFilterAlpha)->setLocale('nl_be'); }
  • 40. Fatal error: Trait method getLocale has not been applied, because there are collisions with other trait methods
  • 42. namespace ZendFilter { trait Locale { protected $locale; public function getLocale() public function setLocale($locale = null) } trait SecondLocale { protected $locale; public function setLocale($locale = null) } class Alpha { use Locale, SecondLocale { SecondLocale::setLocale insteadof Locale; } } } namespace { $alpha = new ZendFilterAlpha(); $alpha->setLocale('nl_be'); }
  • 43. WIN!
  • 44. BUT Strict Standards: ZendFilterLocale and ZendFilterSecondLocale define the same property ($locale) in the composition of ZendFilterAlpha. This might be incompatible, to improve maintainability consider using accessor methods in traits instead.
  • 45. namespace ZendFilter { trait Locale { protected $locale = 'nl_BE'; public function getLocale() public function setLocale($locale = null) } trait SecondLocale { protected $locale = 'en_US'; public function setLocale($locale = null) } class Alpha { use Locale, SecondLocale { SecondLocale::setLocale insteadof Locale; } } } namespace { $alpha = new ZendFilterAlpha(); $alpha->setLocale('nl_BE'); }
  • 46. Fatal error: ZendFilterLocale and ZendFilterSecondLocale define the same property ($locale) in the composition of ZendFilterAlpha. However, the definition differs and is considered incompatible.
  • 47. namespace ZendFilter { trait Locale { static public $locale = 'en_US'; public function getLocale() { return self::$locale; } public function setLocale($locale = null) { self::$locale = $locale; } } class Alpha { use Locale; public function get() { return self::$locale; } } } namespace { $alpha = new ZendFilterAlpha(); echo $alpha->getLocale(); // en_US echo $alpha->get(); // en_US $alpha->setLocale('nl_be'); echo $alpha->getLocale(); // nl_be echo $alpha->get(); // nl_be }
  • 48. namespace ZendFilter { trait Locale { static public $locale = 'en_US'; public function getLocale() { return self::$locale; } public function setLocale($locale = null) { self::$locale = $locale; } } class Alpha { use Locale; public function get() { return self::$locale; } } class Beta { use Locale; } } namespace { $alpha = new ZendFilterAlpha(); echo $alpha->getLocale(); // en_US $alpha->setLocale('nl_be'); echo $alpha->getLocale(); // nl_be $beta = new ZendFilterBeta(); echo $beta->getLocale(); //en_US }
  • 49. Aliassing, useful to replace the parent:: construct
  • 50. namespace ZendMvcController { Use ... trait StdlibDispatch { public function dispatch(Request $request, Response $response = null) { $this->request = $request; if (!$response) { $response = new HttpResponse(); } $this->response = $response; ... if ($result->stopped()) { return $result->last(); } return $e->getResult(); } } abstract class ActionController implements Dispatchable, InjectApplicationEvent, LocatorAware { use StdlibDispatch; } abstract class RestfulController implementsDispatchable, InjectApplicationEvent, LocatorAware { use StdlibDispatch {StdlibDispatch::dispatch as dispatchTrait}; public function dispatch(Request $request, Response $response = null) { if (!$request instanceof HttpRequest) { throw new InvalidArgumentException('Expected an HTTP request'); } return $this->dispatchTrait($request, $response); } } }
  • 51. Aliasing could potentially be a refactoring nightmare
  • 52. namespace ZendView; class TemplatePathStack implements TemplateResolver { use Options { Options::setOptions as setConfig } } $templateStack = (new TemplatePathStack) ->setConfig(['lfi_protection' => true]); //$templateStack = (new TemplatePathStack) ->setOptions(['lfi_protection' => true]);
  • 54. namespace ZendView; class TemplatePathStack implements TemplateResolver { use Options {Options::setOptions as protected} public function __construct($options = array()) { $this->setOptions($options); } } new TemplatePathStack(['lfi_protection' => true]);
  • 56. namespace ZendView; trait Options { public function setOptions($options) { //set the options } } interface TemplateResolver { public function setConfig($options); } class TemplatePathStack implements TemplateResolver { use Options {Options::setOptions as setConfig;} } (new TemplatePathStack)->setConfig(['lfi_protection' => true]);
  • 57. namespace ZendView; trait Options { public function setOptions($options) { } } class TemplatePathStack { use Options { Options::setOptions as setConfig; } } $templateStack = (new TemplatePathStack) ->setConfig(['lfi_protection' => true]); var_dump($templateStack instanceof Options); // false
  • 58. namespace ZendView; trait Options { abstract public function setOptions($options); } class TemplatePathStack { use Options; public function setOptions($options) { echo 'implementation enforced by trait'; } } $templateStack = (new TemplatePathStack) ->setOptions(['lfi_protection' => true]); var_dump($templateStack instanceof Options); // false
  • 59. namespace ZendView; trait Options { abstract public function setOptions($options); } class TemplatePathStack { use Options {Options::setOptions as setConfig;} public function setConfig($options) { echo 'implementation enforced by trait'; } } // Fatal error: Class ZendViewTemplatePathStack contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (ZendViewTemplatePathStack::setOptions)
  • 60. Magic Constants <?php trait Id { public function getClass() { echo __CLASS__; } public function getTrait() { echo __TRAIT__; } } class Foo { use Id; } (new Foo)->getClass(); //Foo (new Foo)->getTrait(); //Id
  • 61. Autoloading <?php namespace NbeZfLoader{ class foo { use Id; } } namespace { function __autoload($class) { var_dump($class); die(); } } // string(15) "NbeZfLoaderId"
  • 62. Good things about traits ● Removes code duplication ● Helps keeping your code cleaner ● Maintainability ● Aliassing works for interfaces ● Property handling ● Easy Autoloading
  • 63. Bad things about traits ● Adds code complexity / understandability with the insteadof operator. ● Duck typing ● Aliassing Fails for Abstract Classes ● Property handling
  • 64. Benchmarks 5.3 vs 5.4 ● ZF project: http://nickbelhomme.com ● Benchmark / Profiling tool: xhprof ● How: 2 VirtualBox Machines - debian clones, with only PHP upgrade (5.4.0RC3)
  • 65. 5.3.3 ● Total Incl. Wall Time (microsec): 674,842 ms ● Total Incl. CPU (microsecs): 672,042 ms ● Total Incl. MemUse (bytes): 13,827,864 bytes ● Total Incl. PeakMemUse (bytes): 13,865,976 bytes ● Number of Function Calls: 14,524
  • 66. 5.4.0RC3 Total Incl. Wall Time (microsec): 166,813 ms ● Total Incl. CPU (microsecs): 168,011 ms ● Total Incl. MemUse (bytes):7,969,928 bytes ● Total Incl. PeakMemUse (bytes):8,015,944 bytes ● Number of Function Calls: 14,520
  • 67. Who runs PHP5.4 today for testing?
  • 68. YOU WIN 6
  • 69. Please rate my talk https://joind.in/4774
  • 70. The End! THANK YOU Please rate my talk https://joind.in/4774 contact@nickbelhomme.com Slideshare, Twitter, IRC: NickBelhomme http://blog.nickbelhomme.com
  • 71. Flickr Photo Credits ● Helico ● donkeyhotey ● jannem ● Thomas.constantin ● SJ photography ● davidagalvan ● stev.ie ● Mosman Council ● DeaPeaJay