SlideShare a Scribd company logo
1 of 46
Download to read offline
Also known as
                      “Elizabeth Ranting about a Pet Peeve”




Zendcon 2008 – Santa Clara, CA
 Elizabeth  Marie Smith aka auroraeosrose
 Pink is good
 I hate computers
 I love programming
 Windows will not kill you
 Work at OmniTI (http://omniti.com)
 Contributor on various open source projects
  (including PHP, PECL and PHP-GTK)
 Why are you here?
 What are you hoping to learn?
  How to improve your code for use on PHP5?
  Improve meaning faster, more stable, easier to maintain
 What   do I want to teach?
    What is available in PHP5 to help with the “improve”
 What   do you already know?
    This is about what you CAN do not what you CAN’T do
If you remember
   only one thing
   from this talk,
   remember this
PHP 5.0.x is beta quality – don’t touch it with a ten foot pole



         PHP 5.1.x is better, but lacking stability and functionality
If you don’t know it exists, how can you use it?
We’ll get back to you later
 Every constructor is named __construct, use
  parent::__construct to chain
 Careful with __destruct, headers are sent
  and you can’t throw exceptions
<?php                                                  Kill da wabbit
class foo {                                            bar Object()
       protected $animal;
      public function __construct($animal) {           Fatal error: Call to private
          $this->animal = $animal;
      }                                                bar::__construct() from invalid
                                                       context in test.php on line 34
      public function __destruct() {
          echo 'Kill da ' . $this->animal . PHP_EOL;
      }
}
class bar {
    static $singleton;
      private function __construct() {}
      static public function getInstance() {
          if (!self::$singleton) {
              self::$singleton = new self;
          }
          return self::$singleton;
      }
}
$class = new foo('wabbit');
// $class = null; also works
unset($class);
$foo = bar::getInstance();
print_r($foo);
$foo = new bar;
 Keep                        people from messing with your stuff
                                                                             <?php                                                class Bar
                                                                             /**                                                  {
                                                                               * Define MyClass                                         public function test() {
                                                                               */                                                           $this->testPrivate();
<?php                                                                        class MyClass                                                  $this->testPublic();
/**                                                                          {                                                          }
  * Define MyClass
  */                                                                               // Declare a public constructor
class MyClass                                                                      public function __construct() { }                  public function testPublic() {
{                                                                                                                                         echo quot;Bar::testPublicnquot;;
                                                                                   // Declare a public method                         }
      public $public = 'Public';                                                   public function MyPublic() { }
      protected $protected = 'Protected';                                                                                             private function testPrivate() {
      private $private = 'Private';                                                // Declare a protected method                          echo quot;Bar::testPrivatenquot;;
                                                                                   protected function MyProtected() { }               }
     function      printHello()                                                                                                   }
     {
         echo      $this->public;                                                  // Declare a private method
         echo      $this->protected;                                               private function MyPrivate() { }               class Foo extends Bar
         echo      $this->private;                                                                                                {
     }                                                                             // This is public                                  public function testPublic() {
}                                                                                  function Foo()                                         echo quot;Foo::testPublicnquot;;
                                                                                   {                                                  }
$obj = new MyClass();                                                                     $this->MyPublic();
echo $obj->public; // Works                                                               $this->MyProtected();                       private function testPrivate() {
echo $obj->protected; // Fatal Error                                                      $this->MyPrivate();                             echo quot;Foo::testPrivatenquot;;
                                                                                   }                                                  }
echo $obj->private; // Fatal Error                                           }                                                    }
$obj->printHello(); // Shows Public, Protected and Private
                                                                             $myclass = new MyClass;                                $myFoo = new foo();
/**                                                                          $myclass->MyPublic(); // Works                         $myFoo->test(); // Bar::testPrivate
  * Define MyClass2                                                          $myclass->MyProtected(); // Fatal Error                                        // Foo::testPublic
  */                                                                         $myclass->MyPrivate(); // Fatal Error
class MyClass2 extends MyClass                                               $myclass->Foo(); // Public, Protected and Private work
{
      // We can redeclare the public and protected method, but not private   /**
      protected $protected = 'Protected2';                                     * Define MyClass2
                                                                               */
     function      printHello()                                              class MyClass2 extends MyClass
     {
         echo      $this->public;                                            {
         echo      $this->protected;                                               // This is public
         echo      $this->private;                                                 function Foo2()
     }                                                                             {
}                                                                                         $this->MyPublic();
                                                                                          $this->MyProtected();
$obj2 = new MyClass2();                                                                   $this->MyPrivate(); // Fatal Error
echo $obj2->public; // Works                                                       }
                                                                             }
echo $obj2->private; // Undefined
echo $obj2->protected; // Fatal Error                                        $myclass2 = new MyClass2;
$obj2->printHello(); // Shows Public, Protected2, Undefined                  $myclass2->MyPublic(); // Works
                                                                             $myclass2-
                                                                             >Foo2(); // Public and Protected work, not Private
 In PHP4 any assignment was a clone
 In PHP5 objects are passed by reference, to
  copy it we have clone it
<?php                             7
class foo {                       7
      public $bar;                9
}
                                  2
class funky {
    public $bar;
    public function __clone() {
        $this->bar++;
    }
}
$foo = new foo();
$foo->bar = 6;
$bar = $foo;
$bar->bar = 7;
echo $foo->bar . PHP_EOL;
echo $bar->bar . PHP_EOL;
$bar = clone $foo;
$bar->bar = 9;
echo $bar->bar . PHP_EOL;
$hello = new funky();
$hello->bar = 1;
$bar = clone $hello;
echo $bar->bar . PHP_EOL;
 Make                      your class follow a contract

<?php
// Declare the interface 'iTemplate'
interface iTemplate
{
       public function setVariable($name, $var);
       public function getHtml($template);
}
// Implement the interface
// This will work
class Template implements iTemplate
{
      private $vars = array();
     public function setVariable($name, $var)
     {
         $this->vars[$name] = $var;
     }
     public function getHtml($template)
     {
         foreach($this->vars as $name => $value) {
             $template = str_replace('{' . $name . '}', $value, $template);
         }
           return $template;
     }
}
// This will not work
// Fatal error: Class BadTemplate contains 1 abstract methods
// and must therefore be declared abstract (iTemplate::getHtml)
class BadTemplate implements iTemplate
{
       private $vars = array();
     public function setVariable($name, $var)
     {
         $this->vars[$name] = $var;
     }
}
 Common                                 base functionality you can extend

<?php
abstract class AbstractClass
                                                          ConcreteClass1
{                                                         FOO_ConcreteClass1
      // Force Extending class to define this method
      abstract protected function getValue();             ConcreteClass2
      abstract protected function prefixValue($prefix);
                                                          FOO_ConcreteClass2
     // Common method
     public function printOut() {
           print $this->getValue() . quot;nquot;;
     }
}
class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return quot;ConcreteClass1quot;;
    }
     public function prefixValue($prefix) {
         return quot;{$prefix}ConcreteClass1quot;;
     }
}
class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return quot;ConcreteClass2quot;;
    }
     public function prefixValue($prefix) {
         return quot;{$prefix}ConcreteClass2quot;;
     }
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') .quot;nquot;;
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') .quot;nquot;;
 __sleep and __wakeup say what to serialize,
    and what to do on unserialize
   __toString is obvious
   __set_state works with var_export()
<?php
class MakeMagic {
      protected $string;
      protected $prefix;
      private $cache;                                                      O:9:quot;MakeMagicquot;:2:{s:9:quot; *
      public function __construct($data, $prefix) {                        stringquot;;s:5:quot;happyquot;;s:9:quot; *
          $this->string = $data;
          $this->prefix = $prefix;                                         prefixquot;;s:2:quot;unquot;;}
          $this->cache();
      }                                                                    MakeMagic Object
      protected function cache() {                                         (
      }
          $this->cache = $this->prefix . $this->string;                        [string:protected] => happy
                                                                               [prefix:protected] => un
      public function __sleep() {
          return array('string', 'prefix');                                    [cache:MakeMagic:private] => unhappy
      }
                                                                           )
      public function __wakeup() {                                         unhappy
          $this->cache();
      }                                                                    MakeMagic Object
      public function __toString() {                                       (
          return $this->cache;
      }                                                                        [string:protected] => happy
      public static function __set_state($properties) {                        [prefix:protected] => un
          return new self($properties['string'], $properties['prefix']);       [cache:MakeMagic:private] => unhappy
      }
}                                                                          )
$class = new MakeMagic('happy', 'un');
$store = serialize($class);
echo $store . PHP_EOL;
$class = unserialize($store);
print_r($class);
echo $class . PHP_EOL;
$string = var_export($class, true);
eval('$test = ' . $string . ';');
print_r($test);
 Manipulate properties “magically”
   Change the way calls are made                                                                                                   Setting 'a' to '1'
                                                                                                                                    Getting 'a'
                                                                                                                                    1
