<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>UseStrict Consulting &#187; Select</title>
	<atom:link href="http://usestrict.net/tag/select/feed/" rel="self" type="application/rss+xml" />
	<link>http://usestrict.net</link>
	<description>Professional IT Solutions &#38; Training</description>
	<lastBuildDate>Sat, 12 May 2012 14:25:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>PHP+PDO+MySQL: How I&#8217;m doing it and a question&#8230;</title>
		<link>http://usestrict.net/2009/08/phppdomysql-how-im-doing-it-and-a-question/</link>
		<comments>http://usestrict.net/2009/08/phppdomysql-how-im-doing-it-and-a-question/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 12:47:18 +0000</pubDate>
		<dc:creator>vinny</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PDO]]></category>
		<category><![CDATA[Select]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Update]]></category>

		<guid isPermaLink="false">http://usestrict.net/?p=832</guid>
		<description><![CDATA[Example of PHP+PDO+MySQL usage to select and update arbitrary fields. Only one prepared statement is used for updating the data.]]></description>
			<content:encoded><![CDATA[<p>I recently decided to rewrite an application that I created for an English school where I used to work, and this time I want to do it right. I chose to write it in PHP with Object Orientation in mind, and use PDO+MySQL for the DAO portion.</p>
<p>The reason for using PDO is that it&#8217;s the closest thing to the DBI that I found for PHP &#8211; and the reason for PHP is that it&#8217;s just plain simpler than using pure Perl, and I don&#8217;t have the time to learn Catalyst or some other Perl Web framework.</p>
<p>Anyway, here&#8217;s what I&#8217;m doing for the PDO portion.</p>
<p>First I created a <code>Db</code> class which is just a DB connection wrapper.</p>
<pre class="brush:php">
&lt;?php
class Db{

	public $dbh  = null;

	public function Db($db_type,$db_host,$db_user,
			         $db_pass,$db_base,$tbl_prefix){

		if ($db_type == 'mysql') { // in case I want to add oracle in the future

			$mysql_DSN = "mysql:host=".$db_host.";dbname=".$this->db_base;

			try {
				$this->dbh = new PDO($mysql_DSN, $db_user, $db_pass,
							   array(PDO::ATTR_PERSISTENT => true, PDO::ERRMODE_WARNING => true,
							         PDO::ATTR_ERRMODE => true));

			}
			catch(PDOException $e){
				$rc[msg] = $e->getMessage();
				die($rc[msg] . "  " . __LINE__);
			}

			return $this->dbh;

		}

	}

}
?&gt;
</pre>
<p>Secondly, I created the DAO classes which extend the DB. They are responsible for <code>prepare</code>&#8216;ing and <code>execute</code>&#8216;ing the queries, and returning the data. Here&#8217;s an example one (I stripped some bells and whistles in order to not confuse anyone):</p>
<pre class="brush:php">
&lt;?php
class StudentsDao extends Db {

	public $sth = array();

	// Constructor
	public function StudentsDao($db_type=NULL,$db_host=NULL,$db_user=NULL,
				  	       $db_pass=NULL,$db_base=NULL,$tbl_prefix=NULL) { // These params are to be passed to Db class

		// Connect to DB
		$this->Db($db_type,$db_host,$db_user,
			      $db_pass,$db_base,$tbl_prefix);

		// Prepares queries
		$this->sth = $this->prepare($tbl_prefix); // Look at prepare() further down

	} // end of function StudentsDao

	// Function that prepares queries
	public function prepare() {

		$sth = null; // will hold our temporary array

		// get all students
		$string = sprintf('select * from %s.%sstudents where id = ?',DB_BASE,TBL_PREFIX);	// I have these constants defined in the main page
		$sth['getStudentById'] = $this->dbh->prepare($string);

		// update Student by Id
		$string = sprintf('update %s.%sstudents
				   set field1 = ?, field2 = ?, field3 = ?
				   where id = ?',DB_BASE,TBL_PREFIX);	// Note that this table has 3 control fields (id, sys_creation_date, and sys_update_date)  prior to field1, field2, and field3 - I don't want them to be touched

		$sth['updStudentById'] = $this->dbh->prepare($string);

		return $sth;

	} // end of prepare()

	// Here we have the handlers for the queries prepared above.

	// Fetches all students
	public function getStudentById($id) {

		$s = $this->sth['getStudents'];
		$s->execute(array($id)) || die(print_r($s->errorInfo,1));
		$result = $s->fetchAll(PDO::FETCH_ASSOC);

		if (sizeof($result) == 0) {
			// no data found
			$out[err_cd] = 1;
		}
		else {
			// data was found
			$out[err_cd] = 0;
			$out[data] = $result;
		}

		return $out;

	}

	// Updates student by Id - this is a tricky one
	public function updateStudentById($data,$id){ // $data can have data regarding one or more fields

		// Populate current fields
		$fields = $this->getStudentById($id); // get current values

		// Remove unwanted fields
		$fields = array_slice($fields[data][0],3); // remove the 3 initial control fields

		// Replace with new fields
		foreach($data as $k=>$v){
			$fields[strtolower($k)] = $v;
		}
		$fields['id'] = $id;

		$s = $this->sth['updStudentById'];
		$s->execute(array_values($fields)) || die(print_r($s->errorInfo,1));
		$count = $s->rowCount();

		if ($count == 1) {
			$out[err_cd] = 0;
		}
		else {
			$out[err_cd] = -1;
		}
		$out[err_msg] = $this->status[$out[err_cd]];
		return $out;

	}
?&gt;
</pre>
<p>In the example above, you will probably frown on the fact that I&#8217;m calling <code>getStudentById()</code> at the beginning of <code>updateStudentById()</code>. It&#8217;s OK &#8211; I frown on it, too. Let me explain why I did that:</p>
<p>I wanted to be able to pass the function an associative array containing only the fields I want to update &#8211; be it only <code>field1</code>, or <code>field1</code> and <code>field2</code> and so on. But I wanted to do that against my already prepared query, and not touching any additional fields. In my application, <code>students</code> table has a BUNCH of fields. In other words, update any given field or set of fields using the single prepared statement, <strong>without</strong> having to set ALL the fields in <code>$data</code></p>
<p>My original idea was to basically, to emulate something like this:</p>
<p><code> update students set field1=field1, field2='some new value ', field3=field3 where id = 1</code></p>
<p>That would set <code>field1</code> to whatever value <code>field1</code> already had. </p>
<p><strong>Here&#8217;s the question part:<br />
Unfortunately, I couldn&#8217;t figure out how to do that using the PDO (how to bind a field name instead of a value against the <code>?</code>-mark). If you know how to do that, do leave a comment explaining how! <img src='http://usestrict.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
</strong></p>
<p>The technique shown in the example will basically pull all values from the record and populate them in the <code>$fields</code> array. The <code>array_slice()</code> is used to remove the control fields that I have in my table, and the rest gets compared against the <code>$data</code> array and if any matching fields are found in <code>$data</code>, those fields get their values assigned over the existing <code>$fields</code> values.</p>
]]></content:encoded>
			<wfw:commentRss>http://usestrict.net/2009/08/phppdomysql-how-im-doing-it-and-a-question/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

