The History of PHPersistence       Hugo Hamon - @hhamon       OSIDays November 2011
PHP/FIWhere Everything Begins…
1995PHP/FI
1995Files handling
$fp = fopen("/counter.txt","w+");		$counter = fgets($fp,1024);	$counter++;		fputs($fp, $counter);	fclose($fp);	  
1995Databases support
$db = mysql_connect("localhost", "root", "secret");$name = "bob";$result = mysql(    $db,    "select * from table where fi...
$i=0;while ($i<$num);    echo mysql_result($result,$i,"lcase(fullname)");    echo "n";    echo mysql_result($result,$i,"ad...
PHP 3/4Code Reusability
User Functions
function db_connect($database, $host, $user, $pwd);function db_fetch_single($dbh, $query);function db_fetch_all($dbh, $que...
function db_connect($database, $host, $user, $pwd){    $dbh = mysql_connect($host, $user, $pwd);    if (!$dbh) {        di...
/**  * Fetches a single record from a database  *  * @param resource $dbh The database handler  * @param string $query A S...
function db_fetch_all($dbh, $query){    $result = mysql_query($query, $dbh);    if (!$result) {        die(Invalid query: ...
function db_insert($dbh, $table, array $values){    $data = array();    foreach ($values as $value) {        $data[] = mys...
include lib/database.inc.php;$dbh = db_connect(osidays);$query = SELECT id, name FROM author;$authors = db_fetch_all($dbh,...
PHP 4OOP & Reusability
class Database{    function Database($database, host, $user, $pwd);    function   disconnect();    function   connect();  ...
require lib/Database.php;$db= &new Database(demo, localhost, root);$q = SELECT id, name FROM author;foreach ($db->fetchAll...
require lib/Database.php;$db= &new Database(demo, localhost, root);$q = SELECT id, name FROM author WHERE id = 1;$author =...
require lib/Database.php;$db= &new Database(demo, localhost, root);$res = $db->insert(author, array(    name => Jules Vern...
PHP 4Professional APIs
DBAL
• PEAR::DB   • MDB• ADOdb      • MDB2• Metabase • Creole
§  Multiple databases support§  Uni ed APIs§  Prepared statements supports§  Query caching§  Security against SQL Inj...
PEAR MDB2
$dsn = array(    phptype    =>   mysql,    username   =>   root,    password   =>   ,    hostspec   =>   localhost,    dat...
ADOdb
include(adodb.inc.php);$db = NewADOConnection(mysql);$db->Connect(localhost, root, password, demo);$result = $db->Execute(...
2004PHP 5
2005PHP Data Object
•  PECL extension as of PHP 5.0.0•  Core extension since PHP 5.1.0 (11/2005)•  12 official drivers as of today•  Extensible ...
« PDO provides a data-access abstractionlayer, which means that, regardless ofwhich database youre using, you use thesame ...
« PDO does not provide adatabase abstraction as itdoesnt rewrite SQL or emulatemissing features »
Transactions         /Prepared Statements
try {  $pdo->beginTransaction(); $query = INSERT INTO author (name) VALUES (?); $stmt = $pdo->prepare($query); $stmt->bind...
Stored Procedures
DELIMITER |CREATE PROCEDURE coming_events (IN start DATE, OUT events INT)BEGIN  SELECT COUNT(*) INTO events FROM events WH...
PHP 5Zend_Db
Table Data Gateway
class AuthorGateway    extends Zend_Db_Table_Abstract{    protected $_name = authors;    protected $_primary = author_id;}
$data = array(    first_name => Jules,    last_name => Vernes,);$table = new AuthorGateway();$table->insert($data);
Row Data Gateway
$table = new AuthorGateway();// New empty row$row = $table->createRow();// Insert a new row$row->firstName = Jules;$row->l...
Active Query
$isbn = 1234567890;$rows = $db->select()    ->from(array(b => books))    ->where(b.isbn = ?, $isbn)    ->order(array(b.tit...
PHP 5Object Relational Mapping
•  Use objects instead of raw SQL queries•  Database abstraction layer (not always)•  Relationships support•  Behaviors su...
2005Propel ORM
$author = new Author();$author->setFirstName("Leo");$author->setLastName("Tolstoy");$book = new Book();$book->setTitle("Wa...
$query = BookQuery::create()  ->joinWith(Book.Author)  ->joinWith(Book.Publisher)  ->where(Author.firstName = ?, Leo)  ->w...
2009Doctrine 1.x
$books = Doctrine_Query::create()    ->select(b.*, a.*, p.*)    ->from(Book b)    ->leftJoin(b.Author a)    ->leftJoin(b.P...
2009	     	  PHP	  5.3	  
ORM Frameworks
Doctrine2
•  Database Abstraction Layer•  Object Relational Mapping•  Schema management•  Migrations support•  XML & NoSQL databases...
/** @Entity() */class Author{  /**   * @Id()   * @GeneratedValue()   * @Column(type="integer")   */  private $id;    /** @...
$post = new BlogPost();$post->setTitle(My First Blog Post);$post->setBody(Some content...);$author = new Author();$author-...
Toward NoSQL…
«	  Not	  Only	  SQL	  »	  
Key   abcdef	     Hugo	  Hamon	     Value
FirstName:	  Hugo	     Column 1Key   abcdef	     LastName:	  Hamon	      Column 2                     Role:	  Speaker	    ...
DocumentKey  abcdef	     Name:	  Hugo	  Hamon	                                              0:	  PHP	                 Skil...
2009MongoDB Driver
•  Cross-platform support•  Schemaless language•  BSON type support•  Binary le storage support (GridFS)•  Master – slave ...
$mongo = new Mongo();$col = $mongo->selectDb(osidays)->books;$books = array(    array(title => Da Vinci Code),    array(ti...
What’s next…… for today and tomorrow?
2011PHP 5.3 ODM Frameworks
•  ORM Layers for Mongodb•  Dealing with objects instead of arrays•  Relationships support•  Query abstraction•  GridFS su...
$post = new BlogPost();$post->setTitle(My First Blog Post);$post->setBody(Some content...);$author = new Author();$author-...
QuesAons?	   92-98, boulevard Victor Hugo 92 115 Clichy Cedex trainings@sensio.com (+33 (0)1 40 99 82 11) sensiolabs.com -...
The History of PHPersistence
The History of PHPersistence
The History of PHPersistence
Upcoming SlideShare
Loading in...5
×

The History of PHPersistence

2,521

Published on

Persistence is one of the most important part in a PHP project. Persisting data to a database came with PHP/FI and its MySQL support. From native extensions and PHP4 database abstraction libraries to PDO and modern ORM frameworks, you will (re)discover how persistence has evolved during the last decade. This talk will also introduce the future of data persistence with the growing success of alternative storage engines.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,521
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
21
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

The History of PHPersistence

  1. 1. The History of PHPersistence Hugo Hamon - @hhamon OSIDays November 2011
  2. 2. PHP/FIWhere Everything Begins…
  3. 3. 1995PHP/FI
  4. 4. 1995Files handling
  5. 5. $fp = fopen("/counter.txt","w+"); $counter = fgets($fp,1024); $counter++; fputs($fp, $counter); fclose($fp);  
  6. 6. 1995Databases support
  7. 7. $db = mysql_connect("localhost", "root", "secret");$name = "bob";$result = mysql( $db, "select * from table where firstname=$name");$num = mysql_numrows($result);echo "$num records found!<p>";
  8. 8. $i=0;while ($i<$num); echo mysql_result($result,$i,"lcase(fullname)"); echo "n"; echo mysql_result($result,$i,"address"); echo "n"; $i++;endwhile;
  9. 9. PHP 3/4Code Reusability
  10. 10. User Functions
  11. 11. function db_connect($database, $host, $user, $pwd);function db_fetch_single($dbh, $query);function db_fetch_all($dbh, $query);function db_insert($dbh, $table, $values);function db_update($dbh, $table, $values, $pk);function db_delete($dbh, $table, $pk);function db_list_fields($dbh, $table);function db_drop_table($dbh, $table);
  12. 12. function db_connect($database, $host, $user, $pwd){ $dbh = mysql_connect($host, $user, $pwd); if (!$dbh) { die(Server unavailable: . mysql_error()); } if (!mysql_select_db($database, $dbh)) { die("$database unavailable: ". mysql_error()); } return $dbh;}
  13. 13. /** * Fetches a single record from a database * * @param resource $dbh The database handler * @param string $query A SQL query * @return array A single record as an array */function db_fetch_single($dbh, $query){ return current(db_fetch_all($dbh, $query));}
  14. 14. function db_fetch_all($dbh, $query){ $result = mysql_query($query, $dbh); if (!$result) { die(Invalid query: . mysql_error()); } $records = array(); while ($record = mysql_fetch_assoc($result)) { $records[] = $record; } return $records;}
  15. 15. function db_insert($dbh, $table, array $values){ $data = array(); foreach ($values as $value) { $data[] = mysql_real_escape_string($value, $dbh); } $sql = sprintf("INSERT INTO `$table` (`%s`) VALUES (%s)", implode(`, `, array_keys($values)), implode(", ", $data) ); $result = mysql_query($query, $dbh); if (!$result) { die(Invalid data to insert: . mysql_error()); } return mysql_insert_id($dbh);}
  16. 16. include lib/database.inc.php;$dbh = db_connect(osidays);$query = SELECT id, name FROM author;$authors = db_fetch_all($dbh, $query);$author = db_fetch_single( $dbh, SELECT id, name FROM author WHERE id = 3);$id = db_insert($dbh, author, array( name => Jules Verne));
  17. 17. PHP 4OOP & Reusability
  18. 18. class Database{ function Database($database, host, $user, $pwd); function disconnect(); function connect(); function free(); function getErrorMessage(); function getErrorCode(); function getLastInsertId(); function insert($table, array $values); function fetchAll($query); function fetchSingle($query); function query($query); function quote($string); function hasError(); function _collectError(); function _init();}
  19. 19. require lib/Database.php;$db= &new Database(demo, localhost, root);$q = SELECT id, name FROM author;foreach ($db->fetchAll($q) as $author) { // ...}$db->free();$db->disconnect();
  20. 20. require lib/Database.php;$db= &new Database(demo, localhost, root);$q = SELECT id, name FROM author WHERE id = 1;$author = $db->fetchSingle($q);$db->free();$db->disconnect();
  21. 21. require lib/Database.php;$db= &new Database(demo, localhost, root);$res = $db->insert(author, array( name => Jules Vernes));if ($result) { $id = $db->getLastInsertId();}$db->disconnect();
  22. 22. PHP 4Professional APIs
  23. 23. DBAL
  24. 24. • PEAR::DB • MDB• ADOdb • MDB2• Metabase • Creole
  25. 25. §  Multiple databases support§  Uni ed APIs§  Prepared statements supports§  Query caching§  Security against SQL Injections
  26. 26. PEAR MDB2
  27. 27. $dsn = array( phptype => mysql, username => root, password => , hostspec => localhost, database => demo,);$db = & MDB2::connect($dsn);$db->setFetchMode(MDB2_FETCHMODE_ASSOC);$rs = $db->queryAll(SELECT id, name FROM author);$db->disconnect();
  28. 28. ADOdb
  29. 29. include(adodb.inc.php);$db = NewADOConnection(mysql);$db->Connect(localhost, root, password, demo);$result = $db->Execute(SELECT id, name FROM author);if ($result) { while (!$result->EOF) { echo ID: , $result->fields[0] ,"n"; echo Name:, $result->fields[1] ,"n"; $result->MoveNext(); }}
  30. 30. 2004PHP 5
  31. 31. 2005PHP Data Object
  32. 32. •  PECL extension as of PHP 5.0.0•  Core extension since PHP 5.1.0 (11/2005)•  12 official drivers as of today•  Extensible Object Oriented API•  Prepared statements & transaction support•  Stored procedures support
  33. 33. « PDO provides a data-access abstractionlayer, which means that, regardless ofwhich database youre using, you use thesame functions to issue queries and fetchdata. »
  34. 34. « PDO does not provide adatabase abstraction as itdoesnt rewrite SQL or emulatemissing features »
  35. 35. Transactions /Prepared Statements
  36. 36. try { $pdo->beginTransaction(); $query = INSERT INTO author (name) VALUES (?); $stmt = $pdo->prepare($query); $stmt->bindValue(1, Jules Verne); $stmt->execute(); $id = $pdo->lastInsertId(); $pdo->commit();} catch (PDOException $e) { $pdo->rollback();}
  37. 37. Stored Procedures
  38. 38. DELIMITER |CREATE PROCEDURE coming_events (IN start DATE, OUT events INT)BEGIN SELECT COUNT(*) INTO events FROM events WHERE start_at >=start;END|$query = "CALL coming_events(2011-03-01, @events);";$pdo->query($query);$stmt = $pdo->query("SELECT @events;");echo $stmt->fetchColumn() , events to come.;
  39. 39. PHP 5Zend_Db
  40. 40. Table Data Gateway
  41. 41. class AuthorGateway extends Zend_Db_Table_Abstract{ protected $_name = authors; protected $_primary = author_id;}
  42. 42. $data = array( first_name => Jules, last_name => Vernes,);$table = new AuthorGateway();$table->insert($data);
  43. 43. Row Data Gateway
  44. 44. $table = new AuthorGateway();// New empty row$row = $table->createRow();// Insert a new row$row->firstName = Jules;$row->lastName = Verne;$row->save();
  45. 45. Active Query
  46. 46. $isbn = 1234567890;$rows = $db->select() ->from(array(b => books)) ->where(b.isbn = ?, $isbn) ->order(array(b.title ASC)) ->query() ->fetchAll();
  47. 47. PHP 5Object Relational Mapping
  48. 48. •  Use objects instead of raw SQL queries•  Database abstraction layer (not always)•  Relationships support•  Behaviors support (i18n, timestampable…)•  Querying API•  Error logging
  49. 49. 2005Propel ORM
  50. 50. $author = new Author();$author->setFirstName("Leo");$author->setLastName("Tolstoy");$book = new Book();$book->setTitle("War & Peace");$book->setIsbn("0140444173");$book->setAuthor($author);$book->save();
  51. 51. $query = BookQuery::create() ->joinWith(Book.Author) ->joinWith(Book.Publisher) ->where(Author.firstName = ?, Leo) ->where(Author.lastName = ?, Tolstoï) ->orderByTitle() ->filterByPublishYear(2009) ->find();
  52. 52. 2009Doctrine 1.x
  53. 53. $books = Doctrine_Query::create() ->select(b.*, a.*, p.*) ->from(Book b) ->leftJoin(b.Author a) ->leftJoin(b.Publisher p) ->where(a.firstName = ?, Karl) ->andWhere(a.lastName = ?, Marx) ->orderBy(b.title ASC) ->execute();
  54. 54. 2009    PHP  5.3  
  55. 55. ORM Frameworks
  56. 56. Doctrine2
  57. 57. •  Database Abstraction Layer•  Object Relational Mapping•  Schema management•  Migrations support•  XML & NoSQL databases support
  58. 58. /** @Entity() */class Author{ /** * @Id() * @GeneratedValue() * @Column(type="integer") */ private $id; /** @Column(type="string", length="30") */ private $name; /** @ReferenceMany(targetDocument="BlogPost") */ private $posts = array();}
  59. 59. $post = new BlogPost();$post->setTitle(My First Blog Post);$post->setBody(Some content...);$author = new Author();$author->setName(Hugo Hamon);$author->addPost($post);$em->persist($user);$em->persist($post);$dm->flush();
  60. 60. Toward NoSQL…
  61. 61. «  Not  Only  SQL  »  
  62. 62. Key abcdef   Hugo  Hamon   Value
  63. 63. FirstName:  Hugo   Column 1Key abcdef   LastName:  Hamon   Column 2 Role:  Speaker   Column 3
  64. 64. DocumentKey abcdef   Name:  Hugo  Hamon   0:  PHP   Skills   1:  HTML   2:  CSS   Role:  Speaker  
  65. 65. 2009MongoDB Driver
  66. 66. •  Cross-platform support•  Schemaless language•  BSON type support•  Binary le storage support (GridFS)•  Master – slave replication support•  Sharding (horizontal scaling)
  67. 67. $mongo = new Mongo();$col = $mongo->selectDb(osidays)->books;$books = array( array(title => Da Vinci Code), array(title => The Lost Symbol), array(title => Digital Fortress),);foreach ($books as $book) { $collection->insert($book);}
  68. 68. What’s next…… for today and tomorrow?
  69. 69. 2011PHP 5.3 ODM Frameworks
  70. 70. •  ORM Layers for Mongodb•  Dealing with objects instead of arrays•  Relationships support•  Query abstraction•  GridFS support•  Query logging & caching
  71. 71. $post = new BlogPost();$post->setTitle(My First Blog Post);$post->setBody(Some content...);$author = new Author();$author->setName(Hugo Hamon);$author->setEmail(hugo@example.com);$dm->persist($user);$user->addPost($post);$dm->flush();
  72. 72. QuesAons?   92-98, boulevard Victor Hugo 92 115 Clichy Cedex trainings@sensio.com (+33 (0)1 40 99 82 11) sensiolabs.com - symfony.com – trainings.sensiolabs.com
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×