<?php
class MemberTest {                                                    public function __call($name, $arguments) {
      /** Location for overloaded data. */                                // Note: value of $name is case sensitive.
      private $data = array();                                            echo quot;Calling object method '$name' quot;                     Is 'a' set?
      /** Overloading not used on declared members. */                }
                                                                                  . implode(', ', $arguments). quot;nquot;;                bool(true)
      public $declared = 1;                                     }                                                                   Unsetting 'a'
       /** Overloading only used on this when accessed outsid $obj = new MemberTest;                                                Is 'a' set?
e the class. */
       private $hidden = 2;                                      $obj->a = 1;                                                       bool(false)
                                                                 echo $obj->a . quot;nnquot;;
       public function __set($name, $value) {
             echo quot;Setting '$name' to '$value'nquot;;
             $this->data[$name] = $value;
                                                                 var_dump(isset($obj->a));
                                                                 unset($obj->a);
                                                                                                                                    1
       }                                                         var_dump(isset($obj->a));
                                                                 echo quot;nquot;;
       public function __get($name) {                                                                                               Let's experiment with the private
             echo quot;Getting '$name'nquot;;                           echo $obj->declared . quot;nnquot;;
             if (array_key_exists($name, $this->data)) {                                                                            property named 'hidden':
                    return $this->data[$name];                   echo quot;Let's experiment with the private property named 'hidd       Privates are visible inside the
             }                                                   en':nquot;;
                                                                 echo quot;Privates are visible inside the class, so __get() not use    class, so __get() not used...
             $trace = debug_backtrace();                         d...nquot;;
             trigger_error(                                      echo $obj->getHidden() . quot;nquot;;                                     2
                    'Undefined property via __get(): ' . $name . echo quot;Privates not visible outside of class, so __get() is used.
                    ' in ' . $trace[0]['file'] .                 ..nquot;;                                                             Privates not visible outside of
                    ' on line ' . $trace[0]['line'],             echo $obj->hidden . quot;nquot;;
                    E_USER_NOTICE);                              $obj->runTest('in object context');                                class, so __get() is used...
       }
             return null;                                                                                                           Getting 'hidden'
      /** As of PHP 5.1.0 */
      public function __isset($name) {
            echo quot;Is '$name' set?nquot;;
            return isset($this->data[$name]);                                                                                       Notice: Undefined property via
      }
                                                                                                                                    __get(): hidden in <file> on line
      /** As of PHP 5.1.0 */
      public function __unset($name) {
                                                                                                                                    70 in <file> on line 29
            echo quot;Unsetting '$name'nquot;;
            unset($this->data[$name]);
      }                                                                                                                             Calling object method 'runTest' in
      /** Not a magic method, just here for example. */                                                                             object context
      public function getHidden() {
            return $this->hidden;
      }
 Interfacesand Classes
 Encapsulate – don’t pollute the global
  namespace
<?php
class MyClass
                                                    The value must be a constant expression, not
{                                                   (for example) a variable, a class member, result
      const constant = 'constant value';            of a mathematical operation or a function call

     function showConstant() {                      You can’t use define to do class constants
         echo self::constant . quot;nquot;;
     }
}
echo MyClass::constant . quot;nquot;;
$classname = quot;MyClassquot;;
echo $classname::constant . quot;nquot;; // As of PHP 5.
3.0
$class = new MyClass();
$class->showConstant();
echo $class::constant.quot;nquot;; // As of PHP 5.3.0
 Autoload magically includes classes/interfaces
  when you use them
 spl_autoload_register let’s you “stack”
  autoloaders
