Www.supinfo.com Copyright © SUPINFO. All rights reserved PDO, PHP Data Object Use a Database with...

Post on 26-Dec-2015

220 views 0 download

Tags:

Transcript of Www.supinfo.com Copyright © SUPINFO. All rights reserved PDO, PHP Data Object Use a Database with...

www.supinfo.com

Copyright © SUPINFO. All rights reserved

PDO, PHP Data Object

Use a Database with PHP

Course objectives

Explain what is PDO.

Use PDO in a PHP project.

Manage Transactions with PDO.

Explain and use Prepared Statements.

At the end of this lesson you will be able to:

PDO, PHP Data Object

Course topics

Introduction.

Basics.

Transaction Management.

Prepared Statements.

Course plan:

PDO, PHP Data Object

Introduction

Why PDO ?

PDO, PHP Data Object

Preview

Before PDO…

… and now.

PDO Architecture.

Advantages.

Installation.

Here the chapters which we will approach:

Introduction

Before PDO…

PDO is only available since PHP 5.

In PHP 4, you must use one of native extension dedicated to database access :

mysqli for MySQL.

oci8 for Oracle.

Each extension provides different specific functions.

Need to change the code if you want to change the DBMS !

Not a good approach…

Introduction

…and now.

PDO is the main new feature of PHP 5.1.

Object Oriented extension :

Provides ease of use and greater abstraction.

A common base for all the DBMS connectors :

No more need to change the code when you want to change of DBMS.

Or almost…

Introduction

PDO ArchitectureIntroduction

PHP >= 5.1 PDO

PDOMySQL

PDOOracle

PDOSQL Server

PDO…

MySQL

Advantages

PDO is written in C language :

Similar performance as the old native drivers.

Optimization opportunities thanks to prepared statements.

Not available with the old MySQL extension.

PDO can execute all query types :

INSERT, UPDATE, DELETE, SELECT

Stored procedure.

Introduction

Installation

PDO and all the major drivers ship with PHP as shared extensions.

You simply need to activate them by editing the php.ini file :

If you use a PHP version < 5.3 :

Add or uncomment the following line :

For all PHP version :

Add or uncomment the following line :

Introduction

extension=php_pdo.so ;(ou .dll sous Windows)

extension=php_pdo_mysql.so ;(ou .dll)

Stop-and-thinkIntroduction

Do you have any questions ?

Basics

Connection to a Database, execute a query, …

PDO, PHP Data Object

Preview

Here the chapters which we will approach:

PDO Classes.

PDO Example.

Database connection.

Perform a query.

Retrieve results.

Fetch Styles.

Basics

PDO Classes

The three main PDO classes that we’ll used are :

PDO : the link to the Database.

PDOStatement : represent a statement and its results.

PDOException : the exception thrown when an error occurs.

Basics

PDO ExampleBasics

$user = 'root';$password = 'root';$dsn = 'mysql:host=localhost;dbname=example';

try { $pdo = new PDO($dsn, $user, $password);} catch (PDOException $e) { die("Error ! : ".$e->getMessage());}

$pdo->exec("INSERT INTO sample (col) VALUES ('val')");

$result = $pdo->query("SELECT col FROM sample");while($row = $result->fetch()) { print_r($row);}

$pdo = NULL;

Database connection The first thing to do is to create a PDO class instance.

The constructor take three parameters :

The DSN (Database Source Name) :

The information about the Database to use.

Example for a MySQL Database :

The Username to use to connect to the Database.

The Password of the account.

Create a PDO instance can throw an exception :

If the necessary driver is not loaded.

If the access is denied.

Basics

mysql:host=localhost;port=3306;dbname=example

Database connection

To use several Database, just create several PDO instance :

Basics

$user1 = 'root'; $password1 = 'root';$dsn1 = 'mysql:host=localhost;dbname=example1';

try { $pdo1 = new PDO($dsn1, $user1, $password1);} catch (PDOException $e) { die(); }

$user2 = 'root';$password2 = 'root';$dsn2 = 'mysql:host=localhost;dbname=example2';

try { $pdo2 = new PDO($dsn2, $user2, $password2);} catch (PDOException $e) { die(); }

Perform a query

Once your connection is open, you can execute query thanks to two methods of PDO instance :

int exec ( string $statement ) :

Executes an SQL statement in a single function call, returning the number of rows affected by the statement.

PDOStatement query ( string $statement ) :

Executes an SQL statement in a single function call, returning the result set (if any) returned by the statement as a PDOStatement object.

Basics

Perform a queryBasics

SQL Statement PDO method

INSERT exec()

UPDATE exec()

DELETE exec()

SELECT query()

EXPLAIN query()

SHOW query()

DESC query()

Retrieve results After a call to the method query() retrieved data are kept in

memory, inside a PDOStatement instance.

The two main methods to manipulate this data are :

array fetchAll( [ $fetch_style=PDO::FETCH_BOTH] )

