<?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>Pontus Östlund &#187; PHP</title>
	<atom:link href="http://www.poppa.se/blog/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.poppa.se/blog</link>
	<description>My blog about web development and such</description>
	<lastBuildDate>Mon, 16 Jan 2012 00:38:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Merging associative arrays in PHP</title>
		<link>http://www.poppa.se/blog/merging-associative-arrays-in-php/</link>
		<comments>http://www.poppa.se/blog/merging-associative-arrays-in-php/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 22:16:50 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Pike]]></category>
		<category><![CDATA[Serendipity]]></category>

		<guid isPermaLink="false">/blog/?p=254</guid>
		<description><![CDATA[It&#8217;s nice when serendipity is your friend! I was porting my Bitly class from Pike to PHP &#8211; I know there&#8217;s probably a hundred PHP classes already out there, but mine is better coded   &#8211; and noted by accident that I had used some Pike syntax in my PHP class but it was [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s nice when <a href="http://en.wikipedia.org/wiki/Serendipity">serendipity</a> is your friend! I was porting my <a href="http://bit.ly/">Bitly</a> class from <a href="http://pike.ida.liu.se">Pike</a> to <a href="http://php.net">PHP</a> &#8211; I know there&#8217;s probably a hundred PHP classes already out there, but mine is better coded <img src='http://www.poppa.se/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  &#8211; and noted by accident that I had used some Pike syntax in my PHP class but it was working anyway. So what was I doing? In Pike there&#8217;s separate data type for associative arrays called <code>mapping</code>. In Pike, in general, when merging two objects you just join them with a <code>+</code> sign. Thus merging two mappings you do like</p>
<pre><code lang="pike">
mapping m1 = ([ "key1" : "Value 1", "key2" : "Value 2" ]);
mapping m2 = ([ "key3" : "Value 3" ]);

write("My mapping: %O\n", m1 + m2);
//> My mapping: ([ /* 3 elements */
//>   "key1": "Value 1",
//>   "key2": "Value 2",
//>   "key3": "Value 3"
//> ])</code></pre>
<p>And I noted that I had done the same thing in PHP and the result was perfectly valid:</p>
<pre><code lang="php">
$a1 = array("key1" => "Value 1", "key2" => "Value 2");
$a2 = array("key3" => "Value 3");

echo "My mapping: ";
print_r($a1 + $a2);
//> My mapping: Array
//> (
//>     [key1] => Value 1
//>     [key2] => Value 2
//>     [key3] => Value 3
//> )</code></pre>
<p>This method doesn&#8217;t work on flat array though so there you&#8217;ll still have to use <code><a href="http://php.net/array_merge">array_merge()</a></code>, but pretty nice anyway.</p>
<p>And oh, the PHP Bitly class will be part of the new <a href="/blog/projects/#plib">PLib</a> release once done!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/merging-associative-arrays-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PLib, the Poppa PHP Library</title>
		<link>http://www.poppa.se/blog/plib-the-poppa-php-library/</link>
		<comments>http://www.poppa.se/blog/plib-the-poppa-php-library/#comments</comments>
		<pubDate>Thu, 14 Feb 2008 18:13:19 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PLib]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=146</guid>
		<description><![CDATA[Other than working my ass off at work I just lately took a real approach on my secretly sleeping project PLib. PLib is my own PHP framework with functions and classes to ease my everyday PHP programming.
To give you an idea of what PLib is all about let me give you an example:
]]></description>
			<content:encoded><![CDATA[<p>Other than working my ass off at work I just lately took a real approach on my secretly sleeping project <a href='http://plib.poppa.se'>PLib</a>. PLib is my own PHP framework with functions and classes to ease my everyday PHP programming.</p>
<p>To give you an idea of what PLib is all about let me give you an example:</p>
<pre><code lang='php'><?php
require_once '/path/to/PLib.php';

//! Lets create thumbnails of all JPEG images in a directory
PLib::Import('Graphics.Image');

//! The Dir class is included in Image so I don't explicitly need to
//! include it
$dir = new Dir('/path/to/jpegs/');
$mw  = 150; // Max width of thumb
$mh  = 90;  // Max height of thumb

while ($file = $dir->Emit('*.jpg')) {
  $img = new Image($file->path);
  $img = $img->Copy($file->path.'/thumb-'.$file->name)->Scale($mw, $mh);
  wbr($img->Path()); // The full path to the thumbnail
}
?></code></pre>
<p>Rather easy I think!</p>
<h2>AutoDoc</h2>
<p>Another cool feature (if I may say so) is the auto documentation. If you quickly want a list of all available classes and functions just type <code>PLib::Info()</code> and you will get the list. Each class and function is then clickable and will lead you to the documentation for which ever class or function you clicked.</p>
<p>If you want the documentation for a specific class just type <code>PLib::Info()</code> and there you have the documentation.</p>
<p>The third way to use the autodoc is to pass an instance of a class as argument like <code>PLib::Info()</code>.</p>
<p>And if you wan&#8217;t a full documentation site just type <code>PLib::Info()</code> and you will get the same documentation as available at the <a href='http://plib.poppa.se'>PLib site</a>.</p>
<h2>The site</h2>
<p>Anyway, PLib has its site of it&#8217;s own where anyone curious can download the latest version of PLib and find out more about the project.</p>
<p><a href='http://plib.poppa.se'><strong>plib.poppa.se</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/plib-the-poppa-php-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP documentation browser</title>
		<link>http://www.poppa.se/blog/php-documentation-browser/</link>
		<comments>http://www.poppa.se/blog/php-documentation-browser/#comments</comments>
		<pubDate>Fri, 20 Jul 2007 20:41:36 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Share]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=135</guid>
		<description><![CDATA[Even though I have my vacation right now I need to hack some 
What I have done is a PHP documentation browser, I simply call it PHPDoc Browser, for GNU/Linux to read the PHP documentation locally on the computer (it&#8217;s a little bit like CHM for Windows). This little app isn&#8217;t that necessary but I [...]]]></description>
			<content:encoded><![CDATA[<p>Even though I have my vacation right now I need to hack some <img src='http://www.poppa.se/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
What I have done is a PHP documentation browser, I simply call it <em>PHPDoc Browser</em>, for GNU/Linux to read the PHP documentation locally on the computer (it&#8217;s a little bit like <a href='http://en.wikipedia.org/wiki/Microsoft_Compiled_HTML_Help'>CHM</a> for Windows). This little app isn&#8217;t that necessary but I thought it was a great thing for learning new stuff: The application is written in <a href='http://www.mono-project.com'>Mono</a>/C# and uses <a href='http://www.sqlite.org/'>SQLite</a> for storing the search index.</p>
<h2>Difference from CHM</h2>
<p>Although there&#8217;s a CHM equivalent, <a href='http://xchm.sourceforge.net/'>XCHM</a>, for Unix like systems I decided that my application serves a purpose: What I like about the PHP manual is that you can hit www.php.net/the_function in you browser and you will get the documentation for &#8220;the_function&#8221;. Of course I implemented the same functionality in <em>PHPDoc Browser</em>. You can also do a wild card search like &#8220;array_*&#8221; and you will get a list of all &#8220;array_*&#8221; functions. </p>
<p>I also implemented a free text search but that&#8217;s not &#8220;a real&#8221; FTS at the moment. FTS in SQLite in a little bit harder than in <a href='http://www.mysql.com'>MySQL</a> so while awaiting the next SQLite version the FTS is a bit of a hack. But you can quote the search to narrow it down <img src='http://www.poppa.se/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h2>What&#8217;s learned?</h2>
<p>Most of the unnecessary stuff I do I do to learn and the <em>PHPDoc Browser</em> is no exception. I learned how to use SQLite in Mono/C# and I also wrote a self contained installer in Bash, and Bash I havn&#8217;t really touch although I&#8217;ve been using GNU/Linux for 6-7 years! I found it quite fun writing the installer <img src='http://www.poppa.se/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Howto</h2>
<p>If you would like to try it out:</p>
<ol>
<li>Download the install script</li>
<li>Un-tar it (`tar zxvf phpdocbrowser-installer.tgz`)</li>
<li>Make sure the script is executable (`chmod +x phpdocbrowser-installer`)</li>
<li>Open a console and run the installer: <code>./phpdocbrowser-installer</code></li>
<li>Answer the questions and you&#8217;r ready to go.</li>
</ol>
<p>The script will create a directory, <code>./phpdocbrowser-installer</code>, in your home directory in wich you will find <code>./phpdocbrowser-installer</code>, <code>./phpdocbrowser-installer</code> and a directory, <code>./phpdocbrowser-installer</code>, with the PHP documentation. A &#8220;run script&#8221; will also be installed either in <code>./phpdocbrowser-installer</code> or in your home directory depending on how you answered the questions and if you agreed to create a desktop shortcut one will hopefully appear on your desktop (havn&#8217;t tested this on KDE but it should work fine in Gnome).</p>
<p>To run the application hit the desktop shortcut, if one was created, or invoke <code>./phpdocbrowser-installer</code> from a console. </p>
<p>If you wish to remove the <em>PHPDoc Browser</em> run the following from a console:<br />
<code>./phpdocbrowser-installer</code>.</p>
<p>And that&#8217;s that!</p>
<h2>Download</h2>
<p><a href='/blog/data/scripts/phpdocbrowser-installer.tgz'>PHPDoc Browser</a></p>
<h2>Screen shots</h2>
<p><a href="/blog/data/images/phpdoc-1.png"><img src="/blog/data/images/phpdoc-1.png/680" alt="PHPDoc"/></a></p>
<p><a href="/blog/data/images/phpdoc-2.png"><img src="/blog/data/images/phpdoc-2.png/680" alt="PHPDoc2"/></a></p>
<p><a href="/blog/data/images/phpdoc3.png"><img src="/blog/data/images/phpdoc3.png/680" alt="PHPDoc3"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/php-documentation-browser/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Syntaxer 2.0.2 released</title>
		<link>http://www.poppa.se/blog/syntaxer-202-released/</link>
		<comments>http://www.poppa.se/blog/syntaxer-202-released/#comments</comments>
		<pubDate>Sun, 25 Mar 2007 20:58:02 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Share]]></category>
		<category><![CDATA[Syntaxer]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=97</guid>
		<description><![CDATA[A few bugs was fixed in this release. I also noted a few new ones but that was mostly in the SyntaxMap class which gererates PHP arrays from the SyntaxMap files.
Changelog for this version

Fixed a bug where the end of strings (quotes) wasn&#8217;t found correctly in languages that has no escape character (like XSL, XML [...]]]></description>
			<content:encoded><![CDATA[<p>A few bugs was fixed in this release. I also noted a few new ones but that was mostly in the <code>SyntaxMap</code> class which gererates PHP arrays from the <code>SyntaxMap</code> files.</p>
<h2>Changelog for this version</h2>
<ul>
<li>Fixed a bug where the end of strings (quotes) wasn&#8217;t found correctly in languages that has no escape character (like XSL, XML and HTML).</li>
<li>Also changed the Syntaxer::AutoDetect() method to return the extension of a file if no alias was found. In this way we can pass a path to the method and use the result directly as argument to `Sytaxer::__construct()`</li>
</ul>
<pre><code lang='php'>$file = '/some/path/to/file.xsl';
$lang = Syntaxer::AutoDetect($file);
$stx  = new Syntaxer($lang);
$stx->Parse(file_get_contents($file));</code></pre>
<p>The Syntaxer can be read about and downloaded <a href='/projects/syntaxer/'>over here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/syntaxer-202-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Syntaxer 2.0.1 released</title>
		<link>http://www.poppa.se/blog/syntaxer-201-released/</link>
		<comments>http://www.poppa.se/blog/syntaxer-201-released/#comments</comments>
		<pubDate>Thu, 22 Mar 2007 23:08:08 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Syntaxer]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=90</guid>
		<description><![CDATA[I&#8217;ve released a new version of my generic syntax highlighting script Syntaxer. I fixed a potential bug where code generated on an operating system that only use \r to define a newline would be messed up (thank you jOOOL at PHPPortalen. Now I&#8217;ve bullet proofed (I hope) the way newlines are handled: I replace all [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released a new version of my generic syntax highlighting script <a href='/projects/syntaxer/'>Syntaxer</a>. I fixed a potential bug where code generated on an operating system that only use <code>\r</code> to define a newline would be messed up (thank you jOOOL at <a href='http://www.phpportalen.net'>PHPPortalen</a>. Now I&#8217;ve bullet proofed (I hope) the way newlines are handled: I replace all <code>\r\n</code> with <code>\r</code> and then replace all <code>\r</code> with <code>\n</code> which means that we always end up with a single <code>\n</code> as the newline character.</p>
<p><a href='/projects/syntaxer/'>The Syntaxer can be downloaded here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/syntaxer-201-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New syntax highlighting script</title>
		<link>http://www.poppa.se/blog/new-syntax-highlighting/</link>
		<comments>http://www.poppa.se/blog/new-syntax-highlighting/#comments</comments>
		<pubDate>Sun, 11 Mar 2007 20:59:34 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Syntaxer]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=82</guid>
		<description><![CDATA[A couple of years ago I wrote a generic syntax highlighting script. What I did was using the syntax files from Edit+ to determine how to parse a given language. All languages have different keywords, function names, delimiters and so on, and to know how to highlight a certain language you need to know these [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of years ago I wrote a generic syntax highlighting script. What I did was using the syntax files from <a href='http://www.editplus.com'>Edit+</a> to determine how to parse a given language. All languages have different keywords, function names, delimiters and so on, and to know how to highlight a certain language you need to know these things. The Edit+ <code>.stx</code> files describes all these things.</p>
<p>Since I have gotten a few years more of knowledge, and PHP5 has arrived, I though I should write a new version of it. I could reuse some of the code but alot was rewritten and redesigned totally. The script has two classes:</p>
<ol>
<li>One class to parse the Edit+ syntax files which gets converted into PHP files so that the syntax files doesn&#8217;t have to to be parsed for every request. If the given <code>.stx</code> file has a newer timestamp than the cached PHP file the PHP file will be regenerated. Alot of this code could be reused from the older version</li>
<li>The actual highlighting class. This class was almost entirely rewritten. Here I loop through every character of the code to highlight. When a keyword, delimiter or something else detectable is matched I grab that and searches forward to where the rule ends. In the older version I had a different approach where the code was splitted on newlines so I looped through line by line and for each line I looped throuh each charachter and did a similar match as in the new version.
<p>The new approach has some advantages:
<ol>
<li>There&#8217;s no need to duplicate the code wich means a lot less memory is used.</li>
<li>Fewer flags is needed since when I match a detectable rule I at once search for the end of the rule. This means that fewer <code>.stx</code> statements is needed wich speeds thing up alot.
<p>And foremost the code got much much cleaner!</li>
</ol>
</li>
</ol>
<p>Anyhow! There are a few minor bugs but the code is pretty usable (I have implemented it here in the blogging system). I added the scripts with documentation and a simple example on the server for anyone to download.</p>
<p>The <a href='/projects/syntaxer/'><strong>Syntaxer2</strong></a> can be found and downloaded over <a href='/projects/syntaxer/'>here</a>. Some bug fixes and more examples will be done in the very near future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/new-syntax-highlighting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Handy functions</title>
		<link>http://www.poppa.se/blog/handy-functions/</link>
		<comments>http://www.poppa.se/blog/handy-functions/#comments</comments>
		<pubDate>Mon, 19 Feb 2007 15:32:44 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=67</guid>
		<description><![CDATA[How many times don&#8217;t you write code like this: $var = isset($_GET['var']) ? $_GET['var'] : 'default';? I read an article in Linux Format (the paper issue) about the up and comming PHP6 (well, it will probably take some time until it gets stable but you can already download it) and some of its new functions [...]]]></description>
			<content:encoded><![CDATA[<p>How many times don&#8217;t you write code like this: <code>$var = isset($_GET['var']) ? $_GET['var'] : 'default';</code>? I read an article in <a href='http://www.linuxformat.co.uk/'>Linux Format</a> (the paper issue) about the up and comming PHP6 (well, it will probably take some time until it gets stable but you can already <a href='http://snaps.php.net/'>download it</a>) and some of its new functions and stuff and learned that there will be a function called <code>$var = isset($_GET['var']) ? $_GET['var'] : 'default';</code>. This function will work like this:<br />
<code>$var = isset($_GET['var']) ? $_GET['var'] : 'default';</code>. Pretty much nicer than the old way!</p>
<p>So I though: How hard can it be to implement the same kind of functionality in a user defined function. Well, it&#8217;s not hard att all, and here&#8217;s how simple it is:</p>
<pre><code lang='php'>/**
 * issetor
 *
 * @param mixed &#038;$what Assoc array key
 * @param mixed $else Default value
 * @return mixed
*/
function issetor(&#038;$what, $else)
{
  return isset($what) ? $what : $else;
}

#=================================================

$arr = array('key1' => 'value1', 'key2' => 1);

$var1 = issetor($arr['key1'], 'some value');
echo $var1; # will echo: value1

$var2 = issetor($arr['key5'], 'default for key 5');
# will echo: default for key 5
echo $var2;</code></pre>
<p>The only thing noticable here is that the first argument needs to be passed by reference or PHP will throw a warning (depending on the error/warning level set). </p>
<p>Of cource you can escape this issue all together just by choking PHP errors/warnings &#8211; <code>$var = isset($_GET['var']) ? $_GET['var'] : 'default';</code> &#8211; but that&#8217;s just pure ugly in my opinion.</p>
<p>Just by modifying the function above slightly we also get a nice way for writing:<br />
<code>$var = isset($_GET['var']) ? $_GET['var'] : 'default';</code></p>
<pre><code lang='php'>/**
 * isemptyor
 *
 * @param mixed &#038;$what Assoc array key
 * @param mixed $else
 * @return mixed
*/
function isemptyor(&#038;$what, $else)
{
  return empty($what) ? $else : $what;
}

#=================================================

$var1 = "Hello";
$var2 = "";

$myvar = isemptyor($var1, 'Default');
echo $myvar; # will echo: Hello

$myvar = isemptyor($var2, 'Default');
# will echo: Default
echo $myvar;</code></pre>
<p>And that&#8217;s it. I use them all the time!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/handy-functions/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Database abstraction layer</title>
		<link>http://www.poppa.se/blog/database-abstraction-layer/</link>
		<comments>http://www.poppa.se/blog/database-abstraction-layer/#comments</comments>
		<pubDate>Sat, 17 Feb 2007 18:35:32 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Share]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=63</guid>
		<description><![CDATA[I can&#8217;t remember the last time I made a web site that wasn&#8217;t hooked up to a database in one way or another! There&#8217;s nothing wrong with using the database functions that PHP provide directly but if you work with different types of databases &#8211; MySQL, Postgres, Oracle, SQL Server, SQLite and so on &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>I can&#8217;t remember the last time I made a web site that wasn&#8217;t hooked up to a database in one way or another! There&#8217;s nothing wrong with using the database functions that PHP provide directly but if you work with different types of databases &#8211; MySQL, Postgres, Oracle, SQL Server, SQLite and so on &#8211; you need to remeber how the functions for these databases work, in what order to pass arguments and what not. And maybe you write an application that teoretically could use an abritrary database and not MySQL that you developed the application for, and then it would be nice to use the same function calls no matter what database is being used.</p>
<p>This is where the database abstraction layer comes in handy. There already exist many of them so, again and as always, why bother writing another one? Well, it&#8217;s fun and you always learn new stuff and, for good and bad, third party <acronym title="Application Programming Interface">API</acronym>s tend to be packed with features that you never use so it get quite tedious learning the API.</p>
<p>So I wrote my own database abstraction layer that only contain the functionality I mostly use. If I need more functionaly it&#8217;s easy to implement. When I wrote the abstraction layer I tried to evolve my OOP (object orientated programming) skills (which isn&#8217;t too great) so that in it self was I goal.</p>
<p>The abstraction layer contains of two interfaces and two master classes: A connection interface and class and a result interface and class. To create a driver for a new type of database you inherit the master classes and implement the interfaces. This is how the skelleton looks like:</p>
<ul>
<li><strong>interface</strong> <em>IDB</em><br />
  The connection interface</li>
<li><strong>interface</strong> <em>IDBResult</em><br />
  The query result interface</li>
<li><strong>abstract class</strong> <em>DB</em><br />
  The connection master class</li>
<li><strong>abstract class</strong> <em>DBResult</em><br />
  The query result master class</li>
</ul>
<p>So a database driver should have two classes: One that extends the <code>DB</code> class and implements the <code>IDB</code> interface and one class that extends the <code>DBResult</code> class and implements the <code>IDBResult</code> interface.</p>
<h2>Example</h2>
<p>Here&#8217;s a simple example of usage:</p>
<pre><code lang='php'><?php
require_once 'Database.php';

//! MySQL example
try {
  $category = $_GET['category'];

  $db = DB::Create('MySQL', 'localhost', 'uname', 'pw0rd', 'mydatabase');
  $db->Connect();
  $res = $db->Query("SELECT * FROM table WHERE cat_id = '%d'", $category);

  if ($res->NumRows() > 0) {
    while ($row = $res->Fetch()) {
      echo "Title: " . $row->title . "<br/>";
    }
  }
}
//! Could be DBDriverNotFound, DBConnectionFail, DBNotFound, DBQueryFail
catch (Exception $e) {
  die("Error: " . $e->getMessage();
}

//! SQLite example
try {
  $category = $_GET['category'];

  $db = DB::Create('SQLite', 'mysqlitedb');
  $db->Connect();
  $res = $db->Query("SELECT * FROM table WHERE cat_id = '%d'", $category);

  if ($res->NumRows() > 0) {
    while ($row = $res->Fetch()) {
      echo "Title: " . $row->title . "<br/>";
    }
  }
}
//! Could be DBDriverNotFound, DBConnectionFail, DBNotFound, DBQueryFail
catch (Exception $e) {
  die("Error: " . $e->getMessage();
}
?></code></pre>
<p>As you can see here we&#8217;re using exactly the same code, except for the instantiation of the database object, wether we&#8217;re using MySQL or SQLite, and that&#8217;s the meaning of the database abstraction layer.</p>
<h2>Sources</h2>
<p>I currently have two implementations for MySQL and SQLite. The MySQL implementation is what I&#8217;m using for this blog and the SQLite implementation is not very well tested yet.</p>
<p>The classes are pretty well <a href='/blog/data/docs/db/'>documented</a> and the documentation is bundled in the package below.</p>
<p><a href='/blog/data/scripts/DB.tar.gz'>Database abstraction layer</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/database-abstraction-layer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get mimetype for a file</title>
		<link>http://www.poppa.se/blog/get-mimetype-for-a-file/</link>
		<comments>http://www.poppa.se/blog/get-mimetype-for-a-file/#comments</comments>
		<pubDate>Sat, 17 Feb 2007 15:19:38 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Share]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=58</guid>
		<description><![CDATA[Sometimes you need/want to find out what mimetype a particular file has. If you have access to the PEAR &#8220;Fileinfo Functions&#8221; you can use them, but if you don&#8217;t here&#8217;s a simple solution that might be helpful.
NOTE! This is not as reliable as the Fileinfo Functions but it works in most cases.
In most GNU/Linux systems [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you need/want to find out what mimetype a particular file has. If you have access to the <a href='http://pear.php.net'>PEAR</a> <a href='http://php.net/manual/en/function.finfo-open.php'>&#8220;Fileinfo Functions&#8221;</a> you can use them, but if you don&#8217;t here&#8217;s a simple solution that might be helpful.</p>
<p>NOTE! This is not as reliable as the Fileinfo Functions but it works in most cases.</p>
<p>In most GNU/Linux systems (if not all) there&#8217;s a file called <code>mime.types</code> (in <code>/etc/</code>) which is mapping of <code>mimetype -&gt; extension</code>. The file looks like this:</p>
<pre><code lang='none'>application/x-gnumeric                          gnumeric
application/x-go-sgf                            sgf
application/x-graphing-calculator               gcf
application/x-gtar                              gtar tgz taz
application/x-hdf                               hdf
application/x-httpd-php                         phtml pht php</code></pre>
<p>Quite obvious you could build an <code>array</code> from this file where the mimetype could be the <code>key</code> and the extension(s) the <code>value</code> as an <code>array</code>:</p>
<pre><code lang='php'>$_MIMETYPES = array(
  "mime/type" => array("ext1", "ext2", "ext3")
);</code></pre>
<p>When we&#8217;ve got this array populated we can easily look up a mimetype for an extention (and vice versa) by these two functions:</p>
<pre><code lang='php'>/**
 * Find mimetype for extension
 * @global array  $_MIMETYPES
 * @param  string $ext
 * @return string|bool
*/
function find_mimetype($ext)
{
  global $_MIMETYPES;
  foreach ($_MIMETYPES as $mime => $exts)
    if (in_array($ext, $exts))
      return $mime;

  return false;
}
/**
 * Get extension(s) for a given mimetype
 * @global array  $_MIMETYPES
 * @param  string $mimetype
 * @return array
*/
function findextensionfor_mimetype($mimetype)
{
  global $_MIMETYPES;
  return isset($MIMETYPES[$mimetype]) ? $MIMETYPES[$mimetype] : array();
}</code></pre>
<p>The script to convert the <code>mime.types</code> database into an array an auto generate the two functions above looks like this (note that this PHP script is intended to run as a command line (cli) script, thus the shebang (#!/usr/bin/php), since we don&#8217;t need to do this conversion run time but only once):</p>
<pre><code lang='php'>#!/usr/bin/php
<?php
/**
 * mimetyper.php
 * Turn the /etc/mime.types database into a PHP array
 * @author Pontus Ostlund <spam@poppa.se>
*/

//! Mimetype file
$mime_db  = '/etc/mime.types';

//! Resulting file for the PHP array
$php_file = 'mimetypes.php';

fileexists($mimedb) or die("No mimetype database ($mime_db) found\\n");
$lines = @file($mimedb) or die("Couldn't read $mimedb");
$fh    = @fopen($phpfile, "w+") or die("Couldn't create $phpfile");
$date  = strftime("%A %B %d %Y", time());

//! Write the PHP header to the file.
@fwrite($fh,
"<?php
/
 * Find mimetype for file extension
 * Generated $date by " . basename(<strong>FILE</strong>) . "
*/
$_MIMETYPES = array(n"
);

//! Loop through the lines array
while ($line = array_shift($lines))
{
  //! Match a comment or a blank line
  if ($line{0} == "#" || $line{0} == "\\n")
    continue;

  //! A line looks like:
  //!    mime.type              extention[ extension[ extension]]
  //! so lets grab the mimetype and extensions
  preg_match('/^(.?)\\s+(.?)$/', trim($line), $match);
  list(, $mime, $ext) = $match;

  if (empty($mime)) continue;

  //! This converts "ext ext ext" to "ext','ext','ext"
  $ext  = join("', '", explode(' ', $ext));

  //! And lets write the new array index to the file
  fwrite($fh, sprintf(
    "\\t'%s' => array('%s')%s\\n",
    $mime, $ext, (empty($lines) ? "" : ","))
  );
}

//! Close the array, add a nifty search function, and close the PHP block
//! and we're done!
fwrite($fh, ");
/**
 * Find mimetype for extension
 * @global array  $_MIMETYPES
 * @param  string $ext
 * @return string|bool
*/
function find_mimetype($ext)
{
  global $_MIMETYPES;
  foreach ($_MIMETYPES as $mime => $exts)
    if (in_array($ext, $exts))
      return $mime;

  return false;
}
/**
 * Get extension(s) for a given mimetype
 * @global array  $_MIMETYPES
 * @param  string $mimetype
 * @return array
*/
function findextensionfor_mimetype($mimetype)
{
  global $_MIMETYPES;
  return isset($MIMETYPES[$mimetype]) ? $MIMETYPES[$mimetype] : array();
}
?>");
fclose($fh);
?></code></pre>
<p>And this should result in a file called <code>mimetypes.php</code> that you just can <code>include</code> in you PHP scripts.</p>
<p><a href='/blog/data/scripts/mimetyper.tar.gz'>Download the scripts</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/get-mimetype-for-a-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