<?php
function __autoload($class_name) {
      require_once $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
<?php
function my_library_loader($classname) {
      static $list;
      if (is_null($list)) {
          $list = array('myclass', 'yourclass', 'ourclass');
      }
      if (in_array($classname, $list)) {
          include $classname . '.class.php';
      }
}
spl_autoload_register('my_library_loader');
spl_autoload_register('__autoload'); // have to explicitly register any __autoload
Enough with the objects already!
 http://php.net/streams
 Streams   became useable in 4.3 and are
  extremely powerful, but still seldom used
 Cool new features came along with 5.0+ -
  mainly filters and socket support for streams
 Two ways to use streams and filters – use the
  built in ones or create your own
<HTML>
                                                                    <HEAD>
                                                                      <TITLE>Example Web Page</TITLE>
                                                                    </HEAD>
                                                                    <body>
                                                                    <p>You have reached this web page by typing
                                                                    &quot;example.com&quot;,
                                                                    &quot;example.net&quot;,
                                                                      or &quot;example.org&quot; into your web

 Available streams will vary –                                      browser.</p>
                                                                    <p>These domain names are reserved for use in
   http, https, tcp, tcps, php                                      documentation and are not available
                                                                      for registration. See <a href=quot;http://www.rfc-
   are usually always present                                       editor.org/rfc/rfc2606.txtquot;>RFC
                                                                      2606</a>, Section 3.</p>
                                                                    </BODY>
                                                                    </HTML>
<?php                                                               Array
$options = array(                                                   (
    'http' => array(                                                    [wrapper_data] => Array
        'method' => 'POST',                                                 (
        'header'=>                                                              [0] => HTTP/1.1 200 OK
           quot;Accept-language: enrnquot;.                                           [1] => Date: Sun, 07 Sep 2008 15:34:29
           quot;Content-type: application/x-www-form-urlencodedrnquot;,   GMT
        'content' => http_build_query(array('foo'=>'bar'))                      [2] => Server: Apache/2.2.3 (CentOS)
));                                                                             [3] => Last-Modified: Tue, 15 Nov 2005
                                                                    13:24:10 GMT
$context = stream_context_create($options);                                     [4] => ETag: quot;280100-1b6-80bfd280quot;
                                                                                [5] => Accept-Ranges: bytes
$fp = fopen('http://www.example.com/', 'r', false, $context);                   [6] => Content-Length: 438
                                                                                [7] => Connection: close
$response = stream_get_contents($fp);                                           [8] => Content-Type: text/html;
                                                                    charset=UTF-8
$meta = stream_get_meta_data($fp);                                          )
                                                                        [wrapper_type] => http
fclose($fp);                                                            [stream_type] => tcp_socket
                                                                        [mode] => r+
print_r($response);                                                     [unread_bytes] => 0
print_r($meta);                                                         [seekable] =>
                                                                        [uri] => http://www.example.com/
?>
                                                                        [timed_out] =>
                                                                        [blocked] => 1
                                                                        [eof] => 1
                                                                    )
Available filters will vary – use stream_get_filters() for a list

                                                      GUVF VF N GRFG
   <?php                                              GUVF VF N GRFG.
   $fp = fopen('php://output', 'w');
   stream_filter_append($fp, 'string.rot13');
   stream_filter_prepend($fp, 'string.toupper');
   fwrite($fp, quot;This is a test.nquot;);

   file_put_contents('php://filter/write=string.rot
   13|string.toupper/resource=php://output', quot;T
   his is a test.nquot;);
   ?>


   Some thoughts – this can be very powerful but very difficult to debug
   Good places to use streams and filters include templating and text
   You can even do transparent encryption and compression
   Most of the fancy filter functionality (including custom filters)
       is new for PHP5
   convert_uudecode() - decode a uuencoded string
   convert_uuencode() - uuencode a string
   file_put_contents() - Write a string to a file
   get_declared_interfaces() - Returns an array of all declared interfaces
   get_headers() - Fetches all the headers sent by the server in response to a HTTP request
   headers_list() - Returns a list of response headers sent (or ready to send)
   http_build_query() - Generate URL-encoded query string
   image_type_to_extension() - Get file extension for image
   imagefilter() - Applies a filter to an image using custom arguments
   php_strip_whitespace() - Return source with stripped comments and whitespace
   proc_nice() - Change the priority of the current process
   setrawcookie() - Send a cookie without URL-encoding the value
   scandir() - List files and directories inside the specified path
   str_split() - Convert a string to an array
   strpbrk() - Search a string for any of a set of characters
   substr_compare() - Binary safe optionally case insensitive comparison of two strings from an
    offset, up to length characters
   error_get_last() - Get the last occurred error as associative array. Returns NULL if there hasn't
    been an error yet
   memory_get_peak_usage() - Returns the peak allocated by PHP memory
   sys_get_temp_dir() - Returns directory path used for temporary files
   spl_object_hash() - Return hash id for given object
Look at all the TOYS!
 http://php.net/spl
 http://www.php.net/~helly/php/ext/spl/
 Standard  PHP Library – common stuff you’d
  use all the time (in C!)
 Some neat hooks for additional functionality
  you can’t do in PHP userland
     Iterators, ArrayAccess, spl_autoload stuff
 After5.3 you can’t turn this off (hurrah)
 So much to find, I can’t fit it all in this talk
     Highlights: ArrayObject, RecursiveFileIterator,
Existing Classes - Filtering File Iterator
<?php
class RecursiveFileFilterIterator extends FilterIterator
{
      /**
        * acceptable extensions - array of strings
        */
      protected $ext = array();
     /**
       * Takes a path and shoves it into our earlier class.
       * Turns $ext into an array.
       * @param $path directory to iterate
       * @param $ext comma delimited list of acceptable extensions
       */
     public function __construct($path, $ext = 'php')
     {
           $this->ext = explode(',', $ext);
           parent::__construct(new RecursiveDirectoryIterator($path));
     }
     /**
       * Checks extension names for files only.
       */
     public function accept()
     {
           $item = $this->getInnerIterator();
           // If it's not a file, accept it.
           if (!$item->isFile()) {
                    return TRUE;
           }
           // If it is a file, grab the file extension and see if it's in the array.
           return in_array(pathinfo($item->getFilename(), PATHINFO_EXTENSION), $this->ext);
     }
}
// Same usage as above, but you can indicate allowed extensions with the optional second argument.
foreach (new RecursiveFileFilterIterator('/path/to/something', 'php,txt') as $item) {
      // This is an SPLFileInfo object.
      echo $item . PHP_EOL;
}
Interfaces - This is your friend
<?php

class User implements ArrayAccess {
      private $db; // class to look up users in a db

        function offsetExists($name) {
           return $this->db->userExists($name);
     }
      function offsetGet($name) {
         return $this->db->getUserId($name);
     }
      function offsetSet($name, $id) {
         $this->db->setUserId($name, $id);
     }
      function offsetUnset($name) {
         $this->db->removeUser($name);
     }
}

$userMap = new User();

echo $userMap[quot;Bobquot;];
Foreach fun
                                              rewinding
<?php
class MyIterator implements Iterator
                                              current: 1
{                                             valid: 1
      private $var = array();                 current: 1
     public function __construct($array)      key: 0
     {
         if (is_array($array)) {              0: 1
             $this->var = $array;             next: 2
         }
     }                                        current: 2
                                              valid: 1
     public function rewind() {
         echo quot;rewindingnquot;;                  current: 2
     }
         reset($this->var);                   key: 1
                                              1: 2
     public function current() {
         $var = current($this->var);          next: 3
         echo quot;current: $varnquot;;              current: 3
         return $var;
     }                                        valid: 1
                                              current: 3
     public function key() {
         $var = key($this->var);              key: 2
         echo quot;key: $varnquot;;
         return $var;
                                              2: 3
     }                                        next:
     public function next() {
                                              current:
         $var = next($this->var);             valid:
         echo quot;next: $varnquot;;
         return $var;
     }
     public function valid() {
         $var = $this->current() !== false;
         echo quot;valid: {$var}nquot;;
         return $var;
     }
}
$values = array(1,2,3);
$it = new MyIterator($values);
foreach ($it as $a => $b) {
    print quot;$a: $bnquot;;
}
 http://php.net/pdo
 Database  Access Layer
 Common way to do db connections, different
  drivers for different dbs
 Doesn’t do SQL abstraction!
Basic Usage
<?php
/* Connect to an ODBC database using driver invocation */
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';

try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

/* Execute a prepared statement by passing an array of values */
$sql = 'SELECT name, colour, calories
      FROM fruit
      WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();
$sth->execute(array('calories' => 175, 'colour' => 'yellow'));
$yellow = $sth->fetchAll();
Advanced Usage
<?php
    $stmt = $db->prepare(quot;select foo from barquot;);
    $stmt->execute();
    $stmt->setFetchMode(PDO_FETCH_LAZY);
    foreach ($stmt as $row) {
         echo $row->foo;
    }
?>
and the less verbose version:
<?php
     foreach ($db->query(quot;select foo from barquot;, PDO_FETCH_LAZY) as $row) {
          echo $row->foo;
     }
?>
Blobs:

<?php
    $db = new PDO(quot;oci:quot;, quot;scottquot;, quot;tigerquot;);
    $db->beginTransaction(); // Essential!
    $stmt = $db->prepare(
          quot;INSERT INTO blobtest (id, contenttype, blob) quot;.
          quot;VALUES (:id, :type, EMPTY_BLOB()) quot;.
          quot;RETURNING blob INTO :blobquot;);
    $stmt->bindParam(':id', $id);
    $stmt->bindParam(':type', $type);
    $stmt->bindParam(':blob', $blob, PDO::PARAM_LOB);
    $type = 'image/gif';
    $id = 1; // generate your own unique id here
    $blob = fopen('/path/to/a/graphic.gif', 'rb');
    $stmt->execute();
    $stmt->commit();
         $stmt = $db->prepare('select blob from blobtest where id = ?');
         $stmt->execute(array($id));
         $row = $stmt->fetch();
         var_dump($row);
         var_dump(stream_get_contents($row[0]));
 http://php.net/mysqli
i means improved (I didn’t name it)
 Transactions, prepared statements, the stuff
  actually works
 Procedural API or OO API (take your pick)
Mysql Improved
<?php
$mysqli = new mysqli(quot;localhostquot;, quot;my_userquot;, quot;my_passwordquot;, quot;worldquot;);   $link = mysqli_connect(quot;localhostquot;, quot;my_userquot;, quot;my_passwordquot;, quot;worldquot;);

/* check connection */                                                  /* check connection */
if (mysqli_connect_errno()) {                                           if (mysqli_connect_errno()) {
      printf(quot;Connect failed: %snquot;, mysqli_connect_error());                 printf(quot;Connect failed: %snquot;, mysqli_connect_error());
      exit();                                                                 exit();
}                                                                       }

$city = quot;Amersfoortquot;;                                                   $city = quot;Amersfoortquot;;

/* create a prepared statement */                                       /* create a prepared statement */
if ($stmt = $mysqli-                                                    if ($stmt = mysqli_prepare($link, quot;SELECT District FROM City WHERE Nam
>prepare(quot;SELECT District FROM City WHERE Name=?quot;)) {                   e=?quot;)) {

     /* bind parameters for markers */                                       /* bind parameters for markers */
     $stmt->bind_param(quot;squot;, $city);                                          mysqli_stmt_bind_param($stmt, quot;squot;, $city);

     /* execute query */                                                     /* execute query */
     $stmt->execute();                                                       mysqli_stmt_execute($stmt);

     /* bind result variables */                                             /* bind result variables */
     $stmt->bind_result($district);                                          mysqli_stmt_bind_result($stmt, $district);

     /* fetch value */                                                       /* fetch value */
     $stmt->fetch();                                                         mysqli_stmt_fetch($stmt);

     printf(quot;%s is in district %snquot;, $city, $district);                     printf(quot;%s is in district %snquot;, $city, $district);

     /* close statement */                                                   /* close statement */
     $stmt->close();                                                         mysqli_stmt_close($stmt);
}                                                                       }

/* close connection */                                                  /* close connection */
$mysqli->close();                                                       mysqli_close($link);
 http://php.net/json
 JavaScriptObject Notation
 Douglas Crocker http://json.org/
 http://gggeek.altervista.org/sw/article_200
  61113.html interesting benchmarks

  <?php

  $arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);

  echo json_encode($arr);

  var_dump(json_decode($arr));
  var_dump(json_decode($arr, true));
 http://php.net/filter
 Clean                      things up                                     array(6) {
                                                                             [quot;product_idquot;]=>
                                                                             array(1) {
                                                                               [0]=>
                                                                               string(17) quot;libgd%3Cscript%3Equot;
<?php                                                                        }
/* data actually came from POST                                              [quot;componentquot;]=>
$_POST = array(
     'product_id'
     'component'
                          => 'libgd<script>',
                          => '10',
                                                                             array(1) {
     'versions'           => '2.0.33',                                         [0]=>
     'testscalar'         => array('2', '23', '10', '12'),
     'testarray'          => '2',                                              int(10)
);
*/                                                                           }
$args = array(
                                                                             [quot;versionsquot;]=>
     'product_id' => FILTER_SANITIZE_ENCODED,                                array(1) {
     'component' => array('filter' => FILTER_VALIDATE_INT,
                                     'flags'    => FILTER_REQUIRE_ARRA         [0]=>
Y,
                                     'options' => array('min_range' => 1       string(6) quot;2.0.33quot;
, 'max_range' => 10)
                                   ),                                        }
     'versions'   => FILTER_SANITIZE_ENCODED,                                [quot;doesnotexistquot;]=>
     'doesnotexist' => FILTER_VALIDATE_INT,
     'testscalar' => array(                                                  NULL
                                     'filter' => FILTER_VALIDATE_INT,
                                     'flags' => FILTER_REQUIRE_SCALAR,       [quot;testscalarquot;]=>
                                   ),
     'testarray' => array(                                                   bool(false)
                                     'filter' => FILTER_VALIDATE_INT,        [quot;testarrayquot;]=>
                                     'flags' => FILTER_REQUIRE_ARRAY,
                                   )                                         array(1) {
);                                                                             [0]=>
$myinputs = filter_input_array(INPUT_POST, $args);                             int(2)
var_dump($myinputs);                                                         }
echo quot;nquot;;                                                                 }
 http://php.net/simplexml
 XML               for dummies                                  <?php
                                                                 $xmlstr = <<<XML
                                                                 <?xml version='1.0' standalone='yes'?>
<?php                                                            <movies>
include 'example.php';                                            <movie>
                                                                    <title>PHP: Behind the Parser</title>
$xml = new SimpleXMLElement($xmlstr);                               <characters>
                                                                     <character>
echo $xml->movie[0]->plot; // quot;So this language. It's like...quot;        <name>Ms. Coder</name>
$xml = new SimpleXMLElement($xmlstr);                                 <actor>Onlivia Actora</actor>
                                                                     </character>