Returns an array containing all of the result set rows.

mixed fetch( [$fetch_style=PDO::FETCH_BOTH] )

Fetches a row from a result set associated with a PDOStatement object.

The fetch_style parameter determines how PDO returns the row.

Basics

Retrieve results

The fetchAll() method returns all the data in an array.

Very easy to use !

But not advisable if query return a large number of result !

In that case, fetch() method is the best choice !

Basics

Retrieve resultsBasics

$sql = "SELECT login, password FROM users";$sth = $pdo->query($sql);$result = $sth->fetchAll(PDO::FETCH_ASSOC);

foreach($result as $row) { echo $row['login'].'-'.$row['password'].'<br/>';}

$sql = "SELECT login, password FROM users";$sth = $pdo->query($sql);

while($row = $sth->fetch(PDO::FETCH_ASSOC)) { echo $row['login'].'-'.$row['password'].'<br/>';}

Fetch all example :

Sequential fetch example :

Fetch StylesBasics

VALUE ACTION

PDO::FETCH_ASSOCReturns an array indexed by column name as returned in your result set.

PDO::FETCH_NUMReturns an array indexed by column number as returned in your result set, starting at column 0.

PDO::FETCH_BOTHReturns an array indexed by both column name and 0-indexed column number as returned in your result set.

PDO::FETCH_OBJ

Returns an anonymous object with property names that correspond to the column names returned in your result set.

PDO::FETCH_CLASS

Returns a new instance of the requested class, mapping the columns of the result set to named properties in the class.

Fetch StylesBasics

$sql = "SELECT login, password FROM users";

$sth = $pdo->query($sql);$result = $sth->fetchAll(PDO::FETCH_ASSOC);print_r($result);

Array( [0] => Array ( [login] => Plop [password] => 1234 ))

PDO::FETCH_ASSOC :

Fetch StylesBasics

$sql = "SELECT login, password FROM users";

$sth = $pdo->query($sql);$result = $sth->fetchAll(PDO::FETCH_BOTH);print_r($result);

Array( [0] => Array ( [login] => Plop [0] => Plop [password] => 1234 [1] => Plop ))

PDO::FETCH_BOTH :

Fetch StylesBasics

$sql = "SELECT login, password FROM users";

$sth = $pdo->query($sql);$result = $sth->fetchAll(PDO::FETCH_OBJ);print_r($result);

Array( [0] => stdClass Object ( [login] => Plop [password] => 1234 ))

PDO::FETCH_OBJ :

Last Insert ID When you insert a new row inside a table, you often let

the DBMS generate the primary key.

You can retrieve the last generated ID thanks to the instance method of PDO :

string lastInsertId ([ string $name = NULL ]) :

If a sequence name was not specified for the name parameter, returns a string representing the row ID of the last inserted row.

Else, returns a string representing the last value retrieved from the specified sequence object.

Basics

$sql = "INSERT INTO users (login, password) VALUES ('john.doe', 'Plop')”;

$pdo->exec($sql);echo $pdo->lastInsertId();// Display the last generated ID

Stop-and-thinkBasics

Do you have any questions ?

ExercisesBasics

Now, you know how to use Database in PHP !

Create two new classes :

PdoUserManager implements UserManager interface.

PdoPostManager implements PostManager interface.

Implement methods using PDO and a MySQL Database.

Update your PHP page to use your new managers instead of the old ones.

They are no register method for now, so add an user directly in Database with a MySQL browser like phpMyAdmin.

Transaction Management

Commit, Rollback & cie.

PDO, PHP Data Object

Preview

Here the chapters which we will approach:

Presentation.

Case Study.

Provided methods.

Example.

Transaction Management

Presentation

Transaction is useful when you want defined a unified set of queries.

If they all succeed, changes are applied.

If one fails, no changes are applied.

We name commit the operation that applied changes in Database.

Transaction Management

Case study

For instance, transactions are very important in banking applications :

Imagine a bank transfer.

The operation is in two steps :

Withdraw money of one account.

Add it to an other.

Imagine each step is a Database query.

What happen if the second query failed ? Where is the money ?

Transaction Management

Provided methods

PDO instances provide three methods to manage transactions :

bool beginTransaction ( void ) :

Turns off auto-commit mode and so, changes made to the database via the PDO object instance are not committed until you end the transaction.

bool commit ( void ) :

Commits a transaction, returning the database connection to auto-commit mode.

bool rollBack ( void ) :

Rolls back the current transaction, returning the database connection to auto-commit mode.

Transaction Management

ExampleTransaction Management

// Define to PDO to generate errors as exceptions$pdo->setAttribute(PDO::ATTR_ERRMODE,

