Tiempo: 2h escuela técnica superior de ingeniería informática Versión original: José Antonio Parejo y Manuel Resinas (diciembre 2008) Última revisión: Amador Durán y David Benavides (diciembre 2006); revisión y buenas prácticas. [Ángel US V7] Diseño: Amador Durán Toro (2003-2006) Departamento de Lenguajes Applied Software Engineering Group December 2008
SQL is the common language to work with all Data Bases. The interfaces that programmers use to work with each database in are different. In order to solve these problems we need abstraction layers (a common interface). Grupo de Ingeniería del Software 1
Basic Concepts PDO = Portable Data s Is a library of objects that allows to access databases from code. PDO provides an abstraction layer for data access, in a way that our code is independent form de DBMS we use. The most important object on PDO is the PDO object, that represents a connection with the DB. PDO is part of the standard distribution from version v5.1 PDO PDODriver PDOException Parameters Grupo de Ingeniería del Software 2
Actors Data Provider (PDO Specific Driver) Connection ( Objeto PDO) Data Base (MySQL, MS Access, SQL Server) Sucess.php PDO PDO Specific Driver PDO Specific Driver 2 BD BD2 Grupo de Ingeniería del Software 3
PDO : This object represents a connection to a database, allowing us to execute queries and obtain results. Common usage: $hostname = 'localhost'; $username = 'username'; $password = 'password'; try { $dbh = new PDO("mysql:host=$hostname;dbname=mysql", echo Connected ; // // Close the connection $dbh = null; catch( PDOException $e ) { // Exception handlin echo error de conexión:.$e->getmessage(); $username,$password); If we don t cath trown Exceptions, the server will Show execution trace & Data including DB user and password!!! Grupo de Ingeniería del Software 4
PDO object methods: PDO(connectionString connectionstring, [user], [pwd pwd], [opts]): establish a connection to our DB. ConnectionString format depends on the DBMS. User and Password are optional. Moreover we can provide a set of config. options (using an array as parameter). begintransaction() ():begin a transaction. commit(): end current transaction and confirm changes. rollback(): abort current transaction. exec(sql): execute a SQL instruction (INSERT, UPDATE, DELETE) and return the number of affected rows. query(sql): executes a SQL query ( SELECT ), returns an object containing the results. lastinsertid(): returns the primary key of last inserted row. (Note: this method can return inconsistent results depending on the driver you use). Grupo de Ingeniería del Software 5
: Represents a prepared statement and, after the statement is executed, an associated result set. Common usage: try { $stmt= $dbh->query("select " ); //alternatively you can use: $stmt = $dbh->prepare("select WHERE a=:data"); $stmt->bindparam(':data', $name); $stmt->execute(); catch(pdoexception $e ) { //Exception Handling echo "error: ".$e->getmessage(); // usage (iterate on results). Grupo de Ingeniería del Software 6
methods: bindparam(paremeters): Binds a parameter to the specified variable name. execute([parameters]): executes the query using either the values of parameters (if provided) or the binded params or values. rowcount(): returns the number of affected rows by tye query (does not work on all DBMS). columncount(): returns the number of columns of the result set. $calories = 150; $colour = 'red'; $sth = $dbh->prepare('select name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'); $sth->execute(array(':calories' => $calories, ':colour => $colour)); Grupo de Ingeniería del Software 7
, iterating on results (2 options): // $stmt is a previously executed foreach ($stmt as $row) { echo $row[ column1 ]; echo $row["columnn ]; // $stmt is a previously executed $row = $stmt->fetch(); while ($row) { echo $row["column1"]; echo $row["columnn"]; $row = $stmt->fetch(); fetch(): Returns the next row of the resultset or false if it was is the last one. Sevilla, noviembre de 2006 Grupo de Ingeniería del Software 8
try/catch blocks in with PDO All PDO object operations can raise exeptions that you should catch. The exception trown is of type PDOException, a subclass of the basic Exception class. Exception methods: getmessage(): returns the message that describes the error getfile(): Gets the name of the file the exception was thrown from. getline():returns line number where the exception was thrown. gettrace() y gettraceasstring():returns the Exception stack trace. Error handling using the catch block: The usual code of the catch block is resouces management and inform the user of the error. Sevilla, noviembre de 2006 Grupo de Ingeniería del Software 9
Code modularization when using a DB: formulario Form <% %> FormMng Data stored on Session Yes errors? No Sucess exito <% %> Data Access Logic Data Base A Mngmnt. Functions func inserta(p1,p2){ var SQL =. B Mngmnt Functions func insertb(p1,p2){ var SQL =.... X Mngmnt Functions func insertx(p1,p2){ var SQL =. Sevilla, noviembre de 2006 Grupo de Ingeniería del Software 10
<% exito Sucess %> Obtain form data Set Session values to null Use provided data (e.g. insert it on a BDs) php include_once( usermng.php ); $form = $_SESSION["form ]; $_SESSION["form ] = null; $_SESSION["errors ] = null; <html> <head> <title>result of registering</title> </head> <body> if(insertuser(form[ name ], form[ address ]) { <div id="div_sucess"> <h1>hello = form[ name ], thank you for registering</h1> </div> else { <div id= div_error_register > Sorry, there is a user with your addresss </div> <div id="div_return"> Press <a href="formulario.php >here</a> to return to the form. </div> </body> </html> Grupo de Ingeniería del Software 11
Funciones de Gestión de X < % func insertx(p1,p2){ var SQL =. % > To implement data access logic of our application for each domain concept: Insert Update Delete Select by different criteria. /* +-------------------------------------------+ User Management +-------------------------------------------+*/ // Insert: function insertuser($user, $address){ $result=true; $users=usersbyaddress($address); $row = $users->fetch(); if($row){ $dbh = new PDO("mysql:host=localhost;dbname=mysql", $username,$password); $stmt = $dbh.execute("insert INTO users ); else This code is not really data $result=false; $row = null; $users=null; return result; access logic but businesss logic. // Selection of users by different criteria: function usersbyaddress($address){ Duplication of connection $dbh = new PDO(); data / code $stmt = $dbh->prepare("select * FROM users WHERE address= :address ); $stmt->bindparam(":address", $address); $stmt->execute(); return $stmt; Sevilla, noviembre de 2006 Grupo de Ingeniería del Software 12
Usually we must follow this steps on each function fo the data access layer: Build a SQL sentence [Opcional] parameter filtering and formatting. Obtain a conecction. Options: Open directly the connection in this function Obtain the connection from $_SESSION or $_SYSTEM Use the connection as a parameter of each function Execute the SQL sentence [Optional] Error/Exception handling (we could delegate error handling on calling block, to allow specific error handling) If we open a connection we must close it Return results
BDConnect <? func connectdb() { return $dbh; func closebdconnect() {? > X Management <? func insertx($p1){ $dbh->.? > php include_once( BDConnect.php ); include_once( gestionusers.php ); $form = $_SESSION["form ]; $_SESSION["form ] = null; $_SESSION["errors ] = null; $dbh = connectdb(); <html> <head> <title>registering Result</title> </head> <body> if(insertuser(form[ name ], form[ address ],$dbh) { <div id="div_sucess"> <h1>hello = form[ name ], thank you for registering</h1> </div> else{ <div id= div_error_registering > Sorry, there is a user with your addresss. </div> <div id="div_return"> Press <a href="formulario.php >here</a> to return to the form. </div> </body> closedbconnection($dbh); </html>