echo $xml->movie->{'great-lines'}-                                   <character>
>line; // quot;PHP solves all my web problemsquot;                            <name>Mr. Coder</name>
                                                                      <actor>El Act&#211;r</actor>
$xml = new SimpleXMLElement($xmlstr);                                </character>
                                                                    </characters>
/* For each <movie> node, we echo a separate <plot>. */             <plot>
foreach ($xml->movie as $movie) {
    echo $movie->plot, '<br />';                                     So, this language. It's like, a programmin
}                                                                g language. Or is it a
                                                                     scripting language? All is revealed in thi
$xml = new SimpleXMLElement($xmlstr);                            s thrilling horror spoof
                                                                     of a documentary.
/* Access the <rating> nodes of the first movie.                    </plot>
  * Output the rating scale, too. */                                <great-lines>
foreach ($xml->movie[0]->rating as $rating) {                        <line>PHP solves all my web problems</line
      switch((string) $rating['type']) { // Get attributes
as element indices                                               >
      case 'thumbs':                                                </great-lines>
             echo $rating, ' thumbs up';                            <rating type=quot;thumbsquot;>7</rating>
             break;                                                 <rating type=quot;starsquot;>5</rating>
      case 'stars':                                               </movie>
             echo $rating, ' stars';                             </movies>
             break;                                              XML;
      }                                                          ?>
}
 Soap  – web services
 Sqlite – file based light DB
 Reflection – view information about code
 DateTime – OO and timezone support for
  date manipulation
 Dom, xmlreader, and xmlwriter – better ways
  to manipulate xml
Oooh, shiny buzzword. What we really mean is do more in C
              And use Design Patterns – but you knew that…
 What functionality do     What functionality do
  you need?                  you have?
 What technologies         What technologies do
  will you use?              you use?
 What built in features    What can be replaced
  can you leverage?          with built in features?




      New and Shiny              Old and Busted
 Use interfaces,             Use “shortcut”
  abstract classes, and        functions to replace
  other OO features to         common actions –
  lock in patterns like        scandir to get a list of
                               files, file_put_contents
  singleton and restrict
  visibility                  Use new extensions to
                               replace userland
 Use SPL features to
                               implementations – xml
  add intelligent              parsers, json encoding
  iteration or provide         and decoding
  common functionality

       In OO Code                 In Procedural Code
 Avoid   trying to make PHP act like other
    languages
       Reflection is nice, using it does not make a good
        JAVA style MVC controller
 Use     PHP5 strengths and avoid weaknesses
       json is a good choice for data transfer, xml is
        slower but standard, xaml would require either a
        PECL extension or a PHP userland parser
   Don’t reinvent the wheel
     Spl has a recursivedirectoryiterator – use it
     http_build_query is quick and safe
     use the filter extension for validation or
      sanitizing
 Use  of SAX xml parsers – xmlreader is your
  friend
 Json encoders/decoders
 Crufty ways of doing singletons, abstract
  classes, private/protected by naming
  conventions, CLASSNAME_CONSTANTNAME
  constants
 Add features (like encryption) without
  messing up old code with streams and filters
 Throw out crazy custom array code and use
  the built in stuff – array_combine rocks
Remember – C is faster than PHP



 You don’t have to use all the PHP5
  features, but don’t use hacks to fake
  them either
 You don’t have to use OOP, but don’t
  complete shun it on principle.
     Writing an extensive function to filter
      the results of a scandir array is silly
      when you can use
      RecursiveDirectoryIterator
 What version of PHP should be on your
 server?
    Why?
 What’s    the one thing to remember from this
 talk?
    What does that mean when thinking about
     writing code?
 What’s    my favorite color?
    And what color are these slides?
 Name    some magic methods in PHP
    What should you never use to prefix your own
     methods?
 How   do you copy a PHP5 object
    What does “deep copy” mean and why is it
     problematic in PHP5?
 Howcan you have more than one __autoload
 methods?
    What’s the one thing to remember when using an
     spl autoload stack?
 What   is a stream?
    Name two common PHP streams
 What   is a filter
    How do you use filters with file_get_contents
 What   is your favorite new function in PHP5?
    Why?
 Why   is preg_last_error useful?
    How much do you like regex ;)
 Name      one new header function
    Halfway there…
 What   does mysqli provide that mysql does
 not?
    What does the I stand for.
 What  extension can you use to validate and
  sanitize data?
 What extension is very useful with
  xmlhttprequest?
 How can you control what properties of an
  object are shown with foreach?
    What interface do you have to use to do this?
 Name    one PHP4 hack no longer needed in
 PHP5
    Why isn’t it needed? How would you replace it?
 Name one technology you’d use in a new
 project because of improved PHP5 support
    Would you use a different one if PHP5 had better
     support?
 What is the difference between how you
 approach designing a new project, and
 redoing parts of a legacy project?
    How are they the same?

More Related Content

What's hot

The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09Bastian Feder
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of LithiumNate Abele
 
Introduction to Clean Code
Introduction to Clean CodeIntroduction to Clean Code
Introduction to Clean CodeJulio Martinez
 
Building a Pluggable Plugin
Building a Pluggable PluginBuilding a Pluggable Plugin
Building a Pluggable PluginBrandon Dove
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionNate Abele
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Fabien Potencier
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Fabien Potencier
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010Fabien Potencier
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Fabien Potencier
 

What's hot (20)

The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09
 
Ch8(oop)
Ch8(oop)Ch8(oop)
Ch8(oop)
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
Introduction to Clean Code
Introduction to Clean CodeIntroduction to Clean Code
Introduction to Clean Code
 
Building a Pluggable Plugin
Building a Pluggable PluginBuilding a Pluggable Plugin
Building a Pluggable Plugin
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
PHP 8.1: Enums
PHP 8.1: EnumsPHP 8.1: Enums
PHP 8.1: Enums
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
 
SOLID PRINCIPLES
SOLID PRINCIPLESSOLID PRINCIPLES
SOLID PRINCIPLES
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 
Php Enums
Php EnumsPhp Enums
Php Enums
 

Viewers also liked

Modernizing i5 Applications
Modernizing i5 ApplicationsModernizing i5 Applications
Modernizing i5 ApplicationsZendCon
 
State And Ajax Zend Con
State And Ajax   Zend ConState And Ajax   Zend Con
State And Ajax Zend ConZendCon
 
Scsu91908004
Scsu91908004Scsu91908004
Scsu91908004SAPHOTO
 
App Inside An App - Zend UnConn 2008
App Inside An App - Zend UnConn 2008App Inside An App - Zend UnConn 2008
App Inside An App - Zend UnConn 2008guest385319
 
Zend Con Harris Data Case Study
Zend Con   Harris Data Case StudyZend Con   Harris Data Case Study
Zend Con Harris Data Case StudyZendCon
 
The Importance of Design in Enterprise Software
The Importance of Design in Enterprise SoftwareThe Importance of Design in Enterprise Software
The Importance of Design in Enterprise SoftwareD. Keith Robinson
 

Viewers also liked (7)

Modernizing i5 Applications
Modernizing i5 ApplicationsModernizing i5 Applications
Modernizing i5 Applications
 
State And Ajax Zend Con
State And Ajax   Zend ConState And Ajax   Zend Con
State And Ajax Zend Con
 
Atlante Globale delle Cure Palliative
Atlante Globale delle Cure PalliativeAtlante Globale delle Cure Palliative
Atlante Globale delle Cure Palliative
 
Scsu91908004
Scsu91908004Scsu91908004
Scsu91908004
 
App Inside An App - Zend UnConn 2008
App Inside An App - Zend UnConn 2008App Inside An App - Zend UnConn 2008
App Inside An App - Zend UnConn 2008
 
Zend Con Harris Data Case Study
Zend Con   Harris Data Case StudyZend Con   Harris Data Case Study
Zend Con Harris Data Case Study
 
The Importance of Design in Enterprise Software
The Importance of Design in Enterprise SoftwareThe Importance of Design in Enterprise Software
The Importance of Design in Enterprise Software
 

Similar to Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"

Runs On Php5 is not Written for PHP5
Runs On Php5 is not Written for PHP5Runs On Php5 is not Written for PHP5
Runs On Php5 is not Written for PHP5Elizabeth Smith
 
Object Oriented Programming in PHP
Object Oriented Programming  in PHPObject Oriented Programming  in PHP
Object Oriented Programming in PHPwahidullah mudaser
 
Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxDavidLazar17
 
PHP Traits
PHP TraitsPHP Traits
PHP Traitsmattbuzz
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPAlena Holligan
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPWildan Maulana
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Alena Holligan
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Fabien Potencier
 
Demystifying Object-Oriented Programming - Midwest PHP
Demystifying Object-Oriented Programming - Midwest PHPDemystifying Object-Oriented Programming - Midwest PHP
Demystifying Object-Oriented Programming - Midwest PHPAlena Holligan
 
Php object orientation and classes
Php object orientation and classesPhp object orientation and classes
Php object orientation and classesKumar
 
What is the difference between a good and a bad repository? (Forum PHP 2018)
What is the difference between a good and a bad repository? (Forum PHP 2018)What is the difference between a good and a bad repository? (Forum PHP 2018)
What is the difference between a good and a bad repository? (Forum PHP 2018)Arnaud Langlade
 

