<?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>myplace.dk &#187; english</title>
	<atom:link href="http://myplace.dk/tag/english/feed/" rel="self" type="application/rss+xml" />
	<link>http://myplace.dk</link>
	<description></description>
	<lastBuildDate>Fri, 30 Sep 2011 12:21:00 +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>Apple hates developers</title>
		<link>http://myplace.dk/2011/02/17/apple-hates-developers/</link>
		<comments>http://myplace.dk/2011/02/17/apple-hates-developers/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 16:03:51 +0000</pubDate>
		<dc:creator>Niels</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://myplace.dk/?p=404</guid>
		<description><![CDATA[<p>My employer will soon release a smartphone app (iPhone and Android), for the first time.  Actually we will release several apps for several customers.  These customers pay my employer to take care of all the technical stuff, so we release the apps in their names. And I got the task of registering developer accounts for [...]]]></description>
			<content:encoded><![CDATA[<p>My employer will soon release a smartphone app (iPhone and Android), for the first time.  Actually we will release several apps for several customers.  These customers pay my employer to take care of all the technical stuff, so we release the apps in their names. And I got the task of registering developer accounts for each customer. In stead of explaining how much work in is and how frustating that work is, I will give you an example of how Apple works.</p>
<p><span id="more-404"></span>I started registering over a week ago, and I just got my first rejection. I made a mistake in the registration. I spelled a named correctly, and now I am being punished for it. The contact at the customers company is called &#8220;Jens Elkjær&#8221;. Well actually he isn&#8217;t, but there is an &#8220;æ&#8221; in his name. I was previously adviced by a colleague that special characters are problematic, and I should avoid them. I just overlooked this one. Copying and pasting name, address email etc. for dozens of accounts numbs your brain, and I overlooked this single character. I also overlooked a couple in the addresses, but those could be changed later.</p>
<p>There was nothing to indicate any kind of error, until I reached a confirmation page. The name was displayed like this: &#8220;Jens Elk�r&#8221;. (The &#8220;æ&#8221; is replaced with the &#8220;<a href="http://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character">replacement character</a>&#8220;.) It was too late. I could not go back and change the name. I could submit the application now or I could rage a while and then submit it.</p>
<p>Today I got this email (anonymized, emphasis is mine):</p>
<blockquote><p><strong>From:</strong> eurodev@apple.com<br />
<strong>Date:</strong> 17-02-2011 10:13<br />
<strong>To:</strong> <em>XXXXX</em>@<em>XXXXX</em>.dk<strong><br />
</strong> <strong>Subject:</strong> Re: iOS Developer Program</p>
<hr />Please include the line below in follow-up emails for this request.</p>
<p>Follow-up:  <em>XXXXX</em></p>
<p>Re: iOS Developer Program</p>
<p>Dear Sir/Madam,</p>
<p>We are in the process of reviewing your iOS Developer Program enrollment information.</p>
<p>In reviewing your Company Enrollment application <em>XXXXX</em>, I have found the following information:</p>
<p>Enrollment Reference Number: <em>XXXXX</em><br />
Program: Standard Program<br />
Enrollment Type: Company/Organization<br />
Applicant Name: <strong>Jens ElkjÃ¦r</strong><br />
Email: <em>XXXXX</em>@<em>XXXXX</em>.dk</p>
<p>Please know that the applicant&#8217;s name does not appear correctly. I have withdrawn your Enrollment <em>XXXXX</em> and you can submit a new Enrollment Request. I would advise you not to use foreign characters, as they are not recognizable from our system.</p>
<p>Should you wish to enroll again for the Standard Program, <strong>please submit a new enrollment using a different Apple ID and email address</strong> than the ones used for your original enrollment. Before submitting your NEW Enrollment, please clear your browser&#8217;s cookies, cache and history, ensure that it is configured to accept all cookies, quit and restart your browser.</p>
<p>Once you have completed the new enrollment, please then contact us back with the NEW Enrollment ID so that we review the NEW application.</p>
<p>We hope that this information is useful to you. Please let us know if you have any questions regarding this information.</p>
<p>Best regards,</p>
<p><em>XXXXX</em> <em>XXXXX</em><br />
Apple Developer Support</p></blockquote>
<p>My list of criticisms is not short.</p>
<p>1. The danish special letters are part of the character set &#8220;ISO 8859-1&#8243; also known as &#8220;latin 1&#8243;. This character set was published in 1985, registered as at internet standard in 1992, and is the default character set in HTTP since <a href="http://tools.ietf.org/html/rfc1945#section-3.6.1">version 1.0</a> published in 1996. However, if international characters is important (such as if you are collecting names from all over the world), you should use the more modern character set UTF, which is rapidly becoming a standard replacing 8859-1. In short, Apple really should just support the danish special letters. It&#8217;s not hard, practically everybody else does. It has been many years since last time I saw a system that didn&#8217;t support them by default.</p>
<p>2. If the danish special letters is not supported, the website could easily have informed me of this. The primitive solution would be a simple text: &#8220;In english letters only.&#8221; But the professional way would be to validate the input. This is very easy to do. Very.</p>
<p>3. The confirmation page didn&#8217;t allow me to go back and change it.</p>
<p>4. So they don&#8217;t support &#8220;æ&#8221; but they accepted it anyway. And then I can&#8217;t just go into profile settings and change it. I can change address, phone-numer, email-address, company name&#8230; Anything but the name. If a person actually changes name (this happens quite often, typically when getting married), it cannot be changed in the Apple profile. This reminds me of a phonecompany that got my name wrong in the phonebook and couldn&#8217;t change me. They said I had to change phonecompany to correct my name. Of course I did. I don&#8217;t do business with amateurs if I have a choice.</p>
<p>5. So there&#8217;s &#8220;Ã¦&#8221; in the name and I can&#8217;t do anything about it. Will Apple do it for me? No. (BTW: &#8220;æ&#8221; will look like that when it is saved or transmitted as UTF-8 and read as 8859-1.)</p>
<p>6. So there&#8217;s &#8220;Ã¦&#8221; in the name and it&#8217;s not going to change. Apple just have to accept it. They don&#8217;t. They reject the application.</p>
<p>7. It&#8217; no use just applying again. I have to make a new profile, and THEN apply again.</p>
<p>8. The new profile can&#8217;t have the same id as the old one. So I can&#8217;t use the same id for the iOS app as for the Android app. This complicates managing alle these accounts for my customers.</p>
<p>9. The new profile can&#8217;t have the same email-address as the old one. <a href="http://www.gomonews.com/apple-developer-support-can-be-pretty-unsupportive/">Others have tried</a>, unsuccessfully. But that&#8217;s the correct one. That is the one the customer has. Of course the customer has other addresses, but none of those are right one. They have to create a new address, and make it forward everything. I need to tell this to a colleague. He will contact our contact person. He will contact their IT department. They will find a technician to do it. According to my experience there is a good chance it won&#8217;t work, and I need to start the chain again.</p>
<p>This is not a list of trouble I&#8217;ve had during the process so far. This just one single example from a long list of unnecessary problems. I find it very hard to believe that Apple is so incompetent. Maybe they are indifferent about the quality of their work? Nah, I&#8217;ve been told so many times by Apple-fans that quality is what Apple is all about.</p>
<p>No, it&#8217;s very simple: Apple hates developers. And I hate Apple.</p>
]]></content:encoded>
			<wfw:commentRss>http://myplace.dk/2011/02/17/apple-hates-developers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ubuntu Linux on ASRock Core 100HT</title>
		<link>http://myplace.dk/2010/12/27/linux-on-asrock-core-100ht/</link>
		<comments>http://myplace.dk/2010/12/27/linux-on-asrock-core-100ht/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 18:10:26 +0000</pubDate>
		<dc:creator>Niels</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://myplace.dk/?p=364</guid>
		<description><![CDATA[<p>I installed Ubuntu 10.10 (Maverick Meerkat) 32 bit on my ASRock Core 100HT, which I use as an &#8220;HTPC&#8221; (Home Theater PC) or &#8220;mediacenter&#8221;. For now I also use it as a NAS and a few other odd jobs. Everything I&#8217;ve tried so far worked out of the box, except infrared. I had to install [...]]]></description>
			<content:encoded><![CDATA[<p>I installed Ubuntu 10.10 (Maverick Meerkat) 32 bit on my ASRock Core 100HT, which I use as an &#8220;HTPC&#8221; (Home Theater PC) or &#8220;mediacenter&#8221;. For now I also use it as a NAS and a few other odd jobs. Everything I&#8217;ve tried so far worked out of the box, except infrared. I had to install the infrared driver in an inconvenient way, but it works too. This blog-post will mostly be about the remote.</p>
<p><span id="more-364"></span></p>
<h1 id="toc-what-i-have-tested">What I have tested</h1>
<p>The HTPC is connected to my TV by HDMI. It automatically chose HDMI output, and the right resolution for my TV (1360&#215;768). I didn&#8217;t have any audio, so I clicked my way into audio settings and changed the output to &#8220;HDMI Stereo&#8221;, and then it worked like I wanted it. I haven&#8217;t tried VGA, optical audio out</p>
<p>It&#8217;s networked by WIFI (802.11b), no problems there. I haven&#8217;t tried 802.11n or wired network.</p>
<p>Reading DVD&#8217;s works. I haven&#8217;t tried CD or burning anything.</p>
<p>Infrared works with the supplied MCE remote. It probably works with almost any infrared remote, with a bit of work. I haven&#8217;t tried that yet.<br />
My <a href="http://logitech.com/harmony">Logitech Harmony</a> (programmable universal remote) works fine with the HTPC. I simply autodetected the MCE remote with the Harmony.</p>
<p>I can play 1080p h264 movies.</p>
<p>USB 2 works, haven&#8217;t tried USB 3 yet.</p>
<p>Oh, and I can turn the device on with the IR-remote.</p>
<h1 id="toc-installing-the-infrared-driver">Installing the infrared driver</h1>
<p>ASRock has two Linux-downloads for the Core 100HT: Infrared driver for Ubuntu 10.4, and infrared driver for Ubuntu 10.10. The latter has a great manual, but there&#8217;s a lot of steps. The style in the manual is &#8220;click this, click that, type this, type that&#8221; etc., which I think is what most people want. I prefer a more terse syntax, with commands I can copy/paste to the terminal. Like this:</p>
<pre>sudo apt-get update
sudo apt-get install lirc lirc-modules-source

        Remote control configuration: None
        IR transmitter, if present: None

unzip -d /tmp/ "IR(10.10)2.6.35-22.zip"

Install one of these, ignore errors:
32 bit: sudo dpkg -i /tmp/Ubuntu\ 10.10/lirc-nct677x-1.1.0-ubuntu10.10-kernel2.6.35.deb
64 bit: sudo dpkg -i /tmp/Ubuntu\ 10.10/lirc-nct677x-x64-1.1.0-ubuntu10.10-kernel2.6.35.deb

Again, ignore errors:
sudo dpkg -i /tmp/Ubuntu\ 10.10/lirc-nct677x-src-1.1.0-ubuntu10.10.deb 

cd /usr/src
sudo dkms remove -m lirc -v 0.8.7~pre3 --all
sudo dkms add -m lirc -v 0.8.7~pre3
sudo dkms build -m lirc -v 0.8.7~pre3
sudo dkms install -m lirc -v 0.8.7~pre3 --force
sudo dpkg-reconfigure lirc

        Remote control configuration: Nuvoton Transceivers/Remotes
        IR transmitter, if present: None</pre>
<pre>Test by running the command "irw", and push some buttons on the remote. It should output the name of the buttons you press.</pre>
<h1 id="toc-using-the-remote">Using the remote</h1>
<p>After installing the driver and confirming that it works, the remote still didn&#8217;t do anything. I haven&#8217;t studied how this is supposed to work, but after playing around a bit I&#8217;ve learning that it&#8217;s probably something like this: LIRC (Linux Infrared Remote Control) receives the infrared signal, recognizes which remote it is and which button it is, and then tells about it to anyone who wants to listen. In my case, nobody.</p>
<p>I started XBMC and made sure it knows I have a remote that doesn&#8217;t send keyboard signals, and then it worked.</p>
<p>For now, I only want one more feature: Starting XBMC with the remote.</p>
<p><em>Warning: I tried to configure LIRC with an easy GUI. I don&#8217;t remember the name, but it didn&#8217;t work and it destroyed what already worked. I removed the software and reinstalled the driver. Please comment or email me if you have anything to add here.</em></p>
<p>I created the file &#8220;~/.lircrc&#8221; with this content:</p>
<pre>begin
    prog = irexec
    button = Home
    config = ps -e | grep xbmc &gt;/dev/null || xbmc&amp;
    repeat = 0
end</pre>
<p>In english, if I understand correct: &#8220;If the program irexec wants to know that Home (big green button with the ) is pressed, give it the string from the &#8216;config&#8217;-line.&#8221;</p>
<p>irexec then executes the command, which is &#8220;if xbmc is not running, run it&#8221;.</p>
<p>The final step is to start irexec when the machine is booting, I simply did that with the Ubuntu &#8220;Startup Applications&#8221; function.</p>
<h1 id="toc-lirc-names-of-the-remote-buttons">LIRC names of the remote buttons</h1>
<p>&#8230;as defined by the driver from ASRocks website.</p>
<table border="0">
<tbody>
<tr>
<td>Aspect</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Power</td>
</tr>
<tr>
<td>RecTV</td>
<td></td>
<td>Guide</td>
<td></td>
<td>LiveTV</td>
<td></td>
<td>DVD</td>
</tr>
<tr>
<td></td>
<td>Record</td>
<td></td>
<td></td>
<td></td>
<td>Stop</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Play</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Rewind</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Forward</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Pause</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>Replay</td>
<td></td>
<td></td>
<td></td>
<td>Skip</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Up</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>Left</td>
<td></td>
<td>OK</td>
<td></td>
<td>Right</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Down</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>VolUp</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>ChanUp</td>
</tr>
<tr>
<td>VolDown</td>
<td></td>
<td></td>
<td>Home</td>
<td></td>
<td></td>
<td>ChanDown</td>
</tr>
<tr>
<td>Back</td>
<td></td>
<td></td>
<td>Mute</td>
<td></td>
<td></td>
<td>More</td>
</tr>
<tr>
<td>One</td>
<td></td>
<td></td>
<td>Two</td>
<td></td>
<td></td>
<td>Three</td>
</tr>
<tr>
<td>Four</td>
<td></td>
<td></td>
<td>Five</td>
<td></td>
<td></td>
<td>Six</td>
</tr>
<tr>
<td>Seven</td>
<td></td>
<td></td>
<td>Eight</td>
<td></td>
<td></td>
<td>Nine</td>
</tr>
<tr>
<td>Star</td>
<td></td>
<td></td>
<td>Zero</td>
<td></td>
<td></td>
<td>Hash</td>
</tr>
<tr>
<td></td>
<td>Clear</td>
<td></td>
<td></td>
<td></td>
<td>Enter</td>
<td></td>
</tr>
<tr>
<td>Radio</td>
<td></td>
<td>Music</td>
<td></td>
<td>Pictures</td>
<td></td>
<td>Videos</td>
</tr>
<tr>
<td>Red</td>
<td></td>
<td>Green</td>
<td></td>
<td>Yellow</td>
<td></td>
<td>Blue</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Teletext</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<h1 id="toc-harmony-names-of-the-remote-buttons" style="font-size: 2em;">Harmony names of the remote buttons</h1>
<p>&#8230;in the configution it autodetected. You could make your own configuration with the LIRC-names or whatever you choose. There is a few duplicates and a few buttons not on the original remote.</p>
<table border="0">
<tbody>
<tr>
<td>Aspect</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>PowerToggle</td>
</tr>
<tr>
<td colspan="2">RecordedTV</td>
<td>Guide</td>
<td></td>
<td>LiveTV</td>
<td></td>
<td>DVDMenu</td>
</tr>
<tr>
<td></td>
<td colspan="2">Rec/Record</td>
<td></td>
<td></td>
<td>Stop</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Play</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td colspan="2">Rew/Rewind</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Fwd/FastForward</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Pause</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>Replay</td>
<td></td>
<td></td>
<td></td>
<td>Skip</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Up</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>Left</td>
<td></td>
<td colspan="2">OK/ChannelPrev</td>
<td>Right</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>Down</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>VolUp</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>ChannelUp</td>
</tr>
<tr>
<td colspan="2">VolDown</td>
<td></td>
<td colspan="3">Media/GreenButton</td>
<td>ChannelDown</td>
</tr>
<tr>
<td>Back</td>
<td></td>
<td></td>
<td>Mute</td>
<td></td>
<td></td>
<td>Info</td>
</tr>
<tr>
<td>1</td>
<td></td>
<td></td>
<td>2</td>
<td></td>
<td></td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td></td>
<td></td>
<td>5</td>
<td></td>
<td></td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td></td>
<td></td>
<td>8</td>
<td></td>
<td></td>
<td>9</td>
</tr>
<tr>
<td>*</td>
<td></td>
<td></td>
<td>0</td>
<td></td>
<td></td>
<td>#</td>
</tr>
<tr>
<td></td>
<td>Clear</td>
<td></td>
<td></td>
<td></td>
<td>Enter</td>
<td></td>
</tr>
<tr>
<td colspan="2">MyRadio</td>
<td colspan="2">MyMusic</td>
<td colspan="2">MyPictures</td>
<td>MyVideos</td>
</tr>
<tr>
<td>Red</td>
<td></td>
<td>Green</td>
<td></td>
<td colspan="2">Yellow</td>
<td>Blue</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td colspan="2">Teletext</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p>Additional commands, not on the original remote:</p>
<table border="0">
<tbody>
<tr>
<th>Harmony</th>
<th>LIRC</th>
</tr>
<tr>
<td>Audio</td>
<td>BB3</td>
</tr>
<tr>
<td>MyTV</td>
<td>TV</td>
</tr>
<tr>
<td>Subtitle</td>
<td>Not detected</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://myplace.dk/2010/12/27/linux-on-asrock-core-100ht/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Layers pattern for security</title>
		<link>http://myplace.dk/2009/11/26/layers-pattern-for-security/</link>
		<comments>http://myplace.dk/2009/11/26/layers-pattern-for-security/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 19:20:59 +0000</pubDate>
		<dc:creator>Niels</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[development tips]]></category>
		<category><![CDATA[english]]></category>

		<guid isPermaLink="false">http://myplace.dk/?p=222</guid>
		<description><![CDATA[<p>Pay attention, web developers! This is where too many of you screw up. Way too often a few characters behave strange and a quick fix is made, in stead of taking a step back to look at the real problem.</p>
<p>This is fine for the beginning amateur, but professionals should always get this right.</p>
What happens when [...]]]></description>
			<content:encoded><![CDATA[<p>Pay attention, web developers! This is where too many of you screw up. Way too often a few characters behave strange and a quick fix is made, in stead of taking a step back to look at the real problem.</p>
<p>This is fine for the beginning amateur, but professionals should <em>always</em> get this right.</p>
<h3 id="toc-what-happens-when-you-dont-do-this">What happens when you don&#8217;t do this</h3>
<p>If you are very lucky, you will have a lot of extra work and more complicated code. If you are less lucky strange things will happen on your website. Maybe &#8220;2&lt;3&#8243; is displayed as &#8220;23&#8243; or &#8220;don&#8217;t&#8221; is displayed as &#8220;don\&#8217;t&#8221;. Maybe it&#8217;s even saved like that in the database, which just makes it much harder to fix.</p>
<p>But worst case is a gaping security hole. Do one little thing wrong, and you can get serious security vulnerabilities like <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">XSS</a> and <a href="http://en.wikipedia.org/wiki/Sql_injection">SQL injection</a>.<br />
<span id="more-222"></span></p>
<h3 id="toc-what-is-layers">What is layers</h3>
<p><img class="alignright size-full wp-image-244" src="http://myplace.dk/wordpress/wp-content/uploads/2009/11/layers.png" alt="" width="192" height="320" />Any non-static website has layers. It&#8217;s just a question of how many, and if you are using them correctly. To make a simple blog you need at least three:</p>
<ol>
<li>The presentation (HTML, CSS etc.)</li>
<li>The application (maybe written in PHP)</li>
<li>A database (like MySQL)</li>
</ol>
<p>A layer should only know about what is above it, and what is below it. In this extremely simple scenario, the HTML knows about the PHP (filenames for the links etc.), but should never know about the database (table names and certainly never ever login information). And SQL statements (or even snippets) should NEVER get more than one layer away from database layers.</p>
<p>Usually there is many more layers in the application part to simplify things. Maybe there is a layer for translating pretty urls to actual PHP filenames. And there should be a &#8220;database abstraction layer&#8221;, which makes database access look the same no matter which database you use.</p>
<p>En example of how even abstraction layers that hardly adds any features are useful: It adds flexibility. With a good database abstraction layer, you can change the entire database (maybe from MySQL to PostGreSQL) without changing your actual application. You just edit the abstraction layer, which sits between the application and the database. The advantages becomes clearer further down.</p>
<p>In this article I will only talk about a few layers, enough for most simple web-projects. But the idea is the same with any amount of layers. I will use:</p>
<ol>
<li>The presentation (HTML, CSS etc.)</li>
<li>The application (maybe written in PHP)</li>
<li>Database Abstraction Layer</li>
<li>A database (like MySQL)</li>
</ol>
<h3 id="toc-my-recommended-solution">My recommended solution</h3>
<p>When the user performs an action (like a search), data from the user (for example search terms) travels through the layers, probably all the way to the bottom, and then results (for example search results) travels all the way back up, possibly including the original data.</p>
<p>Here comes the important part:</p>
<blockquote><p><strong>When data moves from one layer to the other, make sure all necessary conversions are done correctly, and preferrably automatically.</strong></p></blockquote>
<p>When data moves from the browser to your application, you will <a href="http://php.net/manual/en/security.magicquotes.php">probably</a> get it as normal plaintext. So far so good.</p>
<p>Then you transfer the data to the database. The database interpretes certain characters specially, like percent, underscore and apostrophe. The amateur is tempted to fix this with search-and-replace, and will often do this the wrong place so that the fix ends up in places outside the database.</p>
<p>This is a task for the database abstraction layer. My favorite way is <a href="http://en.wikipedia.org/wiki/SQL_injection#Parameterized_statements">parameterized statements</a>. A simple example:</p>
<pre class="codeblock"><code>result = db.getAll("SELECT id, name FROM students WHERE name=?", name);</code></pre>
<p>The questionmarks gets replaced with the parameters after the query.</p>
<p>The variable db containts an object from the database abstraction layer. Which you may have made yourself, maybe one provided by the system you use (PHP has <a href="http://php.net/manual/en/refs.database.php">several</a>), or as I prefer &#8211; a simply one build on top of something good someone else has made.</p>
<p>The results from the database should be in plaintext. No special handling of any characters, special to SQL, HTML or any other technology. Any layer should only know about the layer above and below, and the HTML and browser is far above the dabase and database abstraction layer(s).</p>
<p>Now you have the input and the result from the database, and it&#8217;s time to display them. But data is sent to the browser in HTML format, not plaintext. So transferring data from the application to the presentation layer, means translating from plaintext to HTML.</p>
<p>There are tons of ways to do that, depending on the framwork you are using. Here&#8217;s a very primitive way of doing it in PHP:</p>
<pre class="codeblock"><code>&lt;p&gt;
Search terms: &lt;?=toHTML($terms)?&gt;&lt;br /&gt;
Results: &lt;?=$result_count?&gt;&lt;br /&gt;&lt;!-- No need to escape, this is numeric --&gt;
&lt;/p&gt; </code></pre>
<p>In this primitive example, you need to remember &#8220;toHTML()&#8221; every time you print out text, which is a weak spot. In some systems it takes extra code to NOT encode it in HTML.</p>
<p>The toHTML()-function will replace &lt; with &amp;lt; etc. Maybe it inserts &lt;br /&gt; at the end of lines, but then you should check that the search terms doesn&#8217;t have more than one line. Maybe you should check for that anyway. If it&#8217;s a comment for all users to see, maybe you want some extra checks here. like collapsing 500 newlines in a to two. Maybe like this: &lt;%=toHTML(sanitize($terms))%&gt;</p>
<p>But why not sanitize it while getting it from the browser, so we get sane data? Well, it is a good time to check for very bad input, like binary data. But I like to have the original input in the database. That is always a good thing, for example if you change something in how you display your data. Maybe you want to change how you handle newline characters. Maybe you have improved your sanitizing method.<br />
With this method you just change your code, and you&#8217;re done. If you change the data before you put it in your database, you will need to change your old data. This can be very complicated, sometimes impossible. (For example if a bug removes data.)</p>
<h3 id="toc-summary">Summary</h3>
<ul>
<li>Know that you have layers, and which ones</li>
<li>Insert abstraction layers when they add value</li>
<li>A layer can only know about the layer directly above or below</li>
<li>When data moves from one layer to another, convert it accordingly</li>
<li>Do the conversion in a common place so you only have the code once, and maybe even in a way so you don&#8217;t need to remember to do it every time</li>
</ul>
<p>Doing this the right way makes simple code, pretty results and solves most security issues.</p>
]]></content:encoded>
			<wfw:commentRss>http://myplace.dk/2009/11/26/layers-pattern-for-security/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spiders on caffeine</title>
		<link>http://myplace.dk/2009/10/12/spiders-on-caffeine/</link>
		<comments>http://myplace.dk/2009/10/12/spiders-on-caffeine/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 11:22:31 +0000</pubDate>
		<dc:creator>Niels</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[fun facts]]></category>

		<guid isPermaLink="false">http://myplace.dk/?p=70</guid>
		<description><![CDATA[<p>You may have seen these images before, but I think they are much more interesting with a bit of explanation of the drugs.</p>




<p><p class="wp-caption-text">Normal</p>
This is a typical spider web. This is the goal, what you should compare the other images with.







<p><p class="wp-caption-text">Marijuana</p>
This spider was given marijuana (or &#8220;hash&#8221;) before making the web. Marijuana makes you [...]]]></description>
			<content:encoded><![CDATA[<p>You may have seen these images before, but I think they are much more interesting with a bit of explanation of the drugs.</p>
<table border="0">
<tbody>
<tr>
<td>
<p><div id="attachment_75" class="wp-caption alignleft" style="width: 126px"><img class="size-full wp-image-75 " title="normal" src="http://myplace.dk/wordpress/wp-content/uploads/2009/10/normal.jpg" alt="Normal" width="116" height="126" /><p class="wp-caption-text">Normal</p></div></td>
<td>This is a typical spider web. This is the goal, what you should compare the other images with.</td>
</tr>
</tbody>
</table>
<table border="0">
<tbody>
<tr>
<td>
<p><div id="attachment_74" class="wp-caption alignleft" style="width: 126px"><img class="size-full wp-image-74" title="marijuana" src="http://myplace.dk/wordpress/wp-content/uploads/2009/10/marijuana.jpg" alt="Marijuana" width="116" height="126" /><p class="wp-caption-text">Marijuana</p></div></td>
<td>This spider was given marijuana (or &#8220;hash&#8221;) before making the web. Marijuana makes you slow and makes it hard to concentrate. The spider started just fine, but then it got lazy.</td>
</tr>
</tbody>
</table>
<p><span id="more-70"></span></p>
<table border="0">
<tbody>
<tr>
<td>
<p><div id="attachment_71" class="wp-caption alignleft" style="width: 126px"><img class="size-full wp-image-71" title="benzedrine" src="http://myplace.dk/wordpress/wp-content/uploads/2009/10/benzedrine.jpg" alt="Benzedrine" width="116" height="126" /><p class="wp-caption-text">Benzedrine</p></div></td>
<td>Benzedrine made this spider active. So active, it forgot to plan anything.</td>
</tr>
</tbody>
</table>
<table border="0">
<tbody>
<tr>
<td>
<p><div id="attachment_73" class="wp-caption alignleft" style="width: 126px"><img class="size-full wp-image-73" title="chloral-hydrate" src="http://myplace.dk/wordpress/wp-content/uploads/2009/10/chloral-hydrate.jpg" alt="Chloral Hydrate" width="116" height="126" /><p class="wp-caption-text">Chloral Hydrate</p></div></td>
<td>Chloral hydrate is (among other things) a sedative. This poor spider started nicely, and probably fell asleep.</td>
</tr>
</tbody>
</table>
<table border="0">
<tbody>
<tr>
<td>
<p><div id="attachment_72" class="wp-caption alignleft" style="width: 126px"><img class="size-full wp-image-72" title="caffeine" src="http://myplace.dk/wordpress/wp-content/uploads/2009/10/caffeine.jpg" alt="Caffeine" width="116" height="126" /><p class="wp-caption-text">Caffeine</p></div></td>
<td>This is the interesting part. This is what happens when you get too much caffeine. No planning, no system, worthless. Like the sedated spider, it never got to the part with the spirals.</p>
<p>Now let me ask all you software developers like me out there: Do you really want to create software, with large amounts of caffeine in your body?</p>
<p>And everybody else: Do you want to use software created like this?</td>
</tr>
</tbody>
</table>
<p>This experiment was invented in 1948, but these images are from a similar experiment performed by NASA in 1995.</p>
<p>Source: <a href="http://en.wikipedia.org/wiki/Effect_of_psychoactive_drugs_on_animals">Wikipedia - Effect of psychoactive drugs on animals</a></p>
<p>And by the way:</p>
<blockquote><p>In large amounts, and especially over extended periods of time, caffeine can lead to a condition known as caffeinism. Caffeinism usually combines caffeine dependency with a wide range of unpleasant physical and mental conditions including <em>nervousness, irritability, anxiety, tremulousness, muscle twitching (hyperreflexia), insomnia, headaches, respiratory alkalosis, and heart palpitations</em>.</p>
<p style="text-align: right; "><a href="http://en.wikipedia.org/wiki/Caffeine#Overuse">Wikipedia &#8211; Caffeine</a></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://myplace.dk/2009/10/12/spiders-on-caffeine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fresh content: How I have modified Wordpress so far.</title>
		<link>http://myplace.dk/2008/05/03/fresh-content-how-i-have-modified-wordpress-so-far/</link>
		<comments>http://myplace.dk/2008/05/03/fresh-content-how-i-have-modified-wordpress-so-far/#comments</comments>
		<pubDate>Sat, 03 May 2008 14:35:59 +0000</pubDate>
		<dc:creator>Niels</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[myplace.dk]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://myplace.dk/?p=18</guid>
		<description><![CDATA[<p>So, for the first time in too many years, and since I changed my homepage into a blog, there&#8217;s new content! It&#8217;s a boring article about how I have modified Wordpress so far, to make it behave the way I want. I have a feeling this one will be updated sooner or later.</p>
]]></description>
			<content:encoded><![CDATA[<p>So, for the first time in too many years, and since I changed my homepage into a blog, there&#8217;s new content! It&#8217;s a boring article about <a href="/articles/my-wordpress-modifications/">how I have modified Wordpress</a> so far, to make it behave the way I want. I have a feeling this one will be updated sooner or later.</p>
]]></content:encoded>
			<wfw:commentRss>http://myplace.dk/2008/05/03/fresh-content-how-i-have-modified-wordpress-so-far/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New homepage / Ny hjemmeside</title>
		<link>http://myplace.dk/2008/05/02/new-homepage-ny-hjemmeside/</link>
		<comments>http://myplace.dk/2008/05/02/new-homepage-ny-hjemmeside/#comments</comments>
		<pubDate>Fri, 02 May 2008 06:02:23 +0000</pubDate>
		<dc:creator>Niels</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[dansk]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[myplace.dk]]></category>

		<guid isPermaLink="false">http://myplace.dk/?p=5</guid>
		<description><![CDATA[<p>Once again, it&#8217;s time for a new homepage. I will import everything still relevant from the old homepage, but some pages will die.</p>
<p>Så er det endnu engang tid til en ny hjemmeside. Alt hvad der stadig er aktuelt fra den gamle vil blive flyttet, men nogle sider forsvinder.</p>
]]></description>
			<content:encoded><![CDATA[<p><strong>Once again, it&#8217;s time for a new homepage.</strong> I will import everything still relevant from the old homepage, but some pages will die.</p>
<p><strong>Så er det endnu engang tid til en ny hjemmeside. </strong>Alt hvad der stadig er aktuelt fra den gamle vil blive flyttet, men nogle sider forsvinder.</p>
]]></content:encoded>
			<wfw:commentRss>http://myplace.dk/2008/05/02/new-homepage-ny-hjemmeside/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