PDO::ERRMODE_EXCEPTION);$pdo->beginTransaction();try { $sql1 = "INSERT INTO author (firstname, lastname)

VALUES ( 'Clark', 'Kent' )"; $pdo->exec($sql);

$sql2 ="INSERT INTO article(title, body, author_id)VALUES('Plop', '...',".$pdo->lastInsertId().")";

$pdo->exec($sql2);

$pdo->commit();} catch (Exception $e) { $pdo->rollBack(); echo ”Error: ".$e->getMessage();}

Stop-and-thinkTransaction Management

Do you have any questions ?

Prepared Statement

Improved your queries.

PDO, PHP Data Object

Preview

Here the chapters which we will approach:

Presentation.

Execution Cycle.

Parameterized Prepared Statements.

Provided methods.

Example.

Prepared Statement

Presentation

Many of the more mature databases support the concept of prepared statements.

A prepared query only needs to be parsed (or prepared) once, but can be executed multiple times with the same or different parameters.

The database will analyze, compile and optimize it's plan for executing them.

Avoid repeating the analyze/compile/optimize cycle.

Protects against SQL injection.

This means that prepared statements use fewer resources, run faster and are more secure !

Prepared Statement

Execution CyclePrepared Statement

Analyze

Compile

Optimize

Run

Classic Statement or

first execution cycle of a prepared statement.

Next execution cycle for a prepared statement.

Parameterized Prepared Statements

A parameterized prepared statement is a prepared statement that you can define parameters.

Two types of parameterized prepared statements :

With ordered parameters :

With named parameters :

You can’t make a prepared statement mixing the two types of parameters.

Prepared Statement

$sql = "INSERT INTO users (login, password) VALUES (?, ?)”;

$sql = "INSERT INTO users (login, password) VALUES (:login, :password)”;

Provided methods

Once your statement is ready, you need to provide it to your DBMS.

To do that, you must use the following instance method of PDO class :

PDOStatement prepare ( string $statement ).

Prepared Statement

$sql = "INSERT INTO users (login, password) VALUES (?, ?)”;

$statement = $pdo->prepare($sql);

Provided methods

Once your statement is prepare, you can use it !

To define the statement parameters, you have two ways :

Passing them in parameters of the execute() instance method of PDOStatement.

Use the bindValue() instance method of PDOStatement.

Prepared Statement

Example passing parameters to execute() :

ExamplePrepared Statement

$sql = "INSERT INTO author (firstname, lastname) VALUES ( :firstname, :lastname )";

$statement = $pdo->prepare($sql);

$firstname = 'John';$lastname = 'Doe';

$statement->execute( array(':firstname' => $firstname,

':lastname' => $lastname)

);

Example using bindValue() :

ExamplePrepared Statement

$sql = "INSERT INTO author (firstname, lastname) VALUES ( :firstname, :lastname )";

$statement = $pdo->prepare($sql);

$firstname = 'John';$lastname = 'Doe';

$statement->bindValue(':firstname', $firstname);$statement->bindValue(':lastname', $lastname);

$statement->execute();

Stop-and-thinkPrepared Statement

Do you have any questions ?

Exercises (1/5)Prepared Statements

The code to create a new PDO instance inside your both managers are the same…

Maybe you have defined your Database information inside each of them ?

Very bad !

Imagine you want to change your Database ?

You should update each manager…

Remember : D(on’t) R(epeat) Y(ourself) !

Exercises (2/5)Prepared Statements

Create a new abstract class named AbstractPdoManager:

Define each of your connection parameters as a constant inside it.

Define a constructor that use this parameters to create a PDO instance.

Keep it into a protected instance variable.

Update your managers to extends this class and use his instance variable.

After that, you’ll DRY !

Exercises (3/5)Prepared Statements

Now you now that Prepared Statements are more secure and more efficient.

Update your managers to use Prepared Statements.

Exercises (4/5)Prepared Statements

Create the new domain class Comment :

With attributes :

id : an unique identifier.

body : the content of the comment.

post : the post where the comment has been posted.

user : the author of the comment if authenticated when the comment was posted.

publicationDate : the publication date of the comment.

With just getters and setters as instance methods.

Exercises (5/5)Prepared Statements

Update the Post class :

Add a new attributes named comments.

It represents the comments of the post.

Add a getter and a setter for that attribute.

Update the PdoPostManager to return Posts with their comments.

Create a new interface named CommentManager and an implementation named PdoCommentManager with :

addComment($body, $post, $user) method.

Update the display post page :

Add a form to post a comment.

Display the comments linked to the current post inside the display post page.

Prepared Statements

DBMS Query

PDO advantages

Summary of the Module

Transactions

PDO, PHP Data Object

For more

Publications

Web sites

If you want to go into these subjects more deeply, …

PDO, PHP Data Object

http://php.net/

http://www.nexen.net/

http://www.zend.com/

PHP 5 avancé

5e édition.Éric DASPET

Cyril PIERRE DE GEYER

Available on Cyberlibris.

http://library.supinfo.com/BookDetails.aspx?type=cyberlibris&docid=40001068

http://www.siteduzero.com/tutoriel-3-34790-pdo-interface-d-acces-aux-bdd.html