Similar to Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5" (20)

Runs On Php5 is not Written for PHP5
Runs On Php5 is not Written for PHP5Runs On Php5 is not Written for PHP5
Runs On Php5 is not Written for PHP5
 
Object Oriented Programming in PHP
Object Oriented Programming  in PHPObject Oriented Programming  in PHP
Object Oriented Programming in PHP
 
Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptx
 
PHP Traits
PHP TraitsPHP Traits
PHP Traits
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHP
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
PHP pod mikroskopom
PHP pod mikroskopomPHP pod mikroskopom
PHP pod mikroskopom
 
Oops in php
Oops in phpOops in php
Oops in php
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
 
Demystifying Object-Oriented Programming - Midwest PHP
Demystifying Object-Oriented Programming - Midwest PHPDemystifying Object-Oriented Programming - Midwest PHP
Demystifying Object-Oriented Programming - Midwest PHP
 
Php object orientation and classes
Php object orientation and classesPhp object orientation and classes
Php object orientation and classes
 
OOP in PHP
OOP in PHPOOP in PHP
OOP in PHP
 
PHP OOP
PHP OOPPHP OOP
PHP OOP
 
Web 9 | OOP in PHP
Web 9 | OOP in PHPWeb 9 | OOP in PHP
Web 9 | OOP in PHP
 
What is the difference between a good and a bad repository? (Forum PHP 2018)
What is the difference between a good and a bad repository? (Forum PHP 2018)What is the difference between a good and a bad repository? (Forum PHP 2018)
What is the difference between a good and a bad repository? (Forum PHP 2018)
 

More from ZendCon

Framework Shootout
Framework ShootoutFramework Shootout
Framework ShootoutZendCon
 
Zend_Tool: Practical use and Extending
Zend_Tool: Practical use and ExtendingZend_Tool: Practical use and Extending
Zend_Tool: Practical use and ExtendingZendCon
 
PHP on IBM i Tutorial
PHP on IBM i TutorialPHP on IBM i Tutorial
PHP on IBM i TutorialZendCon
 
PHP on Windows - What's New
PHP on Windows - What's NewPHP on Windows - What's New
PHP on Windows - What's NewZendCon
 
PHP and Platform Independance in the Cloud
PHP and Platform Independance in the CloudPHP and Platform Independance in the Cloud
PHP and Platform Independance in the CloudZendCon
 
I18n with PHP 5.3
I18n with PHP 5.3I18n with PHP 5.3
I18n with PHP 5.3ZendCon
 
Cloud Computing: The Hard Problems Never Go Away
Cloud Computing: The Hard Problems Never Go AwayCloud Computing: The Hard Problems Never Go Away
Cloud Computing: The Hard Problems Never Go AwayZendCon
 
Planning for Synchronization with Browser-Local Databases
Planning for Synchronization with Browser-Local DatabasesPlanning for Synchronization with Browser-Local Databases
Planning for Synchronization with Browser-Local DatabasesZendCon
 
Magento - a Zend Framework Application
Magento - a Zend Framework ApplicationMagento - a Zend Framework Application
Magento - a Zend Framework ApplicationZendCon
 
Enterprise-Class PHP Security
Enterprise-Class PHP SecurityEnterprise-Class PHP Security
Enterprise-Class PHP SecurityZendCon
 
PHP and IBM i - Database Alternatives
PHP and IBM i - Database AlternativesPHP and IBM i - Database Alternatives
PHP and IBM i - Database AlternativesZendCon
 
Zend Core on IBM i - Security Considerations
Zend Core on IBM i - Security ConsiderationsZend Core on IBM i - Security Considerations
Zend Core on IBM i - Security ConsiderationsZendCon
 
Application Diagnosis with Zend Server Tracing
Application Diagnosis with Zend Server TracingApplication Diagnosis with Zend Server Tracing
Application Diagnosis with Zend Server TracingZendCon
 
Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP A...
Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP A...Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP A...
Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP A...ZendCon
 
Solving the C20K problem: Raising the bar in PHP Performance and Scalability
Solving the C20K problem: Raising the bar in PHP Performance and ScalabilitySolving the C20K problem: Raising the bar in PHP Performance and Scalability
Solving the C20K problem: Raising the bar in PHP Performance and ScalabilityZendCon
 
Joe Staner Zend Con 2008
Joe Staner Zend Con 2008Joe Staner Zend Con 2008
Joe Staner Zend Con 2008ZendCon
 
Tiery Eyed
Tiery EyedTiery Eyed
Tiery EyedZendCon
 
Make your PHP Application Software-as-a-Service (SaaS) Ready with the Paralle...
Make your PHP Application Software-as-a-Service (SaaS) Ready with the Paralle...Make your PHP Application Software-as-a-Service (SaaS) Ready with the Paralle...
Make your PHP Application Software-as-a-Service (SaaS) Ready with the Paralle...ZendCon
 
DB2 Storage Engine for MySQL and Open Source Applications Session
DB2 Storage Engine for MySQL and Open Source Applications SessionDB2 Storage Engine for MySQL and Open Source Applications Session
DB2 Storage Engine for MySQL and Open Source Applications SessionZendCon
 
Digital Identity
Digital IdentityDigital Identity
Digital IdentityZendCon
 

More from ZendCon (20)

Framework Shootout
Framework ShootoutFramework Shootout
Framework Shootout
 
Zend_Tool: Practical use and Extending
Zend_Tool: Practical use and ExtendingZend_Tool: Practical use and Extending
Zend_Tool: Practical use and Extending
 
PHP on IBM i Tutorial
PHP on IBM i TutorialPHP on IBM i Tutorial
PHP on IBM i Tutorial
 
PHP on Windows - What's New
PHP on Windows - What's NewPHP on Windows - What's New
PHP on Windows - What's New
 
PHP and Platform Independance in the Cloud
PHP and Platform Independance in the CloudPHP and Platform Independance in the Cloud
PHP and Platform Independance in the Cloud
 
I18n with PHP 5.3
I18n with PHP 5.3I18n with PHP 5.3
I18n with PHP 5.3
 
Cloud Computing: The Hard Problems Never Go Away
Cloud Computing: The Hard Problems Never Go AwayCloud Computing: The Hard Problems Never Go Away
Cloud Computing: The Hard Problems Never Go Away
 
Planning for Synchronization with Browser-Local Databases
Planning for Synchronization with Browser-Local DatabasesPlanning for Synchronization with Browser-Local Databases
Planning for Synchronization with Browser-Local Databases
 
Magento - a Zend Framework Application
Magento - a Zend Framework ApplicationMagento - a Zend Framework Application
Magento - a Zend Framework Application
 
Enterprise-Class PHP Security
Enterprise-Class PHP SecurityEnterprise-Class PHP Security
Enterprise-Class PHP Security
 
PHP and IBM i - Database Alternatives
PHP and IBM i - Database AlternativesPHP and IBM i - Database Alternatives
PHP and IBM i - Database Alternatives
 
Zend Core on IBM i - Security Considerations
Zend Core on IBM i - Security ConsiderationsZend Core on IBM i - Security Considerations
Zend Core on IBM i - Security Considerations
 
Application Diagnosis with Zend Server Tracing
Application Diagnosis with Zend Server TracingApplication Diagnosis with Zend Server Tracing
Application Diagnosis with Zend Server Tracing
 
Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP A...
Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP A...Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP A...
Insights from the Experts: How PHP Leaders Are Transforming High-Impact PHP A...
 
Solving the C20K problem: Raising the bar in PHP Performance and Scalability
Solving the C20K problem: Raising the bar in PHP Performance and ScalabilitySolving the C20K problem: Raising the bar in PHP Performance and Scalability
Solving the C20K problem: Raising the bar in PHP Performance and Scalability
 
Joe Staner Zend Con 2008
Joe Staner Zend Con 2008Joe Staner Zend Con 2008
Joe Staner Zend Con 2008
 
Tiery Eyed
Tiery EyedTiery Eyed
Tiery Eyed
 
Make your PHP Application Software-as-a-Service (SaaS) Ready with the Paralle...
Make your PHP Application Software-as-a-Service (SaaS) Ready with the Paralle...Make your PHP Application Software-as-a-Service (SaaS) Ready with the Paralle...
Make your PHP Application Software-as-a-Service (SaaS) Ready with the Paralle...
 
DB2 Storage Engine for MySQL and Open Source Applications Session
DB2 Storage Engine for MySQL and Open Source Applications SessionDB2 Storage Engine for MySQL and Open Source Applications Session
DB2 Storage Engine for MySQL and Open Source Applications Session
 
Digital Identity
Digital IdentityDigital Identity
Digital Identity
 

Recently uploaded

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 

Recently uploaded (20)

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 

