Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Talking to the Database

0 views

Published on

An introduction on using PDO to talk databases, as well as overviews of Zend_Db, PhpORM, and Doctrine

Published in: Technology
  • Be the first to comment

Talking to the Database

  1. 1. November 16, 2010 NWO-PUG 1 Talking To The Database Chris Tankersley Joind.in Link: http://joind.in/2348 E-mail: chris@ctankersley.com Twitter: @dragonmantank
  2. 2. November 16, 2010 NWO-PUG 2 Who Are You and Why Are You In My House? Chris Tankersley Been doing PHP for almost 8 years now Lots of projects no one uses released under the BSD license Contributer to the Habari Project
  3. 3. November 16, 2010 NWO-PUG 3 An entire talk on PHP ↔ DB? Yes
  4. 4. November 16, 2010 NWO-PUG 4 What will we gain? How to use PDO to make DB access easier Overview of ORMs (Object Relational Mappers)
  5. 5. November 16, 2010 NWO-PUG 5 A History Lesson
  6. 6. November 16, 2010 NWO-PUG 6 Old Skool PHP Hardcoded Everything 1 <?php 2 $conn = mysql_connect('localhost', 'root', ''); 3 mysql_select_db('mydb') or die('Bad Connection!'); 4 5 $query = 'SELECT * FROM mytable WHERE id = '.$_GET['id']; 6 $result = mysql_query($query); 7 8 while($row = mysql_fetch_assoc($result)) { 9 echo $row['id'].': '.$row['value']; 10 }
  7. 7. November 16, 2010 NWO-PUG 7 Then we got smarter config.php 1 define('DB_HOST', 'localhost'); 2 define('DB_USERNAME', 'root'); 3 define('DB_PASSWORD', ''); 4 define('DB_DATABASE', 'mydb'); 1 require_once('config.php'); 2 3 $conn = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD); 4 if($conn == null) { 5 die('Unable to connect'); 6 } 7 8 if(!mysql_select_db(DB_DATABASE)){ 9 die('Couldnt connect to DB'); 10 } db.php
  8. 8. November 16, 2010 NWO-PUG 8 Then we got smarterer Classes! 1 class DB { 2 var $conn; 3 function DB() 4 { 5 $this->conn = $this->connect(DB_TYPE); 6 } 7 8 function connect($type = 'MYSQL') { 9 switch($type) { 10 case 'MYSQL': 11 return mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD); 12 break; 13 case 'POSTGRESQL': 14 // ...
  9. 9. November 16, 2010 NWO-PUG 9 PHP Data Objects ● Introduced in PHP 2004 with PHP 5.0 ● Enabled by Default since 2005 with PHP 5.1 ● Provides DB Abstraction ● Safer (if used right)
  10. 10. November 16, 2010 NWO-PUG 10 What is PDO? ● A Generic interface for working with databases ● Supports a wide range of DB servers via extensions ● MySQL ● PostgreSQL ● SQL Server ● SQLite ● http://www.php.net/manual/en/pdo.drivers.php
  11. 11. November 16, 2010 NWO-PUG 11 Find What Drivers are Available Check phpinfo(); Ask PDO: 1 foreach(PDO::getAvailableDrivers as $driver) { 2 echo $driver.'<br>'; 3 }
  12. 12. November 16, 2010 NWO-PUG 12 Let's Connect! ● Connection Strings ● They are extension specific 1 try { 2 $dbh = new PDO('mysql:host=localhost;dbname=mydb', 'root', ''); 3 echo 'Connected!'; 4 } catch (PDOException $e) { 5 echo $e->getMessage(); 6 } MySQL: 1 try { 2 $dbh = new PDO('sqlite:/path/to/database.db'); 3 echo 'Connected!'; 4 } catch (PDOException $e) { 5 echo $e->getMessage(); 6 } SQLite:
  13. 13. November 16, 2010 NWO-PUG 13 Always Be Prepared ● PDO can be used with or without prepared statements ● Always use prepared statements ● Preparing statements is the easiest way to avoid SQL injection ● Binding can be done via name or order (starting at 1)
  14. 14. November 16, 2010 NWO-PUG 14 Always Be Prepared 1 $stmt = $dbh->prepare('SELECT * FROM mytable WHERE id = :id'); 2 $stmt->bindParam('id', $_GET['id'], PDO::PARAM_INT); 3 //$stmt->bindParam(1, $_GET['id'], PDO::PARAM_INT); 4 $stmt->execute(); 5 $result = $stmt->fetchAll();
  15. 15. November 16, 2010 NWO-PUG 15 Reading Results ● PDO allows different ways to fetch data ● PDO::FETCH_ASSOC ● PDO::FETCH_NUM ● PDO::FETCH_BOTH ● PDO::FETCH_OBJ ● PDO::FETCH_CLASS
  16. 16. November 16, 2010 NWO-PUG 16 First 3 are Familiar 1 // Fetching a single row from the DB 2 $stmt = $dbh->prepare('SELECT * FROM mytable WHERE id = :id'); 3 $stmt->bindParam('id', $_GET['id'], PDO::PARAM_INT); 4 $result = $stmt->fetch(PDO::FETCH_ASSOC); 5 6 foreach($result as $key => $val) { 7 echo $key.': '.$val.'<br>'; 8 } 9 10 // id: 1 11 // value: myname
  17. 17. November 16, 2010 NWO-PUG 17 First 3 are Familiar 1 // Fetching a single row from the DB 2 $stmt = $dbh->prepare('SELECT * FROM mytable WHERE id = :id'); 3 $stmt->bindParam('id', $_GET['id'], PDO::PARAM_INT); 4 $result = $stmt->fetch(PDO::FETCH_NUM); 5 6 foreach($result as $key => $val) { 7 echo $key.': '.$val.'<br>'; 8 } 9 10 // 0: 1 11 // 1: myname
  18. 18. November 16, 2010 NWO-PUG 18 First 3 are Familiar 1 // Fetching a single row from the DB 2 $stmt = $dbh->prepare('SELECT * FROM mytable WHERE id = :id'); 3 $stmt->bindParam('id', $_GET['id'], PDO::PARAM_INT); 4 $result = $stmt->fetch(PDO::FETCH_BOTH); 5 6 foreach($result as $key => $val) { 7 echo $key.': '.$val.'<br>'; 8 } 9 10 // id: 1 11 // 0: 1 12 // value: myname 13 // 1: myname
  19. 19. November 16, 2010 NWO-PUG 19 PDO::FETCH_OBJ Returns an Object 1 // Fetching a single row from the DB 2 $stmt = $dbh->prepare('SELECT * FROM mytable WHERE id = :id'); 3 $stmt->bindParam('id', $_GET['id'], PDO::PARAM_INT); 4 $result = $stmt->fetch(PDO::FETCH_OBJ); 5 6 var_dump($result); 7 8 //object(stdClass)#1 (2) { 9 // ["id"]=> 10 // int(1) 11 // ["value"]=> 12 // string(6) "myname" 13 //}
  20. 20. November 16, 2010 NWO-PUG 20 PDO::FETCH_CLASS is Neat ● Takes a result and turns it into a class ● Use to instatiate a class directly from the DB
  21. 21. November 16, 2010 NWO-PUG 21 Our Class 1 class MyClass { 2 protected $id; 3 protected $value; 4 5 public function __set($key, $val) { 6 $function = 'set'.ucfirst($key); 7 $this->$function($val); 8 } 9 10 public function setId($val) { 11 $this->id = $id; 12 } 13 14 public function setValue($val) { 15 $this->value = 'Value: '.$val; 16 } 17 18 public function getId() { return $this->id; } 19 20 public function getValue() { return $this->value; } 21 }
  22. 22. November 16, 2010 NWO-PUG 22 PDO → Class 1 // Fetching all rows from the DB 2 $stmt = $dbh->prepare('SELECT * FROM mytable'); 3 $result = $stmt->fetchAll(PDO::FETCH_CLASS, 'MyClass'); 4 5 foreach($result as $class) { 6 echo $class->getId().': '.$class->getValue(); 7 } 8 9 // 1: Value: myname 10 // 2: Value: othername
  23. 23. November 16, 2010 NWO-PUG 23 The Shoulders of Giants ● They know more than we do (sometimes) ● They take care of bugs ● They did most of the work ● Why reinvent the wheel?
  24. 24. November 16, 2010 NWO-PUG 24 Zend_Db ● Default database accessor for Zend Framework ● Allows for Row Data Gateway access ● Couple with Zend_Db_Table to allow for Table Data Gateway ● Zend_Db_Select for statement building ● Easy to pick up and learn ● Lots of magic to save you time
  25. 25. November 16, 2010 NWO-PUG 25 Easier to Define Connections ● Uses PDO or native functions ● Same layout for all connections 1 $db = Zend_Db::factory('Pdo_Mysql', array( 2 'host' => 'localhost', 3 'username' => 'root', 4 'password' => '', 5 'dbname' => 'mydb', 6 );
  26. 26. November 16, 2010 NWO-PUG 26 Statements ● Can be direct queries with binding: 1 $stmt = $db->query( 2 'SELECT * FROM mytable WHERE id = ?', 3 array($_GET['id')); ● Can be built via PHP: 1 $select = $db->select()->from('mytable') 2 ->where('id = ?', $_GET['id']);
  27. 27. November 16, 2010 NWO-PUG 27 Multiple Fetching Options ● Can fetch everything with ->fetchAll() ● Can fetch a single row with ->fetch() ● Can use different modes (NUM, ASSOC, OBJ)
  28. 28. November 16, 2010 NWO-PUG 28 Zend_Db_Table ● Makes working with tables easier 1 class MyTable extends Zend_Db_Table_Abstract { 2 protected $_name = 'mytable'; 3 } 4 5 // Create Instance 6 $table = new MyTable(); 7 $table->insert(array('value'=>'New Value')); 8 9 // Update the table 10 $where = $table->getAdapter()->quoteInto('id = ?', 1); 11 $table->update(array('value' => 'Newer Value'), $where); 12 13 // Delete the row 14 $table->delete($where); 15 16 // Select something 17 $select = $table->select()->where('id < 10'); 18 $result = $table->fetchAll($select);
  29. 29. November 16, 2010 NWO-PUG 29 PhpORM ● Halfway between Zend_Db and Doctrine ● Sits on top of Zend_Db (soon directly PDO) ● Allows for 1:n or 1:1 relationships between entities ● Some basic CLI commands ● Decouples Objects from the Database
  30. 30. November 16, 2010 NWO-PUG 30 Basic Ideas ● Doesn't matter where the data comes from ● Entities should be defined by business requirements, not the database schema ● Make building apps easy without extra 'stuff'
  31. 31. November 16, 2010 NWO-PUG 31 Entities ● Objects your app needs to use 1 Class Animal extends PhpORM_Entity 2 { 3 protected $_daoObjectName = 'Dao_Animals'; 4 5 /** type=primary_autoincrement **/ 6 protected $id; 7 /** type=varchar length=50 **/ 8 protected $type; 9 /** type=date **/ 10 protected $inductionDate; 11 /** type=varchar length=50 null **/ 12 protected $name; 13 }
  32. 32. November 16, 2010 NWO-PUG 32 Repositories Fetch Entities 1 class Repository_Animals extends PhpORM_Repository 2 { 3 protected $_daoObjectName = 'Dao_Animals'; 4 protected $_entityName = 'Animal'; 5 } 6 7 $repo = new Repository_Animals(); 8 // Return all the cats 9 $cats = $repo->fetchAllBy('type', 'cat'); 10 // Find the specified object by primary key 11 $dog = $repo->find($dogId); 12 // Search by something other than primary key 13 $fluffy = $repo->findOneBy('name', 'Fluffy');
  33. 33. November 16, 2010 NWO-PUG 33 Doctrine ● Hugely popular ORM solution ● Doctrine 2 is a huge rewrite and only PHP 5.3+ ● I'll be showing 1.2 ● Allows for complex relationships ● Can generate migration models ● Models are generated from config files
  34. 34. November 16, 2010 NWO-PUG 34 Rich Command Line Client ● Client takes care of creating PHP code for you ● Can either go from Yaml → PHP + DB ● Or you can go from Db → PHP Objects
  35. 35. November 16, 2010 NWO-PUG 35 Yaml Files Generate Objects 1 Project: 2 columns: 3 id: 4 type: integer 5 primary: true 6 autoincrement: true 7 name: string(255) 8 description: text 1 $project = new Project(); 2 $project->id = 4; 3 $project->name = 'My Project'; 4 $project->description = 'A description'; 5 $project->save();
  36. 36. November 16, 2010 NWO-PUG 36 Doctrine has way more ● DQL – Doctrine Query Language ● Lazy Loading of relationships ● Caching
  37. 37. November 16, 2010 NWO-PUG 37 Links ● PDO ● http://php.net/manual/en/book.pdo.php ● Zend_Db ● http://framework.zend.com/manual/en/zend.db.html ● PhpORM ● https://github.com/dragonmantank/PhpORM ● Doctrine ● http://www.doctrine-project.org/
  38. 38. November 16, 2010 NWO-PUG 38 Thanks!

×