<?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>shapeshifter.se &#187; PHP</title>
	<atom:link href="http://www.shapeshifter.se/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.shapeshifter.se</link>
	<description>Mostly miscellaneous technical mumbo-jumbo.</description>
	<lastBuildDate>Mon, 11 Jul 2011 14:19:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>UUID generator for PHP</title>
		<link>http://www.shapeshifter.se/2008/09/29/uuid-generator-for-php/</link>
		<comments>http://www.shapeshifter.se/2008/09/29/uuid-generator-for-php/#comments</comments>
		<pubDate>Mon, 29 Sep 2008 18:48:44 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[UUID]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=352</guid>
		<description><![CDATA[UUID (Universally Unique Identifier) is standard (part of ISO/IEC 11578:1996) to create &#8220;universally unique&#8221; identifiers to identify objects within a system or across system boundaries. The identifiers are 128-bit in length (that&#8217;s 16 bytes) and while there really is no way to guarantee global uniqueness the probability of colissions are very small both thanks to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Uuid">UUID</a> (Universally Unique Identifier) is standard (part of ISO/IEC 11578:1996) to create &#8220;universally unique&#8221; identifiers to identify objects within a system or across system boundaries. The identifiers are 128-bit in length (that&#8217;s 16 bytes) and while there really is no way to guarantee global uniqueness the probability of colissions are very small both thanks to the number of bits and the way the identifiers are created.</p>
<p>The UUID generation algorithms are specified in <a href="http://tools.ietf.org/html/rfc4122">RFC4122</a> and I&#8217;ve created a static PHP class that implements version 1 which is time based UUID, version 4 which is truly psuedo random UUID and version 3 and 5 which are named based UUID, using either MD5 (version 3) or SHA-1 (version 5).<br />
<span id="more-352"></span><br />
I know there is a PECL package around the original uuidlib but this class have no external dependencies. The full source is available at the bottom of the page.</p>
<p><!-- WSA: rules for context 'adsense-post-top' did not apply --></p>
<p>The class has the following public functions, their return value depends on the format argument.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$mixed</span> generate<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fmt</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">FMT_BYTE</span><span style="color: #339933;">,</span> <span style="color: #000088;">$node</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ns</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000088;">$mixed</span> convert<span style="color: #009900;">&#40;</span><span style="color: #000088;">$uuid</span><span style="color: #339933;">,</span> <span style="color: #000088;">$from</span><span style="color: #339933;">,</span> <span style="color: #000088;">$to</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>UUID version constants where each constant represents a specific UUID version</p>
<blockquote>
<pre>UUID_TIME, UUID_NAME_MD5, UUID_RANDOM, UUID_NAME_SHA1</pre>
</blockquote>
<p>UUID format constants</p>
<ul>
<li><em>FMT_BYTE</em> is the default and returns a array of bytes that represents the 128-bit UUID.</li>
<li><em>FMT_FIELD</em> returns a associative array with individual fields as the format specified in RFC4122.</li>
<li><em>FMT_STRING</em> returns the familiar ASCII representation of a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx).</li>
<li><em>FMT_BINARY</em> returns a raw 128-bit binary representation of the UUID.</li>
</ul>
<p>The <em>convert</em> method can be used to convert between these representations.</p>
<h3>UUID version 1 example</h3>
<p>xxxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx<br />
Version 1 UUIDs are timed based with the node constant. The name space argument is ignored and is not used in the generation. The node identifier (&#8221;abcdef&#8221; in this case) should identify the node or object, only 6 bytes (or characters) are used from the node id.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'class.uuid.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span>UUID<span style="color: #339933;">::</span><span style="color: #004000;">UUID_TIME</span><span style="color: #339933;">,</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">FMT_STRING</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;abcdef&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$str</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Example output, the last part is the node id and will remain constant (as long as the node id is the same), the first part will change according to time while the middle part is pseudo random.</p>
<blockquote>
<pre>1b55e723-578b-4e34-d5cf-616263646566</pre>
</blockquote>
<p>The class does not fully implement version 1 as described in the RFC. The clock sequence is generated from a psuedo random generator each time a new UUID is generated and not written and read from a stable storage as described in the RFC.</p>
<h3>UUID version 4 example</h3>
<p>xxxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx<br />
Version 4 is a fully pseudo random where all fields are randomly generated.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'class.uuid.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span>UUID<span style="color: #339933;">::</span><span style="color: #004000;">UUID_RANDOM</span><span style="color: #339933;">,</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">FMT_STRING</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$str</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Kind of useless example output <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<blockquote>
<pre>d8988842-43d5-42b3-9049-af4bbc694dbe</pre>
</blockquote>
<h3>UUID version 3/5 example</h3>
<p>xxxxxxxxx-xxxx-3/5xxx-xxxx-xxxxxxxxxxxx<br />
The main difference is that a node id is unique within a name space and a UUID generated from the same node id and name space is always the same. The generation algorithm is the same for both version 3 and 5 with the only difference being the hash method used (MD5 versus SHA1).<br />
This is the example from the RFC.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'class.uuid.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * 6ba7b810-9dad-11d1-80b4-00c04fd430c8 is the DNS name space
 */</span>
<span style="color: #000088;">$md5</span> <span style="color: #339933;">=</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span>UUID<span style="color: #339933;">::</span><span style="color: #004000;">UUID_NAME_MD5</span><span style="color: #339933;">,</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">FMT_STRING</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">&quot;www.widgets.com&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'6ba7b810-9dad-11d1-80b4-00c04fd430c8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$sha1</span>  <span style="color: #339933;">=</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span>UUID<span style="color: #339933;">::</span><span style="color: #004000;">UUID_NAME_SHA1</span><span style="color: #339933;">,</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">FMT_STRING</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">&quot;www.widgets.com&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'6ba7b810-9dad-11d1-80b4-00c04fd430c8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;MD5: <span style="color: #006699; font-weight: bold;">$md5</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;SHA1: <span style="color: #006699; font-weight: bold;">$sha1</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Example output</p>
<blockquote>
<pre>MD5: e902893a-9d22-3c7e-a7b8-d6e313b71d9f
SHA1: 13726f09-44a9-5eeb-8910-3525a23fb23b</pre>
</blockquote>
<h3>Final notes</h3>
<p>This class have been tested with PHP 5.2.x on both little and big endian machines. While there could be bugs in the algorithm implementation at least they are consistent across platforms <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Get from github</h3>
<ul>
<li><a href="https://github.com/fredriklindberg/class.uuid.php">class.uuid.php</a></li>
</ul>
<h3>Links</h3>
<ul>
<li><a href="http://tools.ietf.org/html/rfc4122">RFC4122</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2008/09/29/uuid-generator-for-php/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Asynchronous background execution with PHP</title>
		<link>http://www.shapeshifter.se/2008/08/04/asynchronous-background-execution-with-php/</link>
		<comments>http://www.shapeshifter.se/2008/08/04/asynchronous-background-execution-with-php/#comments</comments>
		<pubDate>Mon, 04 Aug 2008 08:23:12 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=189</guid>
		<description><![CDATA[If you ever worked with threads and particular work queues you know how convenient they can be.
Have some demanding work that needs to be done but no time to do it yourself? No problem, just put it on the work queue and continue with whatever we were doing, some other thread will come along and [...]]]></description>
			<content:encoded><![CDATA[<p>If you ever worked with threads and particular work queues you know how convenient they can be.<br />
Have some demanding work that needs to be done but no time to do it yourself? No problem, just put it on the work queue and continue with whatever we were doing, some other thread will come along and do the dirty work for you.</p>
<p>Consider the following scenario. Actions and inputs from a web page triggers something that might take a (very) long time to execute and if executed during the browser session which besides annoying the user who has to wait for a page to load, might cause a time out and interrupt the processing. How do we solve this?</p>
<p><span id="more-189"></span></p>
<p>I&#8217;ll use the term <em>job</em> to indicate some work that needs to be execution, in practice this is an isolated PHP function which takes an unspecified time to execute.</p>
<p><!-- WSA: rules for context 'adsense-post-top' did not apply --></p>
<p>Some possible solutions</p>
<ul>
<li>Store job information somewhere (like a SQL database) have a separate script, PHP or in some other language, running on the host, either continuously or from <a href="http://en.wikipedia.org/wiki/Cron">crontab</a>. The obvious flaw is that it requires additional administrative maintenance to keep the script running and if executed from crontab, will cause an additional delay before the job is executed.</li>
<li>Use <a href="http://www.php.net/manual/en/function.pcntl-fork.php">pcntl_fork</a> from inside the (web page) PHP script and execute the job function in the child, problem is that this will fork an entire Apache (or whatever web server you&#8217;re using) processes which can cause all sorts of problems.</li>
<li>Some other solution I didn&#8217;t think about? <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>My solution ended up being a mix of the two above. It consists of three major parts and, a bit simplified, works like this</p>
<ol>
<li>Job information is stored in a SQL database.</li>
<li>An external CLI-based <em>worker</em> PHP-script is launched from inside the web page script using <a href="http://www.php.net/manual/en/function.proc-open.php">proc_open</a>.</li>
<li>The worker script, which is running in an isolated PHP process calls pcntl_fork to create a duplicate of itself. The parent returns directly to the web page script.</li>
<li>The child process of the worker script now runs free of any webserver process and can now retrieve job information from the SQL database. When all jobs are executed it kills itself.</li>
</ol>
<p>Here is a nice block diagram that shows the interaction of the components</p>
<p style="text-align: center;">
<a href="http://www.shapeshifter.se/wp-content/uploads/2008/08/bgphp.png"><img src="http://www.shapeshifter.se/wp-content/uploads/2008/08/bgphp-300x173.png" alt="Block layout of PHP background execution" title="bgphp" width="300" height="173" class="size-medium wp-image-205" style="float: none;" /></a>
</p>
<p>And viola, we have asynchronous background execution of (almost) arbitrary PHP functions. There are a few problems left to solve, we&#8217;ll tackle those further down.</p>
<p><strong>Requirements</strong></p>
<ul>
<li>PHP 5 built with CLI support</li>
<li>The PHP module pcntl</li>
<li>The classes <em>SQLConnector</em> and <em>Prefs</em> published in earlier posts.</li>
</ul>
<h3>SQL database</h3>
<p>First, we&#8217;ll need some database support. I&#8217;ve used MySQL, but any database should work fine. One simple table is required, it&#8217;s called <em>jobs</em> and looks like this</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------+---------------------+------+-----+---------+----------------+</span>
<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">FIELD</span> <span style="color: #66cc66;">|</span> Type                <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #66cc66;">|</span> Extra          <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------+---------------------+------+-----+---------+----------------+</span>
<span style="color: #66cc66;">|</span> jid   <span style="color: #66cc66;">|</span> bigint<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #66cc66;">|</span> NO   <span style="color: #66cc66;">|</span> PRI <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">DATA</span>  <span style="color: #66cc66;">|</span> text                <span style="color: #66cc66;">|</span> YES  <span style="color: #66cc66;">|</span>     <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span>                <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------+---------------------+------+-----+---------+----------------+</span></pre></div></div>

<p>The column <em>jid</em> is an arbitrary job id and the column <em>data</em> contains job information (more on what exactly job information is will be covered further down). You can create this table with the following SQL command</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> jobs <span style="color: #66cc66;">&#40;</span>jid bigint <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
    <span style="color: #993333; font-weight: bold;">DATA</span> text<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>jid<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<h3>PHP implementation</h3>
<p><!-- WSA: rules for context 'adsense-post-top' did not apply --><br />
The implementation consists of three files, we&#8217;ll focus on the class <em>jobs</em> first. This leads us into what exactly the <em>data</em> column should contain. Since the <em>job</em> (PHP function) will execute in a new context the worker must be able to bring in PHP files so that required functions and classes can be resolved. So, in addition to the actual job function and an opaque argument we also need to store a list of PHP files to include at execution time.</p>
<p>The complete data structure stored in the <em>data</em> column looks like this.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #666666; font-style: italic;">/* Version identifier of job structure */</span>
    <span style="color: #0000ff;">'version'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">/* Array of PHP files to include at execution time */</span>
    <span style="color: #0000ff;">'include'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">/* Name of actual job function */</span>
    <span style="color: #0000ff;">'callback'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">/* Opaque argument passed to callback function */</span>
    <span style="color: #0000ff;">'args'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>A dedicated class calls <em>jobs</em> manages jobs and allows enqueuing and dequeuing of jobs. For clarity, only the function prototypes are shown here, the full source code can be found at the bottom of the pafe.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> jobs <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_con</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">/* SQL Connector */</span>
    <span style="color: #000000; font-weight: bold;">const</span> jobversion <span style="color: #339933;">=</span> <span style="color: #0000ff;">'1'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">/* Job structure version */</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'version'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">jobversion</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'include'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'callback'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'args'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Enqueue a job for execution
     *  cb - Name of PHP function to execute
     *  args - Arguments to pass to 'cb'
     *  incs - Array of PHP files to include before execution
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> enqueue<span style="color: #009900;">&#40;</span><span style="color: #000088;">$cb</span><span style="color: #339933;">,</span> <span style="color: #000088;">$args</span><span style="color: #339933;">,</span> <span style="color: #000088;">$incs</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Return the job identifier (integer) of
     * next available job or -1 if no new jobs are
     * available.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> nextJob<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Dequeue job with id 'jid' for execution,
     * if no such job is available null is returned.
     *
     * An array with the following keys are returned
     *  (jid, include, callback, args)
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> dequeue<span style="color: #009900;">&#40;</span><span style="color: #000088;">$jid</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Attempt to launch worker process if not already running
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> startWorker<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The callback function &#8216;cb&#8217; will be called like this, <em>cb(args)</em>, before this call all files listed in the array <em>incs</em> will be included using <em>require_once</em>.<br />
The functions <em>enqueue</em>, <em>dequeue</em> and <em>nextJob</em> are nothing special, they simply do normal SQL manipulation (inserts and removes job from the table). However the routine <em>startWorker</em> might deserve some attention (it&#8217;s called internally from <em>enqueue</em>)</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/* Should be set to the path of the CLI PHP binary */</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;PHP_PATH&quot;</span><span style="color: #339933;">,</span>      <span style="color: #0000ff;">&quot;/usr/local/bin/php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> startWorker<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">/*
     * Attempt to read the preference
     * 'worker_pid' to check if the worker is
     * already running.
     */</span>
    <span style="color: #000088;">$prefs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Prefs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'jobs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$prefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">worker_pid</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span> <span style="color: #339933;">!=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* Get our working directory */</span>
    <span style="color: #000088;">$cwd</span> <span style="color: #339933;">=</span> <span style="color: #990000;">getcwd</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Construct a command such as the following
     *  /usr/local/bin/php /working/path/worker.php
     */</span>
    <span style="color: #000088;">$cmd</span> <span style="color: #339933;">=</span> <span style="color: #990000;">escapeshellcmd</span><span style="color: #009900;">&#40;</span>PHP_PATH <span style="color: #339933;">.</span><span style="color: #0000ff;">&quot; <span style="color: #006699; font-weight: bold;">$cwd</span>/worker.php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$desc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* Execute the command and wait for it to finish */</span>
    <span style="color: #000088;">$proc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">proc_open</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cmd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$desc</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pipes</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">proc_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$proc</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The <em>startWorker</em> function is executed in the context of a web page (from inside the Apache PHP module for example) and as you can see it doesn&#8217;t call <em>pcntl_fork</em> directly. Technically it still forks, otherwise it wouldn&#8217;t be able to execute another process. But we let the PHP module deal with that mess.</p>
<p>This leads us to worker.php<br />
File: <strong>worker.php</strong>
</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'prefs.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_mysql.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;PHP_PATH&quot;</span><span style="color: #339933;">,</span>      <span style="color: #0000ff;">&quot;/usr/local/bin/php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$argv</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Don't call me from a browser&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * Fork our self and let the parent return directly to startWorker
 */</span>
<span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;could not fork&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">/*
     * This is the parent process. Record the child pid so that we
     * don't launch more processes than wanted.
     */</span>
    <span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'localhost'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'pwd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$prefs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Prefs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'jobs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$prefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">worker_pid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pid</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$prefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">/*
     * Exit the script, it runs in a separate
     * PHP process NOT inside Apache
     */</span>
    <span style="color: #990000;">exit</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'localhost'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'pwd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span>
<span style="color: #000088;">$jobs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> jobs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$cwd</span> <span style="color: #339933;">=</span> <span style="color: #990000;">getcwd</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$cwd</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;can't get working directory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * Loop over all available jobs
 */</span>
<span style="color: #000088;">$pjid</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">;;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$jid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$jobs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">nextJob</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$jid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #339933;">||</span> <span style="color: #000088;">$jid</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$pjid</span><span style="color: #009900;">&#41;</span>
        <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Execute each job in a clean environment
     */</span>
    <span style="color: #000088;">$cmd</span> <span style="color: #339933;">=</span> <span style="color: #990000;">escapeshellcmd</span><span style="color: #009900;">&#40;</span>PHP_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; <span style="color: #006699; font-weight: bold;">$cwd</span>/job_execute.php <span style="color: #006699; font-weight: bold;">$jid</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$desc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$proc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">proc_open</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cmd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$desc</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pipes</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">proc_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$proc</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$pjid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$jid</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Tell the world that we aren't executing any more */</span>
<span style="color: #000088;">$prefs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Prefs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'jobs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$prefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">worker_pid</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span></pre></div></div>

<p>The first thing that happens is that <em>worker.php</em> forks itself and lets the parent return directly to the caller, which in this case is <em>startWorker</em>. This allows <em>startWorker</em> and thus <em>enqueue</em> to finish and the calling PHP script can resume with what ever it was doing (creating a web page etc).</p>
<p>Also note that <em>worker.php</em> doesn&#8217;t execute the job functions directly, instead it hands the jid number to a second script called <em>job_execute.php</em>. There is a good reason for this, since we must include PHP files (with <em>require_once</em>) to be able to execute the job function the namespace of the worker would be contaminated quite fast and with that comes the risk of name collisions. By letting each job execute in a totally clean environment they can include only the files needed for their execution and thus avoid any name collisions.
</p>
<p>
<em>job_execute.php</em> takes a job id (<em>jid</em>) as argument, dequeues the job, includes all required files, calls the job function and then terminates.
</p>
<p>File: <strong>job_execute.php</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_mysql.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$argv</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Don't call me from a browser&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$argv</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Job missing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$jid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$argv</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'localhost'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'pwd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$jobs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> jobs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$job</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$jobs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dequeue</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$jid</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Job dequeue failed&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * Include required files
 */</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'include'</span><span style="color: #009900;">&#93;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$inc</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$inc</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Execute the job handler */</span>
<span style="color: #000088;">$cb</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'callback'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$cb</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'args'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Okay, that should be all. Are you still with me? <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Using it</h3>
<p>
After all this&#8230;how do one use this then? First of all we need one or more job functions that we would like to be background executed. The prototype for such a function looks like this</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> myBgFunc<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #339933;">...</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Where <em>args</em> can be anything you like (as long as PHP allows it). Put the function inside a file and include (preferably with <em>require_once</em>) any other files that you might need. For example like this, not the best example, but anyway.</p>
<p>File: <strong>myfunc.php</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">/* $args is an integer in this case */</span>
<span style="color: #000000; font-weight: bold;">function</span> test1<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$j</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$args</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #000088;">$j</span> <span style="color: #339933;">*=</span> <span style="color:#800080;">1.00001</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">/* Report result somewhere */</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Now, from your run-of-the-mill PHP script, create a <em>jobs</em> object and enqueue the function <em>test1</em>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_mysql.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'localhost'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'pwd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$jobs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> jobs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">/* Remember, &quot;function&quot;, &quot;argument&quot;, &quot;files needed&quot; */</span>
<span style="color: #000088;">$jobs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enqueue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;test1&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">rand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">1000</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'myfunc.php'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;Job enqueued&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Even if <em>test1</em> takes ages to execute, the enqeue function will execute in a fraction of a second and report back directly to the web browser. You can enqueue any number of functions, they will be executed on a first-come first-serve basis.</p>
<h3>Improvements</h3>
<p>I&#8217;ve tested this a bit and it seems to work, however I haven&#8217;t put it through some real situation test yet. With some additional locking it should be possible to run multiple instances of <em>worker.php</em> to take advantage of SMP systems.</p>
<p>
There is no built-in mechanism to know when a job has finished. The job function will need to report its results to a SQL database for example. If browser feedback is needed an AJAX solution could poll the database for the execution status.</p>
<h3>Files</h3>
<p>
Files with complete source code
</p>
<ul>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/jobs.phps'>jobs.inc</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/worker.phps'>worker.php</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/job_execute.phps'>job_execute.php</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/prefs.phps'>prefs.inc</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/db_iface.phps'>db_iface.inc</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/db_mysql.phps'>db_mysql.inc</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/static.phps'>static.inc</a></li>
</ul>
<p>If you found this useful consider putting a link back to this article from your own blog/website, thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2008/08/04/asynchronous-background-execution-with-php/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>SQL backed preference system for PHP</title>
		<link>http://www.shapeshifter.se/2008/08/02/sql-backed-preference-system-for-php/</link>
		<comments>http://www.shapeshifter.se/2008/08/02/sql-backed-preference-system-for-php/#comments</comments>
		<pubDate>Sat, 02 Aug 2008 12:30:27 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=158</guid>
		<description><![CDATA[
Sometimes you need to store information and settings that really doesn&#8217;t fit into any other SQL table, in these situations it&#8217;s nice to have a generic key-value driven preference system.
The preference system consists of multiple stores or trunks, each store is identified by a unique, arbitrary string and each store has multiple key-value pairs. The [...]]]></description>
			<content:encoded><![CDATA[<p><!-- WSA: rules for context 'adsense-post-square' did not apply --><br />
Sometimes you need to store information and settings that really doesn&#8217;t fit into any other SQL table, in these situations it&#8217;s nice to have a generic key-value driven preference system.</p>
<p>The preference system consists of multiple stores or trunks, each store is identified by a unique, arbitrary string and each store has multiple key-value pairs. The key-value pairs are dynamically created and flushed to database when the preference object is destroyed or when an explicit flush is requested.<br />
<span id="more-158"></span><br />
This offers a very flexible system, illustrated by this example</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'localhost'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'username'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'password'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">/* Create a preference store called 'store1' */</span>
<span style="color: #000088;">$store1</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Prefs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'store1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">/* Create a preference store called 'myprefs' */</span>
<span style="color: #000088;">$myprefs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Prefs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'myprefs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$store1</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">some_setting</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$myprefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">abcd</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1234</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$store1</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">abcd</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4321</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$myprefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">a_list</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">print</span> <span style="color: #000088;">$myprefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">abcd</span> <span style="color: #339933;">*</span> <span style="color: #000088;">$store1</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">some_setting</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Do an explicit write to the database */</span>
<span style="color: #000088;">$store1</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>To build a system like this you&#8217;ll first need a SQL table in some database, I&#8217;ve called the table <em>prefs</em>. The table layout is very simple and only consists of two columns, the first is the store identifier and the second contains key-value pairs.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------+-------------+------+-----+---------+-------+</span>
<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">FIELD</span> <span style="color: #66cc66;">|</span> Type        <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #66cc66;">|</span> Extra <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------+-------------+------+-----+---------+-------+</span>
<span style="color: #66cc66;">|</span> ident <span style="color: #66cc66;">|</span> varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">64</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">|</span> NO   <span style="color: #66cc66;">|</span> PRI <span style="color: #66cc66;">|</span>         <span style="color: #66cc66;">|</span>       <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">DATA</span>  <span style="color: #66cc66;">|</span> text        <span style="color: #66cc66;">|</span> YES  <span style="color: #66cc66;">|</span>     <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span>       <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------+-------------+------+-----+---------+-------+</span></pre></div></div>

<p>You can create this table with the following SQL command</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> prefs <span style="color: #66cc66;">&#40;</span>ident varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">64</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">DATA</span> text<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>ident<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>The class itself <em>Prefs</em> is shown below</p>
<p><em>Note that this requires the SQL connector classes published earlier, if you don&#8217;t want to use those you&#8217;ll need to modify all SQL queries below to suite your needs.</em></p>
<p>File: <strong>prefs.inc</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_iface.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * Automatic SQL-backed preference system
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> Prefs <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">/* Connection handle */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_con</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">/* Store identifier */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_ident</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">/* Contains key-value pairs */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_dirty</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_fetched</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$connector</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ident</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$connector</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_ident</span> <span style="color: #339933;">=</span> <span style="color: #990000;">addslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ident</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* Write changes to database when object is destroyed */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __destruct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">doflush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> __get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$nm</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dofetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$nm</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">else</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$nm</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> __set<span style="color: #009900;">&#40;</span><span style="color: #000088;">$nm</span><span style="color: #339933;">,</span> <span style="color: #000088;">$val</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dofetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$nm</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$val</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dirty</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* Do an explicit flush to the database */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">Flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">doflush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Write key-value pairs to database
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> doflush<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dirty</span><span style="color: #009900;">&#41;</span>
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">addslashes</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">serialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$ident</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_ident</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;select count(*) from prefs where ident = '<span style="color: #006699; font-weight: bold;">$ident</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchRow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;update prefs set data = '<span style="color: #006699; font-weight: bold;">$data</span>' where ident = '<span style="color: #006699; font-weight: bold;">$ident</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;insert into prefs(ident, data) values('<span style="color: #006699; font-weight: bold;">$ident</span>', '<span style="color: #006699; font-weight: bold;">$data</span>')&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dirty</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Read key-value pairs from database
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> dofetch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_fetched</span><span style="color: #009900;">&#41;</span>
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$ident</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_ident</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;select data from prefs where ident = '<span style="color: #006699; font-weight: bold;">$ident</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNumRows</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchRow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">unserialize</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">stripslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_fetched</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>So how can this work then? the class uses the two magic constructs <em>__set</em> and <em>__get</em> to build automatic properties, there routines are called when an non-existing property is accessed.</p>
<p>For example</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">foo</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span></pre></div></div>

<p>This code would trigger __set in the class associated with $obj, it would be called with __set(&#8221;foo&#8221;, 10).<br />
The same goes for</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">print</span> <span style="color: #000088;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">foo</span></pre></div></div>

<p>which would trigger __get(&#8221;foo&#8221;) in the class associated with $obj.<br />
These implicit pairs are then stored in an array which is serialized and stored in a SQL database.</p>
<p>Note that this system makes use of <a href="http://www.php.net/manual/en/function.serialize.php">serialize</a> which is a PHP specific construct, this might make it difficult to access the data from other languages.</p>
<ul>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/prefs.phps'>prefs.inc</a></li>
</ul>
<p>If you found this helpful, tell a friend or put a link back to this article on your own website/blog.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2008/08/02/sql-backed-preference-system-for-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Generic Object Oriented SQL interface for PHP</title>
		<link>http://www.shapeshifter.se/2008/08/01/generic-object-oriented-sql-interface-for-php/</link>
		<comments>http://www.shapeshifter.se/2008/08/01/generic-object-oriented-sql-interface-for-php/#comments</comments>
		<pubDate>Fri, 01 Aug 2008 15:19:34 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=137</guid>
		<description><![CDATA[This is an extensible object oriented wrapper around the MySQL and MSSQL (Microsoft SQL Server) interfaces provided by PHP. I&#8217;ve been using them for a while, it&#8217;s nothing new and no rocket science but others might find them useful.

Why do this at all? why just not stick with the API provided by PHP? It&#8217;s really [...]]]></description>
			<content:encoded><![CDATA[<p>This is an extensible object oriented wrapper around the MySQL and MSSQL (Microsoft SQL Server) interfaces provided by PHP. I&#8217;ve been using them for a while, it&#8217;s nothing new and no rocket science but others might find them useful.<br />
<!-- WSA: rules for context 'adsense-post-square' did not apply --><br />
Why do this at all? why just not stick with the API provided by PHP? It&#8217;s really nothing else than a more convenient way to interact with a SQL server and exposing it&#8217;s interface in a vendor natural way. Instead of writing <em>mysql_query</em> everywhere, one simply writes <em>query</em>.</p>
<p>Having a consistent interface will obviously help if you are using multiple types of database servers or someday would like to migrate to another SQL server (of course, weird and vendor specific SQL code could be a problem in this case). Other advantages are things like automatic disconnection on object destruction etc.</p>
<p>The foundation is an abstract class called <em>SQLConnector</em> and provides the basic interface. The class will connect to the database on creation and disconnect when the object is destroyed, it also implements <em>__sleep</em> and <em>__wakeup</em> so that it&#8217;s possible to serialize a SQL connection.</p>
<p>Because <em>SQLConnector</em> is abstract one can&#8217;t create objects directly from it, we&#8217;ll create child classes for each type of SQL-server we want to connect to. These objects will share the same interface and can be used interchangeably.<br />
<span id="more-137"></span></p>
<p>File <strong>db_iface.inc</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>php
abstract <span style="color: #000000; font-weight: bold;">class</span> SQLConnector
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_dbAddress</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">/* Address of SQL server */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_dbAccount</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">/* Account name (username) */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_dbPwd</span><span style="color: #339933;">;</span>     <span style="color: #666666; font-style: italic;">/* Password */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_dbName</span><span style="color: #339933;">;</span>    <span style="color: #666666; font-style: italic;">/* Initial database */</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* Base constructor */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$address</span><span style="color: #339933;">,</span> <span style="color: #000088;">$account</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pwd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbAddress</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$address</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbAccount</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$account</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbPwd</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pwd</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbName</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">/* Call the connect method in the child class */</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbAddress</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbAccount</span><span style="color: #339933;">,</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbPwd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* Let the child disconnect when the object is destroyed */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __destruct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">disconnect</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* We are about to be serialized, disconnect
     * and return data needed for serialization
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __sleep<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">disconnect</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'m_dbAddress'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'m_dbAccount'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'m_dbPwd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'m_dbName'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* We have been unserialized, re-connect */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __wakeup<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbAddress</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbAccount</span><span style="color: #339933;">,</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbPwd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Abstract methods that needs to be implemented by child classes
     */</span>
    abstract protected <span style="color: #000000; font-weight: bold;">function</span> connect<span style="color: #009900;">&#40;</span><span style="color: #000088;">$address</span><span style="color: #339933;">,</span> <span style="color: #000088;">$account</span><span style="color: #339933;">,</span>
        <span style="color: #000088;">$pwd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    abstract protected <span style="color: #000000; font-weight: bold;">function</span> disconnect<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    abstract <span style="color: #000000; font-weight: bold;">function</span> query<span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    abstract <span style="color: #000000; font-weight: bold;">function</span> fetchRow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    abstract <span style="color: #000000; font-weight: bold;">function</span> fetchAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    abstract <span style="color: #000000; font-weight: bold;">function</span> getNumRows<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    abstract <span style="color: #000000; font-weight: bold;">function</span> freeResult<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    abstract <span style="color: #000000; font-weight: bold;">function</span> getError<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>The following class implements MySQL connectivity using the interface above</p>
<p>File: <strong>db_mysql.inc</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_iface.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> MySQLConnector <span style="color: #000000; font-weight: bold;">extends</span> SQLConnector
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_dbHandle</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_Result</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* 
     * Connect function, also selects correct database
     * Returns 1 upon success, otherwise 0
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> connect<span style="color: #009900;">&#40;</span><span style="color: #000088;">$address</span><span style="color: #339933;">,</span> <span style="color: #000088;">$account</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pwd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$address</span><span style="color: #339933;">,</span> <span style="color: #000088;">$account</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pwd</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Disconnect function
     * Returns 1 upon success, otherwise 0
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> disconnect<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">@</span><span style="color: #990000;">mysql_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
&nbsp;
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Does a mysql-query, returns 1 upon sucess otherwise 0
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> query<span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Fetches an array row
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> fetchRow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">mysql_fetch_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> fetchAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$a_rs</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$row</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #990000;">mysql_free_result</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$a_rs</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">/*
     * Get number of rows
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> getNumRows<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Free resources allocated by a query 
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> freeResult<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">mysql_free_result</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Get errorstring
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> getError<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>A (very) similar class for MSSQL connectivity<br />
File: <strong>db_mssql.inc</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_iface.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> MSSQLConnector <span style="color: #000000; font-weight: bold;">extends</span> SQLConnector
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_dbHandle</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_Result</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Connect function, also selects correct database
     * Returns 1 upon success, otherwise 0
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> connect<span style="color: #009900;">&#40;</span><span style="color: #000088;">$address</span><span style="color: #339933;">,</span> <span style="color: #000088;">$account</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pwd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #990000;">mssql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$address</span><span style="color: #339933;">,</span> <span style="color: #000088;">$account</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pwd</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mssql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Disconnect function
     * Returns 1 upon success, otherwise 0
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> disconnect<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">@</span><span style="color: #990000;">mssql_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">/*
     * Does a mssql-query, returns 1 upon success otherwise 0
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> query<span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mssql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Fetches an array row
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> fetchRow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">mssql_fetch_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> fetchAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mssql_fetch_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$a_rs</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$row</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #990000;">mssql_free_result</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$a_rs</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Get number of rows
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> getNumRows<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">mssql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Free resources allocated by a query
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> freeResult<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">mssql_free_result</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_Result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">/*
     * Get errorstring
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> getError<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> mssql_error<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>So, how do one use this then? It&#8217;s quite simple</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_mysql.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_mssql.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$c1</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mysql-host'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'username'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'password'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'mydb'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$c2</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MSSQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mssql-host'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'username'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'password'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'mydb'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$c1</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;select something from somewhere&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$c1</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchRow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #339933;">...</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$c2</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;select somethingelse from somewhereelse&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Improvements, oh yes. The connect functions should really throw an error if things doesn&#8217;t work.<br />
Also, wrappers for any SQL server should be quite easy to implement.</p>
<ul>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/db_iface.phps'>db_iface.inc</a> &#8211; Abstract interface</li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/db_mysql.phps'>db_mysql.inc</a> &#8211; MySQL interface</li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/db_mssql.phps'>db_mssql.inc</a> &#8211; MSSQL interface</li>
</ul>
<p>If this article was usable or otherwise helpful for you, tell a friend or put a link back from your own website/blog.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2008/08/01/generic-object-oriented-sql-interface-for-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