Architecting for PHP5 - Why "Runs on PHP5" is not "Written for PHP5"

  • 1. Also known as “Elizabeth Ranting about a Pet Peeve” Zendcon 2008 – Santa Clara, CA
  • 2.  Elizabeth Marie Smith aka auroraeosrose  Pink is good  I hate computers  I love programming  Windows will not kill you  Work at OmniTI (http://omniti.com)  Contributor on various open source projects (including PHP, PECL and PHP-GTK)
  • 3.  Why are you here?  What are you hoping to learn?  How to improve your code for use on PHP5?  Improve meaning faster, more stable, easier to maintain  What do I want to teach?  What is available in PHP5 to help with the “improve”  What do you already know?  This is about what you CAN do not what you CAN’T do
  • 4. If you remember only one thing from this talk, remember this
  • 5. PHP 5.0.x is beta quality – don’t touch it with a ten foot pole PHP 5.1.x is better, but lacking stability and functionality
  • 6. If you don’t know it exists, how can you use it?
  • 7. We’ll get back to you later
  • 8.  Every constructor is named __construct, use parent::__construct to chain  Careful with __destruct, headers are sent and you can’t throw exceptions <?php Kill da wabbit class foo { bar Object() protected $animal; public function __construct($animal) { Fatal error: Call to private $this->animal = $animal; } bar::__construct() from invalid context in test.php on line 34 public function __destruct() { echo 'Kill da ' . $this->animal . PHP_EOL; } } class bar { static $singleton; private function __construct() {} static public function getInstance() { if (!self::$singleton) { self::$singleton = new self; } return self::$singleton; } } $class = new foo('wabbit'); // $class = null; also works unset($class); $foo = bar::getInstance(); print_r($foo); $foo = new bar;
  • 9.  Keep people from messing with your stuff <?php class Bar /** { * Define MyClass public function test() { */ $this->testPrivate(); <?php class MyClass $this->testPublic(); /** { } * Define MyClass */ // Declare a public constructor class MyClass public function __construct() { } public function testPublic() { { echo quot;Bar::testPublicnquot;; // Declare a public method } public $public = 'Public'; public function MyPublic() { } protected $protected = 'Protected'; private function testPrivate() { private $private = 'Private'; // Declare a protected method echo quot;Bar::testPrivatenquot;; protected function MyProtected() { } } function printHello() } { echo $this->public; // Declare a private method echo $this->protected; private function MyPrivate() { } class Foo extends Bar echo $this->private; { } // This is public public function testPublic() { } function Foo() echo quot;Foo::testPublicnquot;; { } $obj = new MyClass(); $this->MyPublic(); echo $obj->public; // Works $this->MyProtected(); private function testPrivate() { echo $obj->protected; // Fatal Error $this->MyPrivate(); echo quot;Foo::testPrivatenquot;; } } echo $obj->private; // Fatal Error } } $obj->printHello(); // Shows Public, Protected and Private $myclass = new MyClass; $myFoo = new foo(); /** $myclass->MyPublic(); // Works $myFoo->test(); // Bar::testPrivate * Define MyClass2 $myclass->MyProtected(); // Fatal Error // Foo::testPublic */ $myclass->MyPrivate(); // Fatal Error class MyClass2 extends MyClass $myclass->Foo(); // Public, Protected and Private work { // We can redeclare the public and protected method, but not private /** protected $protected = 'Protected2'; * Define MyClass2 */ function printHello() class MyClass2 extends MyClass { echo $this->public; { echo $this->protected; // This is public echo $this->private; function Foo2() } { } $this->MyPublic(); $this->MyProtected(); $obj2 = new MyClass2(); $this->MyPrivate(); // Fatal Error echo $obj2->public; // Works } } echo $obj2->private; // Undefined echo $obj2->protected; // Fatal Error $myclass2 = new MyClass2; $obj2->printHello(); // Shows Public, Protected2, Undefined $myclass2->MyPublic(); // Works $myclass2- >Foo2(); // Public and Protected work, not Private
  • 10.  In PHP4 any assignment was a clone  In PHP5 objects are passed by reference, to copy it we have clone it <?php 7 class foo { 7 public $bar; 9 } 2 class funky { public $bar; public function __clone() { $this->bar++; } } $foo = new foo(); $foo->bar = 6; $bar = $foo; $bar->bar = 7; echo $foo->bar . PHP_EOL; echo $bar->bar . PHP_EOL; $bar = clone $foo; $bar->bar = 9; echo $bar->bar . PHP_EOL; $hello = new funky(); $hello->bar = 1; $bar = clone $hello; echo $bar->bar . PHP_EOL;
  • 11.  Make your class follow a contract <?php // Declare the interface 'iTemplate' interface iTemplate { public function setVariable($name, $var); public function getHtml($template); } // Implement the interface // This will work class Template implements iTemplate { private $vars = array(); public function setVariable($name, $var) { $this->vars[$name] = $var; } public function getHtml($template) { foreach($this->vars as $name => $value) { $template = str_replace('{' . $name . '}', $value, $template); } return $template; } } // This will not work // Fatal error: Class BadTemplate contains 1 abstract methods // and must therefore be declared abstract (iTemplate::getHtml) class BadTemplate implements iTemplate { private $vars = array(); public function setVariable($name, $var) { $this->vars[$name] = $var; } }
  • 12.  Common base functionality you can extend <?php abstract class AbstractClass ConcreteClass1 { FOO_ConcreteClass1 // Force Extending class to define this method abstract protected function getValue(); ConcreteClass2 abstract protected function prefixValue($prefix); FOO_ConcreteClass2 // Common method public function printOut() { print $this->getValue() . quot;nquot;; } } class ConcreteClass1 extends AbstractClass { protected function getValue() { return quot;ConcreteClass1quot;; } public function prefixValue($prefix) { return quot;{$prefix}ConcreteClass1quot;; } } class ConcreteClass2 extends AbstractClass { public function getValue() { return quot;ConcreteClass2quot;; } public function prefixValue($prefix) { return quot;{$prefix}ConcreteClass2quot;; } } $class1 = new ConcreteClass1; $class1->printOut(); echo $class1->prefixValue('FOO_') .quot;nquot;; $class2 = new ConcreteClass2; $class2->printOut(); echo $class2->prefixValue('FOO_') .quot;nquot;;
  • 13.  __sleep and __wakeup say what to serialize, and what to do on unserialize  __toString is obvious  __set_state works with var_export() <?php class MakeMagic { protected $string; protected $prefix; private $cache; O:9:quot;MakeMagicquot;:2:{s:9:quot; * public function __construct($data, $prefix) { stringquot;;s:5:quot;happyquot;;s:9:quot; * $this->string = $data; $this->prefix = $prefix; prefixquot;;s:2:quot;unquot;;} $this->cache(); } MakeMagic Object protected function cache() { ( } $this->cache = $this->prefix . $this->string; [string:protected] => happy [prefix:protected] => un public function __sleep() { return array('string', 'prefix'); [cache:MakeMagic:private] => unhappy } ) public function __wakeup() { unhappy $this->cache(); } MakeMagic Object public function __toString() { ( return $this->cache; } [string:protected] => happy public static function __set_state($properties) { [prefix:protected] => un return new self($properties['string'], $properties['prefix']); [cache:MakeMagic:private] => unhappy } } ) $class = new MakeMagic('happy', 'un'); $store = serialize($class); echo $store . PHP_EOL; $class = unserialize($store); print_r($class); echo $class . PHP_EOL; $string = var_export($class, true); eval('$test = ' . $string . ';'); print_r($test);
  • 14.  Manipulate properties “magically”  Change the way calls are made Setting 'a' to '1' Getting 'a' 1 <?php class MemberTest { public function __call($name, $arguments) { /** Location for overloaded data. */ // Note: value of $name is case sensitive. private $data = array(); echo quot;Calling object method '$name' quot; Is 'a' set? /** Overloading not used on declared members. */ } . implode(', ', $arguments). quot;nquot;; bool(true) public $declared = 1; } Unsetting 'a' /** Overloading only used on this when accessed outsid $obj = new MemberTest; Is 'a' set? e the class. */ private $hidden = 2; $obj->a = 1; bool(false) echo $obj->a . quot;nnquot;; public function __set($name, $value) { echo quot;Setting '$name' to '$value'nquot;; $this->data[$name] = $value; var_dump(isset($obj->a)); unset($obj->a); 1 } var_dump(isset($obj->a)); echo quot;nquot;; public function __get($name) { Let's experiment with the private echo quot;Getting '$name'nquot;; echo $obj->declared . quot;nnquot;; if (array_key_exists($name, $this->data)) { property named 'hidden': return $this->data[$name]; echo quot;Let's experiment with the private property named 'hidd Privates are visible inside the } en':nquot;; echo quot;Privates are visible inside the class, so __get() not use class, so __get() not used... $trace = debug_backtrace(); d...nquot;; trigger_error( echo $obj->getHidden() . quot;nquot;; 2 'Undefined property via __get(): ' . $name . echo quot;Privates not visible outside of class, so __get() is used. ' in ' . $trace[0]['file'] . ..nquot;; Privates not visible outside of ' on line ' . $trace[0]['line'], echo $obj->hidden . quot;nquot;; E_USER_NOTICE); $obj->runTest('in object context'); class, so __get() is used... } return null; Getting 'hidden' /** As of PHP 5.1.0 */ public function __isset($name) { echo quot;Is '$name' set?nquot;; return isset($this->data[$name]); Notice: Undefined property via } __get(): hidden in <file> on line /** As of PHP 5.1.0 */ public function __unset($name) { 70 in <file> on line 29 echo quot;Unsetting '$name'nquot;; unset($this->data[$name]); } Calling object method 'runTest' in /** Not a magic method, just here for example. */ object context public function getHidden() { return $this->hidden; }
  • 15.  Interfacesand Classes  Encapsulate – don’t pollute the global namespace <?php class MyClass The value must be a constant expression, not { (for example) a variable, a class member, result const constant = 'constant value'; of a mathematical operation or a function call function showConstant() { You can’t use define to do class constants echo self::constant . quot;nquot;; } } echo MyClass::constant . quot;nquot;; $classname = quot;MyClassquot;; echo $classname::constant . quot;nquot;; // As of PHP 5. 3.0 $class = new MyClass(); $class->showConstant(); echo $class::constant.quot;nquot;; // As of PHP 5.3.0
  • 16.  Autoload magically includes classes/interfaces when you use them  spl_autoload_register let’s you “stack” autoloaders <?php function __autoload($class_name) { require_once $class_name . '.php'; } $obj = new MyClass1(); $obj2 = new MyClass2(); ?> <?php function my_library_loader($classname) { static $list; if (is_null($list)) { $list = array('myclass', 'yourclass', 'ourclass'); } if (in_array($classname, $list)) { include $classname . '.class.php'; } } spl_autoload_register('my_library_loader'); spl_autoload_register('__autoload'); // have to explicitly register any __autoload
  • 17. Enough with the objects already!
  • 18.  http://php.net/streams  Streams became useable in 4.3 and are extremely powerful, but still seldom used  Cool new features came along with 5.0+ - mainly filters and socket support for streams  Two ways to use streams and filters – use the built in ones or create your own
  • 19. <HTML> <HEAD> <TITLE>Example Web Page</TITLE> </HEAD> <body> <p>You have reached this web page by typing &quot;example.com&quot;, &quot;example.net&quot;, or &quot;example.org&quot; into your web Available streams will vary – browser.</p> <p>These domain names are reserved for use in http, https, tcp, tcps, php documentation and are not available for registration. See <a href=quot;http://www.rfc- are usually always present editor.org/rfc/rfc2606.txtquot;>RFC 2606</a>, Section 3.</p> </BODY> </HTML> <?php Array $options = array( ( 'http' => array( [wrapper_data] => Array 'method' => 'POST', ( 'header'=> [0] => HTTP/1.1 200 OK quot;Accept-language: enrnquot;. [1] => Date: Sun, 07 Sep 2008 15:34:29 quot;Content-type: application/x-www-form-urlencodedrnquot;, GMT 'content' => http_build_query(array('foo'=>'bar')) [2] => Server: Apache/2.2.3 (CentOS) )); [3] => Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT $context = stream_context_create($options); [4] => ETag: quot;280100-1b6-80bfd280quot; [5] => Accept-Ranges: bytes $fp = fopen('http://www.example.com/', 'r', false, $context); [6] => Content-Length: 438 [7] => Connection: close $response = stream_get_contents($fp); [8] => Content-Type: text/html; charset=UTF-8 $meta = stream_get_meta_data($fp); ) [wrapper_type] => http fclose($fp); [stream_type] => tcp_socket [mode] => r+ print_r($response); [unread_bytes] => 0 print_r($meta); [seekable] => [uri] => http://www.example.com/ ?> [timed_out] => [blocked] => 1 [eof] => 1 )
  • 20. Available filters will vary – use stream_get_filters() for a list GUVF VF N GRFG <?php GUVF VF N GRFG. $fp = fopen('php://output', 'w'); stream_filter_append($fp, 'string.rot13'); stream_filter_prepend($fp, 'string.toupper'); fwrite($fp, quot;This is a test.nquot;); file_put_contents('php://filter/write=string.rot 13|string.toupper/resource=php://output', quot;T his is a test.nquot;); ?> Some thoughts – this can be very powerful but very difficult to debug Good places to use streams and filters include templating and text You can even do transparent encryption and compression Most of the fancy filter functionality (including custom filters) is new for PHP5
  • 21. convert_uudecode() - decode a uuencoded string  convert_uuencode() - uuencode a string  file_put_contents() - Write a string to a file  get_declared_interfaces() - Returns an array of all declared interfaces  get_headers() - Fetches all the headers sent by the server in response to a HTTP request  headers_list() - Returns a list of response headers sent (or ready to send)  http_build_query() - Generate URL-encoded query string  image_type_to_extension() - Get file extension for image  imagefilter() - Applies a filter to an image using custom arguments  php_strip_whitespace() - Return source with stripped comments and whitespace  proc_nice() - Change the priority of the current process  setrawcookie() - Send a cookie without URL-encoding the value  scandir() - List files and directories inside the specified path  str_split() - Convert a string to an array  strpbrk() - Search a string for any of a set of characters  substr_compare() - Binary safe optionally case insensitive comparison of two strings from an offset, up to length characters  error_get_last() - Get the last occurred error as associative array. Returns NULL if there hasn't been an error yet  memory_get_peak_usage() - Returns the peak allocated by PHP memory  sys_get_temp_dir() - Returns directory path used for temporary files  spl_object_hash() - Return hash id for given object
  • 22. Look at all the TOYS!
  • 23.  http://php.net/spl  http://www.php.net/~helly/php/ext/spl/  Standard PHP Library – common stuff you’d use all the time (in C!)  Some neat hooks for additional functionality you can’t do in PHP userland  Iterators, ArrayAccess, spl_autoload stuff  After5.3 you can’t turn this off (hurrah)  So much to find, I can’t fit it all in this talk  Highlights: ArrayObject, RecursiveFileIterator,
  • 24. Existing Classes - Filtering File Iterator <?php class RecursiveFileFilterIterator extends FilterIterator { /** * acceptable extensions - array of strings */ protected $ext = array(); /** * Takes a path and shoves it into our earlier class. * Turns $ext into an array. * @param $path directory to iterate * @param $ext comma delimited list of acceptable extensions */ public function __construct($path, $ext = 'php') { $this->ext = explode(',', $ext); parent::__construct(new RecursiveDirectoryIterator($path)); } /** * Checks extension names for files only. */ public function accept() { $item = $this->getInnerIterator(); // If it's not a file, accept it. if (!$item->isFile()) { return TRUE; } // If it is a file, grab the file extension and see if it's in the array. return in_array(pathinfo($item->getFilename(), PATHINFO_EXTENSION), $this->ext); } } // Same usage as above, but you can indicate allowed extensions with the optional second argument. foreach (new RecursiveFileFilterIterator('/path/to/something', 'php,txt') as $item) { // This is an SPLFileInfo object. echo $item . PHP_EOL; }
  • 25. Interfaces - This is your friend <?php class User implements ArrayAccess { private $db; // class to look up users in a db function offsetExists($name) { return $this->db->userExists($name); } function offsetGet($name) { return $this->db->getUserId($name); } function offsetSet($name, $id) { $this->db->setUserId($name, $id); } function offsetUnset($name) { $this->db->removeUser($name); } } $userMap = new User(); echo $userMap[quot;Bobquot;];
  • 26. Foreach fun rewinding <?php class MyIterator implements Iterator current: 1 { valid: 1 private $var = array(); current: 1 public function __construct($array) key: 0 { if (is_array($array)) { 0: 1 $this->var = $array; next: 2 } } current: 2 valid: 1 public function rewind() { echo quot;rewindingnquot;; current: 2 } reset($this->var); key: 1 1: 2 public function current() { $var = current($this->var); next: 3 echo quot;current: $varnquot;; current: 3 return $var; } valid: 1 current: 3 public function key() { $var = key($this->var); key: 2 echo quot;key: $varnquot;; return $var; 2: 3 } next: public function next() { current: $var = next($this->var); valid: echo quot;next: $varnquot;; return $var; } public function valid() { $var = $this->current() !== false; echo quot;valid: {$var}nquot;; return $var; } } $values = array(1,2,3); $it = new MyIterator($values); foreach ($it as $a => $b) { print quot;$a: $bnquot;; }
  • 27.  http://php.net/pdo  Database Access Layer  Common way to do db connections, different drivers for different dbs  Doesn’t do SQL abstraction!
  • 28. Basic Usage <?php /* Connect to an ODBC database using driver invocation */ $dsn = 'mysql:dbname=testdb;host=127.0.0.1'; $user = 'dbuser'; $password = 'dbpass'; try { $dbh = new PDO($dsn, $user, $password); } catch (PDOException $e) { echo 'Connection failed: ' . $e->getMessage(); } /* Execute a prepared statement by passing an array of values */ $sql = 'SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'; $sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); $sth->execute(array(':calories' => 150, ':colour' => 'red')); $red = $sth->fetchAll(); $sth->execute(array('calories' => 175, 'colour' => 'yellow')); $yellow = $sth->fetchAll();
  • 29. Advanced Usage <?php $stmt = $db->prepare(quot;select foo from barquot;); $stmt->execute(); $stmt->setFetchMode(PDO_FETCH_LAZY); foreach ($stmt as $row) { echo $row->foo; } ?> and the less verbose version: <?php foreach ($db->query(quot;select foo from barquot;, PDO_FETCH_LAZY) as $row) { echo $row->foo; } ?> Blobs: <?php $db = new PDO(quot;oci:quot;, quot;scottquot;, quot;tigerquot;); $db->beginTransaction(); // Essential! $stmt = $db->prepare( quot;INSERT INTO blobtest (id, contenttype, blob) quot;. quot;VALUES (:id, :type, EMPTY_BLOB()) quot;. quot;RETURNING blob INTO :blobquot;); $stmt->bindParam(':id', $id); $stmt->bindParam(':type', $type); $stmt->bindParam(':blob', $blob, PDO::PARAM_LOB); $type = 'image/gif'; $id = 1; // generate your own unique id here $blob = fopen('/path/to/a/graphic.gif', 'rb'); $stmt->execute(); $stmt->commit(); $stmt = $db->prepare('select blob from blobtest where id = ?'); $stmt->execute(array($id)); $row = $stmt->fetch(); var_dump($row); var_dump(stream_get_contents($row[0]));
  • 30.  http://php.net/mysqli i means improved (I didn’t name it)  Transactions, prepared statements, the stuff actually works  Procedural API or OO API (take your pick)
  • 31. Mysql Improved <?php $mysqli = new mysqli(quot;localhostquot;, quot;my_userquot;, quot;my_passwordquot;, quot;worldquot;); $link = mysqli_connect(quot;localhostquot;, quot;my_userquot;, quot;my_passwordquot;, quot;worldquot;); /* check connection */ /* check connection */ if (mysqli_connect_errno()) { if (mysqli_connect_errno()) { printf(quot;Connect failed: %snquot;, mysqli_connect_error()); printf(quot;Connect failed: %snquot;, mysqli_connect_error()); exit(); exit(); } } $city = quot;Amersfoortquot;; $city = quot;Amersfoortquot;; /* create a prepared statement */ /* create a prepared statement */ if ($stmt = $mysqli- if ($stmt = mysqli_prepare($link, quot;SELECT District FROM City WHERE Nam >prepare(quot;SELECT District FROM City WHERE Name=?quot;)) { e=?quot;)) { /* bind parameters for markers */ /* bind parameters for markers */ $stmt->bind_param(quot;squot;, $city); mysqli_stmt_bind_param($stmt, quot;squot;, $city); /* execute query */ /* execute query */ $stmt->execute(); mysqli_stmt_execute($stmt); /* bind result variables */ /* bind result variables */ $stmt->bind_result($district); mysqli_stmt_bind_result($stmt, $district); /* fetch value */ /* fetch value */ $stmt->fetch(); mysqli_stmt_fetch($stmt); printf(quot;%s is in district %snquot;, $city, $district); printf(quot;%s is in district %snquot;, $city, $district); /* close statement */ /* close statement */ $stmt->close(); mysqli_stmt_close($stmt); } } /* close connection */ /* close connection */ $mysqli->close(); mysqli_close($link);
  • 32.  http://php.net/json  JavaScriptObject Notation  Douglas Crocker http://json.org/  http://gggeek.altervista.org/sw/article_200 61113.html interesting benchmarks <?php $arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5); echo json_encode($arr); var_dump(json_decode($arr)); var_dump(json_decode($arr, true));
  • 33.  http://php.net/filter  Clean things up array(6) { [quot;product_idquot;]=> array(1) { [0]=> string(17) quot;libgd%3Cscript%3Equot; <?php } /* data actually came from POST [quot;componentquot;]=> $_POST = array( 'product_id' 'component' => 'libgd<script>', => '10', array(1) { 'versions' => '2.0.33', [0]=> 'testscalar' => array('2', '23', '10', '12'), 'testarray' => '2', int(10) ); */ } $args = array( [quot;versionsquot;]=> 'product_id' => FILTER_SANITIZE_ENCODED, array(1) { 'component' => array('filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_ARRA [0]=> Y, 'options' => array('min_range' => 1 string(6) quot;2.0.33quot; , 'max_range' => 10) ), } 'versions' => FILTER_SANITIZE_ENCODED, [quot;doesnotexistquot;]=> 'doesnotexist' => FILTER_VALIDATE_INT, 'testscalar' => array( NULL 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_SCALAR, [quot;testscalarquot;]=> ), 'testarray' => array( bool(false) 'filter' => FILTER_VALIDATE_INT, [quot;testarrayquot;]=> 'flags' => FILTER_REQUIRE_ARRAY, ) array(1) { ); [0]=> $myinputs = filter_input_array(INPUT_POST, $args); int(2) var_dump($myinputs); } echo quot;nquot;; }
  • 34.  http://php.net/simplexml  XML for dummies <?php $xmlstr = <<<XML <?xml version='1.0' standalone='yes'?> <?php <movies> include 'example.php'; <movie> <title>PHP: Behind the Parser</title> $xml = new SimpleXMLElement($xmlstr); <characters> <character> echo $xml->movie[0]->plot; // quot;So this language. It's like...quot; <name>Ms. Coder</name> $xml = new SimpleXMLElement($xmlstr); <actor>Onlivia Actora</actor> </character> echo $xml->movie->{'great-lines'}- <character> >line; // quot;PHP solves all my web problemsquot; <name>Mr. Coder</name> <actor>El Act&#211;r</actor> $xml = new SimpleXMLElement($xmlstr); </character> </characters> /* For each <movie> node, we echo a separate <plot>. */ <plot> foreach ($xml->movie as $movie) { echo $movie->plot, '<br />'; So, this language. It's like, a programmin } g language. Or is it a scripting language? All is revealed in thi $xml = new SimpleXMLElement($xmlstr); s thrilling horror spoof of a documentary. /* Access the <rating> nodes of the first movie. </plot> * Output the rating scale, too. */ <great-lines> foreach ($xml->movie[0]->rating as $rating) { <line>PHP solves all my web problems</line switch((string) $rating['type']) { // Get attributes as element indices > case 'thumbs': </great-lines> echo $rating, ' thumbs up'; <rating type=quot;thumbsquot;>7</rating> break; <rating type=quot;starsquot;>5</rating> case 'stars': </movie> echo $rating, ' stars'; </movies> break; XML; } ?> }
  • 35.  Soap – web services  Sqlite – file based light DB  Reflection – view information about code  DateTime – OO and timezone support for date manipulation  Dom, xmlreader, and xmlwriter – better ways to manipulate xml
  • 36. Oooh, shiny buzzword. What we really mean is do more in C And use Design Patterns – but you knew that…
  • 37.  What functionality do  What functionality do you need? you have?  What technologies  What technologies do will you use? you use?  What built in features  What can be replaced can you leverage? with built in features? New and Shiny Old and Busted
  • 38.  Use interfaces,  Use “shortcut” abstract classes, and functions to replace other OO features to common actions – lock in patterns like scandir to get a list of files, file_put_contents singleton and restrict visibility  Use new extensions to replace userland  Use SPL features to implementations – xml add intelligent parsers, json encoding iteration or provide and decoding common functionality In OO Code In Procedural Code
  • 39.  Avoid trying to make PHP act like other languages  Reflection is nice, using it does not make a good JAVA style MVC controller  Use PHP5 strengths and avoid weaknesses  json is a good choice for data transfer, xml is slower but standard, xaml would require either a PECL extension or a PHP userland parser  Don’t reinvent the wheel  Spl has a recursivedirectoryiterator – use it  http_build_query is quick and safe  use the filter extension for validation or sanitizing
  • 40.  Use of SAX xml parsers – xmlreader is your friend  Json encoders/decoders  Crufty ways of doing singletons, abstract classes, private/protected by naming conventions, CLASSNAME_CONSTANTNAME constants  Add features (like encryption) without messing up old code with streams and filters  Throw out crazy custom array code and use the built in stuff – array_combine rocks
  • 41. Remember – C is faster than PHP  You don’t have to use all the PHP5 features, but don’t use hacks to fake them either  You don’t have to use OOP, but don’t complete shun it on principle.  Writing an extensive function to filter the results of a scandir array is silly when you can use RecursiveDirectoryIterator
  • 42.  What version of PHP should be on your server?  Why?  What’s the one thing to remember from this talk?  What does that mean when thinking about writing code?  What’s my favorite color?  And what color are these slides?
  • 43.  Name some magic methods in PHP  What should you never use to prefix your own methods?  How do you copy a PHP5 object  What does “deep copy” mean and why is it problematic in PHP5?  Howcan you have more than one __autoload methods?  What’s the one thing to remember when using an spl autoload stack?
  • 44.  What is a stream?  Name two common PHP streams  What is a filter  How do you use filters with file_get_contents  What is your favorite new function in PHP5?  Why?  Why is preg_last_error useful?  How much do you like regex ;)  Name one new header function  Halfway there…
  • 45.  What does mysqli provide that mysql does not?  What does the I stand for.  What extension can you use to validate and sanitize data?  What extension is very useful with xmlhttprequest?  How can you control what properties of an object are shown with foreach?  What interface do you have to use to do this?
  • 46.  Name one PHP4 hack no longer needed in PHP5  Why isn’t it needed? How would you replace it?  Name one technology you’d use in a new project because of improved PHP5 support  Would you use a different one if PHP5 had better support?  What is the difference between how you approach designing a new project, and redoing parts of a legacy project?  How are they the same?