<?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>Thijs Lensselink&#039;s Blog &#187; PHP</title>
	<atom:link href="http://lenss.nl/category/code/php-code/feed/" rel="self" type="application/rss+xml" />
	<link>http://lenss.nl</link>
	<description>Webdevelopment and stuff...</description>
	<lastBuildDate>Mon, 06 Feb 2012 20:37:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WordPress install compromised</title>
		<link>http://lenss.nl/2012/02/wordpress-install-compromised/</link>
		<comments>http://lenss.nl/2012/02/wordpress-install-compromised/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 20:37:10 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[/home]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[brazil]]></category>
		<category><![CDATA[hacked]]></category>
		<category><![CDATA[IRC bot]]></category>
		<category><![CDATA[pbot]]></category>
		<category><![CDATA[PHP bot]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1408</guid>
		<description><![CDATA[Last week i got an email from the Dutch NCSC (Nationaal Cyber Security Centrum). Apparently one of the nodes i manage for a customer was part of a botnet. There were no further demands. They just informed me about the issue. Damn cool! Being part of a botnet however. Not so cool! With the email [...]]]></description>
			<content:encoded><![CDATA[<p>Last week i got an email from the Dutch <a href="https://www.ncsc.nl/">NCSC</a> (Nationaal Cyber Security Centrum). Apparently one of the nodes i manage for a customer was part of a <a href="http://en.wikipedia.org/wiki/Botnet">botnet</a>. There were no further demands. They just informed me about the issue. Damn cool! Being part of a <a href="http://en.wikipedia.org/wiki/Botnet">botnet</a> however. Not so cool!</p>
<p>With the email came a small excerpt of a IRC channel log. I recognized the node. So SSH&#8217;ed into that specific node. And used <a href="http://linux.die.net/man/8/netstat">netstat</a> to check for any strange connections. A connection on port 20 to the C&#038;C node of the <a href="http://en.wikipedia.org/wiki/Botnet">botnet</a>. Thats not good.</p>
<blockquote><p>
$ netstat -an<br />
Active Internet connections (servers and established)<br />
Proto Recv-Q Send-Q Local Address           Foreign Address         State<br />
tcp        0      0 xxx.xxx.xxx.xx:20       69.162.80.62:20         ESTABLISHED
</p></blockquote>
<p>In the email from NCSC it was mentioned to look for files called <strong>wp-rss3.php</strong>. But a search for this file did not return any hits. Hmmm. And i still  had no idea which site it concerned. Since a couple were running on this particular node. The only thing certain. It&#8217;s <a href="http://wordpress.org">WordPress</a> related. So i started searching for recent <a href="http://wordpress.org">WordPress</a> compromises. And found a lot of hits on Google for the <a href="http://code.google.com/p/timthumb/">timThumb</a> and <a href="http://code.google.com/p/wps3slider/">wps3slider</a> plugins. But checking the log files for these plugins revealed nothing. And for some weird reason i just cleaned up the log partition a couple of days before. So not much luck there.</p>
<p>Some more Googling <a href="http://markmaunder.com/2011/08/01/zero-day-vulnerability-in-many-wordpress-themes/">told</a> me to do a search on the WordPress installs for the PHP function <a href="http://php.net/manual/en/function.base64-decode.php">base64_decode()</a>. O well. Lets give it a try. Some suspicious files did show up instantly.</p>
<blockquote><p>
$ find . -type f -exec grep -l &#8216;base64_decode&#8217; {} \;<br />
./[site]/www/public/wp-content/uploads/2010/06/wp-rss4.php (<a href="http://pastebin.com/rWD1Tfxk">source</a>)<br />
./[site]/www/public/wp-content/uploads/2011/05/alienee.php (<a href="http://pastebin.com/LwDaSFUK">source</a>)<br />
./[site]/www/public/wp-content/plugins/wps3slider/temp/34e3a3a74f6e2d0f236bdd3ba70c0c03.php (<a href="http://pastebin.com/fG6pDWC2">source</a>)<br />
./[site]/www/public/wp-content/plugins/wps3slider/temp/cf2cdb3ad3249b9692de07290f16f287.php (<a href="http://pastebin.com/pRSwG7Ud">encoded</a>) (<a href="http://pastebin.com/0qQ3Qeut">decoded</a>)<br />
./[site]/www/public/wp-content/plugins/wps3slider/temp/771b821c974131c67e34c83d8d2db725.php (<a href="http://pastebin.com/KUP8xBEQ">encoded</a>) (<a href="http://pastebin.com/Z77iMH1X">decoded</a>)<br />
./[site]/www/public/wp-content/plugins/wps3slider/temp/2b3753ea4769084f2e571737b695b03a.php (<a href="http://pastebin.com/RLgsTerk">encoded</a>) (<a href="http://pastebin.com/KwgqCS8R">decoded</a>)<br />
./[site]/www/public/wp-content/plugins/wps3slider/temp/7228f168d9692eafeafc54dbc3a1ab49.php (<a href="http://pastebin.com/HeE3PdnJ">encoded</a>) (<a href="http://pastebin.com/FzCqSfg6">decoded</a>)<br />
./[site]/www/public/wp-content/plugins/wps3slider/uploads/1.php (<a href="http://pastebin.com/YJ17ygSL">source</a>)<br />
/var/tmp/dc.pl (<a href="http://pastebin.com/YTusrVZk">encoded</a>) (<a href="http://pastebin.com/0WfqZt0R">decoded</a>)
</p></blockquote>
<p>Interesting. A quick look at the files showed that most of them were obfuscated. But not all. Two of the files were IRC bots written in <a href="http://www.php.net/">PHP</a>. At this moment i couldn&#8217;t resist but crack a little smile. But its also a reminder of how fragile the web really is. I quickly moved the files out of the way. And rebooted the machine. When it  came back online i monitored all connections for a while. But the connection to the C&#038;C node was not restored. So i informed NCSC. And went back to bed!</p>
<p>The WordPress admin should have kept the sites up to date. Lesson learned i hope! of course i could not resist to come back to it later. And so i did. I started by searching the Apache log files for <strong>wp-rss4.php</strong>. And found a couple of instances where this file was directly called. From a total of 4 different IP addresses.</p>
<blockquote><p>69.162.80.62</p></blockquote>
<p>This is the IP address of the C&#038;C server.</p>
<blockquote><p>
186.241.16.25<br />
201.8.237.18<br />
201.8.226.109
</p></blockquote>
<p>These IP addresses are all originating from Brasil. No further information is available at this moment. After that i started poking around the trojans / IRC bots found earlier. And as mentioned earlier. There were two bots installed on the server, One was running. The other wasn&#8217;t. This is configuration snippet from both bots.</p>
<p>The first bot. And the one i was informed about.</p>
<pre class="php" name="code">var $config = array("server"=>"antesedepois.servegame.com",^M
                     "port"=>20,^M
                     "pass"=>"depois",^M
                     "prefix"=>"depois",^M
                     "maxrand"=>8,^M
                     "chan"=>"#depoiswp",^M
                     "key"=>"",^M
                     "modes"=>"+iB-x",^M
                     "password"=>"depois",^M
                     "trigger"=>".",^M
                     "hostauth"=>"*" // * for any hostname^M</pre>
<p>And the second one</p>
<pre class="php" name="code">
var $config = array("server"=>"58.225.75.155",
                     "port"=>9999,
                     "pass"=>"",
                     "prefix"=>"animal",
                     "maxrand"=>8,
                     "chan"=>"#animal",
                     "key"=>"",
                     "modes"=>"+iB-x",
                     "password"=>"oishi",
                     "trigger"=>".",
                     "hostauth"=>"*!*@The.Black.Cat" // * for any hostname
                     );
</pre>
<p>Notice the <strong>^M</strong> characters at the end. Seems like somebody is using windows. So now we have login details for two C&#038;C servers. Why not take a look. </p>
<blockquote><p>
$ ircii<br />
/server antesedepois.servegame.com:20
</p></blockquote>
<p>Some standard IRC stuff</p>
<blockquote><p>*** Connecting to port 20 of server antesedepois.servegame.com<br />
*** Welcome to the Internet Relay Chat Network, root (from IRCPRIVATE)<br />
*** /etc/irc/script/local V0.5 for Debian finished. Welcome to ircII.<br />
*** If you have not already done so, please read the new user information with /HELP NEWUSER<br />
*** Your host is IRCPRIVATE, running version 1.2.1546<br />
*** This server was created jan 27 2012 at 06: 29:02 HodB (Serial # 00-00-00)<br />
*** channel modes available abdefghijklmnopqrstuvwxyzACEFIKLMOPT<br />
*** IRCX<br />
*** There are 6 users and 362 invisible on 1 servers<br />
*** 7 channels have been formed<br />
*** This server has 368 clients and 0 servers connected<br />
*** Current local users:  368  Max: 989<br />
*** Current global users:  368  Max: 989<br />
*** MOTD Not Present</p></blockquote>
<p>So let&#8217;s check the channels on this thing</p>
<blockquote><p>/list</p>
<p>*** Channel    Users  Topic<br />
*** #depoiswp  360    Entrou = Ban :)<br />
*** #grmteam   6<br />
*** #depoisSca 4      Entrou = Ban :)<br />
*** #depoisSca 4      Entrou = Ban :)<br />
*** #depoisVul 6      Entrou = Ban :)<br />
*** #rfi       3<br />
*** #sql       1  </p></blockquote>
<p>I entered all of the channels and waited for a while. But no activity took place. The only really interested channel is #depoiswp. This is the channel where all the bots connect. At the time i logged in there were about 360 of them  available. I immediately recognized the log excerpt send to me by the NCSC.</p>
<blockquote><p>*** Topic for #depoiswp: Entrou = Ban :)<br />
*** #depoiswp SYSTEM 1327945185<br />
(#depoiswp/#depoiswp) Entrou = Ban :)<br />
*** [A]depois88802849 (~depois48170648@68.233.238.XX) has joined channel #depoiswp<br />
*** #depoiswp 1327653297<br />
*** [A]depois13436992 (~depois92951214@212.227.114.XX) has joined channel #depoiswp<br />
*** [A]depois18833547 (~depois69088341@184.154.130.XX) has joined channel #depoiswp<br />
*** [A]depois80116634 (~depois13242297@213.251.189.XXX) has joined channel #depoiswp<br />
*** [A]depois31855907 (~depois23946193@82.85.28.XXX) has joined channel #depoiswp<br />
*** [A]depois25458508 (~depois64120008@87.106.214.XX) has joined channel #depoiswp<br />
*** [A]depois17803105 (~depois55004207@74.208.16.XX) has joined channel #depoiswp<br />
*** [A]depois96800217 (~depois89042073@174.121.216.XXX) has joined channel #depoiswp<br />
*** [A]depois17108432 (~depois51961332@209.68.1.XXX) has joined channel #depoiswp<br />
*** [A]depois95432403 (~depois13925479@209.68.1.XXX) has joined channel #depoiswp<br />
*** [A]depois96515275 (~depois10767943@195.74.38.XXX) has joined channel #depoiswp<br />
*** [A]depois73596561 (~depois90562179@69.89.31.XXX) has joined channel #depoiswp<br />
*** [A]depois85357227 (~depois31697723@64.191.115.XX) has joined channel #depoiswp<br />
*** [A]depois07993697 (~depois40240585@79.96.128.XX) has joined channel #depoiswp<br />
*** [A]depois97441253 (~depois19633359@193.189.74.XX) has joined channel #depoiswp<br />
*** [A]depois76843389 (~depois55419325@176.9.34.XXX) has joined channel #depoiswp<br />
*** [I]depois16679788 (~depois28004829@213.171.218.XXX) has joined channel #depoiswp<br />
*** [A]depois88178285 (~depois05296405@74.220.215.XXX) has joined channel #depoiswp</p></blockquote>
<blockquote><p>
<[A]depois16231776> [Attack Finalizado!]: 1749605 MB enviados / Pacotes enviados: 14580 MB/s<br />
<[I]depois60130568> [Attack Finalizado!]: 75 MB enviados / Pacotes enviados: 1 MB/s<br />
<[I]depois48664304> [Attack Finalizado!]: 75 MB enviados / Pacotes enviados: 1 MB/s<br />
<[I]depois65415449> [Attack Finalizado!]: 75 MB enviados / Pacotes enviados: 1 MB/s<br />
<[I]depois11325010> [Attack Finalizado!]: 75 MB enviados / Pacotes enviados: 1 MB/s<br />
*** [A]depois40994506 (~depois72760562@79.98.28.XX) has joined channel #depoiswp<br />
<[A]depois07568398> [Attack Finalizado!]: 2187317 MB enviados / Pacotes enviados: 18228 MB/s<br />
<[A]depois55402758> [Attack Finalizado!]: 11425 MB enviados / Pacotes enviados: 95 MB/s<br />
*** [A]depois03383512 (~depois52457929@74.220.215.XX) has joined channel #depoiswp<br />
<[A]depois37064023> [Attack Finalizado!]: 1264043 MB enviados / Pacotes enviados: 10534 MB/s<br />
<[A]depois69234369> [Attack Finalizado!]: 2205504 MB enviados / Pacotes enviados: 18379 MB/s<br />
*** [A]depois74911768 (~depois04730096@74.220.215.XX) has joined channel #depoiswp<br />
*** Signoff: [A]depois31575043 (Connection reset by peer)<br />
<[I]depois17710498> [Attack Finalizado!]: 81 MB enviados / Pacotes enviados: 1 MB/s<br />
<[I]depois28464134> [Attack Finalizado!]: 81 MB enviados / Pacotes enviados: 1 MB/s</p></blockquote>
<p>Thats fine and all. I disconnected shortly after that. I really have no reason  to be poking around there now do i ;) Besides who want to  interfere with an ongoing investigation. So poking around the files a bit more didnot  reveal  all that information.Except for the fact that besides a IRC bot a backdoor was also installed in the form of a perl script dc.pl installed in /var/tmp. So who knows. The server might be rooted at this point.</p>
<p>I spend some more time on decoding the bot and trojan contents. And posted them on pastebin if you are interested. The server is going to be  decommissioned soon. So i am not going to pay much more attention to it.</p>
<p><strong>1.php and b2dabd0e2c42b55fabf741bcac29f857.php</strong><br />
Web Shell by boff</p>
<p><strong>2b3753ea4769084f2e571737b695b03a.php</strong><br />
This file was base64 encoded but once decoded reveled to be a simple script by v0pCr3w and nob0dyCr3w to run system commands on the server. Also included was a simple upload form.</p>
<p><strong>34e3a3a74f6e2d0f236bdd3ba70c0c03.php</strong><br />
 c99 injector v1</p>
<p><strong>771b821c974131c67e34c83d8d2db725.php</strong><br />
This script was rot13 and base64 encoded and was trying to cleanup after the hacker. And install a second back door.</p>
<p><strong>7228f168d9692eafeafc54dbc3a1ab49.php and cce0a37ffc138a8908da05977639bed1.php</strong><br />
Again rot13 and base64 encoded.But this script contained something that looks like a control panel. The page title was &#8216;Hacked by Sherif #oishi @ ALLnet&#8217;</p>
<p><strong>alienee.php</strong><br />
Still working on this one</p>
<p><strong>cf2cdb3ad3249b9692de07290f16f287.php and ded3244749701c4eb5a29b959ad56736.php</strong><br />
These files contained a second bot that was connecting to a whole different server. Probably exploited by another crew?</p>
<p><strong>dc.pl</strong><br />
This Perl backdoor was created by one  of the IRC bot scripts. And was hiding in /var/tmp after creation.</p>
<p>And some links i found useful while working on this issue.<br />
<a href=" http://eromang.zataz.com/2012/01/08/gangbang-mytijn-org-malware-spreader-down/"></p>
<p>http://eromang.zataz.com/2012/01/08/gangbang-mytijn-org-malware-spreader-down/</a></p>
<p><a href="http://www.madirish.net/content/hookworm-stealth-php-backdoor">http://www.madirish.net/content/hookworm-stealth-php-backdoor</a><br />
<a href="http://markmaunder.com/2011/08/01/zero-day-vulnerability-in-many-wordpress-themes/">http://markmaunder.com/2011/08/01/zero-day-vulnerability-in-many-wordpress-themes/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2012/02/wordpress-install-compromised/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP critical bug CVE-2012-0830</title>
		<link>http://lenss.nl/2012/02/php-critical-bug-cve-2012-0830/</link>
		<comments>http://lenss.nl/2012/02/php-critical-bug-cve-2012-0830/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 11:39:43 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[attack]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[Crash]]></category>
		<category><![CDATA[CVE-2012-0830]]></category>
		<category><![CDATA[remote]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1423</guid>
		<description><![CDATA[Ok it&#8217;s a bit late But i have been laying under a rock for the last week. And i guess it can&#8217;t hurt! Last week a critical bug was discovered in PHP. Which affects versions 5.3.9 and 5.2.17. The bug could be exploited to run arbitrary code on a remote PHP system. So upgrade your [...]]]></description>
			<content:encoded><![CDATA[<p>Ok it&#8217;s a bit late But i have been laying under a rock for the last week. And i guess it can&#8217;t hurt!</p>
<p>Last week a critical bug was discovered in PHP. Which affects versions 5.3.9 and 5.2.17. The bug could be exploited to run arbitrary code on a remote PHP system. So upgrade your systems. And of course Stefan Esser <a href="http://news.php.net/php.internals/57655">popped up</a> with some wise words :)&#8230; O well i still think the guy does great work.</p>
<p>More info about the issue can be found on packetstorm (<a href="http://packetstormsecurity.org/files/cve/CVE-2012-0830">CVE-2012-0830</a>) </p>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2012/02/php-critical-bug-cve-2012-0830/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP getting strict sessions</title>
		<link>http://lenss.nl/2011/11/php-getting-strict-sessions/</link>
		<comments>http://lenss.nl/2011/11/php-getting-strict-sessions/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 13:38:28 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Zend]]></category>
		<category><![CDATA[5.4]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[session fixation]]></category>
		<category><![CDATA[strict_session]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1405</guid>
		<description><![CDATA[For years PHP has been vulnerable to session adoption which can enable session fixation. And since sessions are a major part of web applications now a days. A lot of platforms are open and waiting for an attack to happen. session adoption &#038; session fixation The problem exists because the current session module does not [...]]]></description>
			<content:encoded><![CDATA[<p>For years <a href="http://php.net/">PHP</a> has been vulnerable to session adoption which can enable <a href="http://en.wikipedia.org/wiki/Session_fixation">session fixation</a>. And since sessions are a major part of web applications now a days. A lot of platforms are open and waiting for an attack to happen.</p>
<p><strong>session adoption &#038; session fixation</strong></p>
<p>The problem exists because the current session module does not validate the session id that comes in from a cookie. This means uninitialized session id&#8217;s can be passed by the client. This happens due to the fact that browsers overwrite cookie if multiple cookies are send per request.<br />
Some people would say this is solvable by implementing <a href="http://nl3.php.net/manual/en/function.session-regenerate-id.php">session_regenerate_id()</a>. But this is not the case.</p>
<p>Because session fixation can be used to take over control of web applications. Validation is required when multiple cookies are send per request. When multiple cookie are send with a request. Browsers send multiple cookies without domain / path information. This way it&#8217;s impossible to tell which cookie belongs to which domain. </p>
<p><strong>So how do we fix this?</strong></p>
<p>There is some userland code that does offer the ability to validate session data. But this has not been widely adopted by other developers.</p>
<p>Code that adds the session ID as a validation key:</p>
<pre class="php" name="code">
session_destory();
session_regenerate_id();
$_SESSION['valid_id'] = session_id();
</pre>
<p>And the code to check if the session was properly initialized:</p>
<pre class="php" name="code">
if ($_SESSION['valid_id'] !== session_id()) {
  die('Invalid use of session ID');
}
</pre>
<p>Thank god the internal developer know this. And are working to fix this. For the past days there has been an interesting discussion going on on the <a href="http://news.php.net/php.internals">internals</a> list. About applying a patch that will fix this. The patch will add some new php.ini features and a new method validate_id() for the session save handler. Hopefully this will be available in version 5.4.</p>
<p>To not break BC strict_mode will be disabled by default. But can be enabled by setting the following setting in php.ini. When enabled uninitialized session ID will be discarded.</p>
<blockquote><p>session.use_strict_mode=0</p></blockquote>
<p>To prevent a DoS instead of session fixation. An new feature has been added that deletes possible malicious cookies that prevent new session ID.</p>
<blockquote><p>session.safe_session_cookie=1</p></blockquote>
<p>You can read more about session fixation and the upcoming patch on the <a href="https://wiki.php.net/rfc/strict_sessions">PHP-Wiki</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2011/11/php-getting-strict-sessions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Abbywinters.com is hiring!</title>
		<link>http://lenss.nl/2011/11/abbywinters-com-is-hiring/</link>
		<comments>http://lenss.nl/2011/11/abbywinters-com-is-hiring/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 12:46:51 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[abbywinters.com]]></category>
		<category><![CDATA[Adult]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Job]]></category>
		<category><![CDATA[naturally delicious]]></category>
		<category><![CDATA[SCRUM]]></category>
		<category><![CDATA[Sexy]]></category>
		<category><![CDATA[Webdeveloper]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1386</guid>
		<description><![CDATA[If you&#8217;re looking for a new challenging and exiting Senior Webdeveloper position. Don&#8217;t look any further. If you already think you have the job of your dreams. Think again! abbywinters.com (NSFW) is one of the largest and most ethical, highly rated, well designed, and successful erotic websites in the world today. abbywinters.com is the WINNER [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://careers.abbywinters.com/job-opportunities/senior-php-developer/" target="_blank"><img src="http://lenss.nl/wp-content/uploads/2011/11/aw-logo-roundel-blue.png" alt="" title="abbywinters.com - Delivering game-changing experiences" style="float:left;margin:10px;" width="140" height="140" class="alignright size-full wp-image-1385" /></a> If you&#8217;re looking for a new challenging and exiting Senior Webdeveloper position. Don&#8217;t look any further. If you already think you have the job of your dreams. Think again!</p>
<p><em><a href="http://www.abbywinters.com" target="_blank">abbywinters.com</a> <b>(NSFW)</b> is one of the largest and most ethical, highly rated, well designed, and successful erotic websites in the world today. abbywinters.com is the WINNER of the AVN 2011 Awards for Best Membership site!</em></p>
<p>And we are looking to hire a new talented webdeveloper to expand our small team. What would you think about joining our small Agile team of highly qualified professionals? </p>
<p>You will be creating sexy, exiting and game changing experiences for the web, work for one of the industry leaders. And just be part of an awesome company. Some of the jobs key elements are:</p>
<ul>
<li>Implementing development projects</li>
<li>Leading informal mentoring during day-to-day work</li>
<li>Contribute to design of development projects</li>
<li>Track, reduce, and prevent technical debt in Web Development projects</li>
</ul>
<p><br/></p>
<blockquote><p>Motivated by principles of social responsibility, we deliver provocative media by embracing imagination, creativity and emerging technologies. Our models, customers and business partners are inspired by our fervid passion.</p>
<p><br/></p>
<p>Our experienced staff use state-of-the-art content production facilities to produce 10 shoots a week from concept to finished art, utilizing the most advanced digital capture, post production and delivery systems in the world.</p>
<p><br/></p>
<p>You will be working directly with our Web Dev Manager, Lead developer and colleagues in the web dev team. We need each individual to contribute for us to continue as a pioneer in our industry.</p>
</blockquote>
<p><br/></p>
<p>If you posses a &#8220;Can do&#8221; attitude. Would like to work in the center of Amsterdam. And are able to identify your self in the criteria below. You might want to head over to our <a href="http://careers.abbywinters.com/job-opportunities/senior-php-developer/">career portal</a> for a more detailed description.<br/></p>
<p><strong>Technical competencies – Required</strong></p>
<ul>
<li>High level of skill with PHP 5</li>
<li>High level of skill with Object Oriented Programming</li>
<li>High level of skill with HTML/CSS</li>
<li>High level of skill with JavaScript</li>
<li>High level of skill with Internet Applications</li>
<li>Moderate level of skill with Unit Testing and Test Driven Design</li>
<li>Moderate level of skill with MySQL</li>
<li>Moderate level of skill with Windows XP operating system</li>
<li>Experience with the GNU/Linux operating system</li>
<li>Competent with Revision Control systems (Subversion)</li>
<li>Bachelor of Science in Computer Science, or equivalent experience</li>
<li>Zend Certified Engineer, or equivalent experience</li>
<li>At least 5 years experience in Web Application Development</li>
</ul>
<p><br/></p>
<p><strong>Technical competencies – Desired</strong></p>
<ul>
<li>Moderate level of skill with the Apache HTTP server</li>
<li>Good understanding of the Model-View-Controller pattern</li>
<li>Good understanding of the ActiveRecord Object-Relational-Mapping pattern</li>
<li>Familiarity with Agile software development practices (Scrum)</li>
<li>E-commerce</li>
<li>Agile development experience</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2011/11/abbywinters-com-is-hiring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP slow on 32-bit Ubuntu</title>
		<link>http://lenss.nl/2011/09/php-slow-on-32-bit-ubuntu/</link>
		<comments>http://lenss.nl/2011/09/php-slow-on-32-bit-ubuntu/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 11:09:44 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[32-bit]]></category>
		<category><![CDATA[largefile]]></category>
		<category><![CDATA[slow]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1325</guid>
		<description><![CDATA[My last post was about the 32-bit integer issue i was having with PHP. And besides setting up a 64-bit server one of the solutions is to compile PHP with the CFLAGS mentioned in my previous post. Intrigued by the fact that my 32-bit Ubuntu installation did not suffer from the same issue. I started [...]]]></description>
			<content:encoded><![CDATA[<p>My last <a href="http://lenss.nl/2011/08/php5-filesize-limit-on-32-bit-system/">post</a> was about the 32-bit integer issue i was having with PHP. And besides setting up a 64-bit server one of the solutions is to compile PHP with the CFLAGS mentioned in my previous post. </p>
<p>Intrigued by the fact that my 32-bit Ubuntu installation did not suffer from the same issue. I started to read the PHP5 changelog for Ubuntu.</p>
<blockquote><p>
CFLAGS=”-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64″ ./configure</p></blockquote>
<p>But this has a negative side effect. Namely PHP running 50% slower then it should be. And to my surprise Ubuntu applies the CFLAGS above when compiling PHP5 for a 32-bit platform. So that would mean PHP on Ubuntu is always running 50% slower? Well according to <a href="https://bugs.php.net/bug.php?id=45942">this</a> is should be the case. </p>
<p>I downloaded <a href="http://nl.php.net/get/php-5.3.8.tar.gz/from/a/mirror">php-5.3.8</a> from php.net and compiled two versions. One with the CFLAGS set for large files. And one normal without any changes. After that i downloaded the benchmark script from <a href="http://www.php-benchmark-script.com">php-benchmark-script.com</a>. And did a couple of runs on each of the two installs. The results are stunning.</p>
<p><strong>PHP-5.3.8 compiled with large file support:</strong></p>
<blockquote><p>test_math                 : 4.414 sec.<br />
test_stringmanipulation   : 4.968 sec.<br />
test_loops                : 3.529 sec.<br />
test_ifelse               : 2.344 sec.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
Total time:               : 15.255 sec.</p></blockquote>
<p><strong>PHP-5.3.8 compiled without large file support:</strong></p>
<blockquote><p>test_math                 : 2.274 sec.<br />
test_stringmanipulation   : 2.286 sec.<br />
test_loops                : 1.619 sec.<br />
test_ifelse               : 1.228 sec.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
Total time:               : 7.407 sec.</p></blockquote>
<p>That&#8217;s pretty much a 50% speed decrease. One more thing i tried is adding the &#8216;AC_SYS_LARGEFILE&#8217; macro to configure.in and rebuild the configure script. But this had no effect at all.</p>
<blockquote><p>$ cd php-5.3.8<br />
$ vi configure.in (add AC_SYS_LARGEFILE somewhere)<br />
$ export PHP_AUTOCONF=/usr/share/autoconf2.59<br />
$ ./buildconf &#8211;force</p></blockquote>
<p>I then tried two things. First i build without the CFLAGS. But this didn&#8217;t seem to do much. Then i used the same configure script with the CFLAGS for large file support. But there was no speed increase measurable. </p>
<p>So why would Ubuntu have made the choice to compile PHP with the large file support on a 32-bit platform? Are there really that much developers that work on large files in web / cli applications written in PHP? Enough to sacrifice a 50% speed decrease?</p>
<p>I don&#8217;t really know the answer to that. But i will do my large file processing on 64-bit machines. And will compile PHP from scratch from now on. Until i have upgraded my aging hardware.</p>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2011/09/php-slow-on-32-bit-ubuntu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP5 filesize limit on 32-bit system</title>
		<link>http://lenss.nl/2011/08/php5-filesize-limit-on-32-bit-system/</link>
		<comments>http://lenss.nl/2011/08/php5-filesize-limit-on-32-bit-system/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 22:38:00 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Zend]]></category>
		<category><![CDATA[filesize]]></category>
		<category><![CDATA[is_file]]></category>
		<category><![CDATA[limit]]></category>
		<category><![CDATA[workaround]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1313</guid>
		<description><![CDATA[So we have a PHP based importer script that does some heavy duty media processing at the office. And i had to import some new media today. But for some reason a couple of files weren&#8217;t picked up without a message. So i cleaned up the upload folder. The only files left were the files [...]]]></description>
			<content:encoded><![CDATA[<p>So we have a PHP based importer script that does some heavy duty media processing at the office. And i had to import some new media today. But for some reason a couple of files weren&#8217;t picked up without a message. So i cleaned up the upload folder. The only files left were the files not being processed. And when i started the importer. The result was.</p>
<blockquote><p>
Importer found (0) files to import!</p></blockquote>
<p>Hmmm. That&#8217;s not right. So i had a look at the code behind the importer. Which basically is a loop using a <a href="http://nl2.php.net/manual/en/class.directoryiterator.php">DirectoryIterator</a> object. And some var_dump calls revealed the issue. For some reason <a href="http://nl2.php.net/manual/en/splfileinfo.isfile.php">->isFile()</a> was returning <em>(false)</em> for regular files. WTF! Let&#8217;s test that on the command line.</p>
<blockquote><p>$ php -r &#8220;var_dump(is_file(&#8216;/some/file.ext&#8217;));&#8221;;<br />
<em>bool(false)</em></p></blockquote>
<p>Ok so we have an issue here. How big are these files really. A inspection revealed they are all over 2GB. Maybe some 32 bit issue? As the platform the code is running on is a 32 bit server. So i asked my colleagues, Googled a bit and read through php.net. To find out that there is an issue with PHP and files larger then 2GB.</p>
<blockquote><p><a href="https://bugs.php.net/bug.php?id=27792">https://bugs.php.net/bug.php?id=27792</a><br />
<a href="https://bugs.php.net/bug.php?id=48886">https://bugs.php.net/bug.php?id=48886</a><br />
<a href="http://nl.php.net/manual/en/function.filesize.php">http://nl.php.net/manual/en/function.filesize.php</a></p></blockquote>
<p>Those however all seem related to filesize. The filesize function manual page even has a note about it. Maybe it&#8217;s related?</p>
<blockquote><p>    <strong>Note:</strong> Because PHP&#8217;s integer type is signed and many platforms use 32bit integers, <strong>filesize() </strong> may return unexpected results for files which are larger than <strong>2GB</strong>. For files between 2GB and 4GB in size this can usually be overcome by using <strong>sprintf(&#8220;%u&#8221;, filesize($file))</strong>. </p></blockquote>
<p>But i can&#8217;t apply that patch on a production server. So i came up with a simple solution for now. I extended the <a href="http://nl2.php.net/manual/en/class.directoryiterator.php">DirectoryIterator</a> class and have overwritten the <em>isFile</em> method. Which works for now (don&#8217;t think this will work on windows).</p>
<pre name="code" class="php">
Class MyDirectoryIterator extends DirectoryIterator {
	public function isFile() {
		return (integer) exec("[ -f {$this->getPathname()} ] &#038;&#038; echo 1 || echo 0");
	}
}
</pre>
<p>Convinced it was a 32 bit issue. I came home later that day. And wanted to try it out on my own desktop. That is a 32 bit system and runs Ubuntu 11.04. To my surprise the result was different then i expected.</p>
<blockquote><p>$ php -r &#8220;var_dump(is_file(&#8216;/some/file.ext&#8217;));&#8221;;<br />
<em>bool(true)</em></p></blockquote>
<p>I used the same files as before. And tested some more big files. But the result was the same. Weird. Let&#8217;s try some other 32 bit machines.</p>
<blockquote><p>Ubuntu 11.04: bool(true)</p>
<p>CentOS release 5.6 (Final): bool(false)<br />
Debian 6.0.2 (squeeze): bool(false)</p></blockquote>
<p>Only my desktop at home seems to have a good result. Ubuntu must have some patch somewhere to fix this issue? To confirm i compiled PHP 5.3.8 from source. And did the same test again on Ubuntu 11.04. And this time it was <em>(false)</em>.</p>
<blockquote><p>$ php -r &#8220;var_dump(is_file(&#8216;/some/file.ext&#8217;));&#8221;;<br />
<em>bool(false)</em></p></blockquote>
<p>I am not really in the mood to search the Ubuntu <a href="http://changelogs.ubuntu.com/changelogs/pool/main/p/php5/">changelog</a>. And for now the work around will do. But i really would like to know what patch is applied to resolve the issue.</p>
<p><strong>[ update ]</strong></p>
<p>While applying the patch for the is_file issue. I was confronted with the fact that way more function calls cause issues. So while waiting for PHP to get patched i had to create some workarounds for the time being.</p>
<p>Getting the filesize:</p>
<pre name="code" class="php">
(integer) exec("stat -c%s {$file->getFilename()}");
</pre>
<p>Calculate a MD5 checksum:</p>
<pre name="code" class="php">
$md5 = exec("md5sum {$file->getFilename()}");
$expl = explode('\t', $md5);
return (string) $expl[0];
</pre>
<p>Calculate the CRC32 checksum:</p>
<pre name="code" class="php">
$hash = exec("cksum {$this->path}");
$expl = explode(' ', $hash);
return $expl[0];
</pre>
<p>Get the modified time:</p>
<pre name="code" class="php">
$stat = explode('.', exec("stat -c%y {$this->path}"));
$timestamp = strtotime($stat[0]);
return $timestamp;
</pre>
<p>Hopefully that will do for now. On a side note the issue is solvable by setting certain <strong>CFLAGS</strong> when compiling PHP. I have no idea what the impact of that will be on the PHP binary. But it does seem to solve the issue. Not sure how one would apply that when PHP is installed from the distro&#8217;s repository though.</p>
<blockquote><p>CFLAGS=&#8221;-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64&#8243; ./configure</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2011/08/php5-filesize-limit-on-32-bit-system/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP locale dates adventure</title>
		<link>http://lenss.nl/2011/08/php-locale-dates-adventure/</link>
		<comments>http://lenss.nl/2011/08/php-locale-dates-adventure/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 21:54:46 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[locale]]></category>
		<category><![CDATA[strftime]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1295</guid>
		<description><![CDATA[About a week ago i was working on a twitter widget for a website. This required some dates to be displayed in Dutch. And i found out the hard way my knowledge on this has faded away over time. So the code i was working on. Did something like this. $date = date('D M d [...]]]></description>
			<content:encoded><![CDATA[<p>About a week ago i was working on a twitter widget for a website. This required some dates to be displayed in Dutch. And i found out the hard way my knowledge on this has faded away over time.</p>
<p>So the code i was working on. Did something like this.</p>
<pre name="code" class="php">
$date = date('D M d H:i:s Y', strtotime($someVar));
</pre>
<p>My thought was that by setting the correct locale the dates would appear in the correct language. Wrong!</p>
<pre name="code" class="php">
date_default_timezone_set('Europe/Amsterdam');
setlocale(LC_ALL, 'nl_NL.utf8');
</pre>
<p>After a reload i was greeted by the same dates as before. In plain English. Oke no worries. Let&#8217;s see what setlocale returns.</p>
<pre name="code" class="php">
var_dump(setlocale(LC_ALL, 'nl_NL.utf8'));
</pre>
<blockquote><p>
bool(false)</p></blockquote>
<p>That&#8217;s not good. Seems like we are missing some locales on the server. Let&#8217;s check.</p>
<blockquote><p>locale -a</p></blockquote>
<blockquote><p>en_AG<br />
en_AG.utf8<br />
en_AU.utf8<br />
en_BW.utf8<br />
en_CA.utf8<br />
en_DK.utf8<br />
en_GB.utf8<br />
en_HK.utf8<br />
en_IE.utf8<br />
en_IN<br />
en_IN.utf8<br />
en_NG<br />
en_NG.utf8<br />
en_NZ.utf8<br />
en_PH.utf8<br />
en_SG.utf8<br />
en_US.utf8<br />
en_ZA.utf8<br />
en_ZW.utf8<br />
&#8230;</p></blockquote>
<p>And some more output after that. But not the one i am looking for. But thankfully aptitude was kind enough to provide the missing language packages.</p>
<blockquote><p>nl_NL<br />
nl_NL@euro<br />
nl_NL.iso88591<br />
nl_NL.iso885915@euro<br />
nl_NL.utf8</p></blockquote>
<p>So let&#8217;s set the correct locale for this script.</p>
<pre name="code" class="php">
setlocale(LC_ALL, 'nl_NL.utf8');
</pre>
<p>But still no changes. I must be missing something&#8230;.. Let&#8217;s consult the <a href="http://www.php.net/manual/en/function.date.php">manual</a>. The last line in the <strong>examples</strong> section is what i was looking for</p>
<blockquote><p>To format dates in other languages, you should use the <a href="http://www.php.net/manual/en/function.setlocale.php">setlocale()</a> and <a href="http://www.php.net/manual/en/function.strftime.php">strftime()</a> functions instead of date(). </p></blockquote>
<p>Duuh! Completely forgot about <a href="http://www.php.net/manual/en/function.strftime.php">strftime</a>. Let&#8217;s change the code.</p>
<pre name="code" class="php">
strftime('%a %b %d %H:%M:%S %Y', strtotime($somevar));
</pre>
<blockquote><p>ma aug 15 14:55:06 2011</p></blockquote>
<p>Perfect. That did it. </p>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2011/08/php-locale-dates-adventure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reserved keywords, corrupt cache and stack errors</title>
		<link>http://lenss.nl/2011/06/reserved-keywords_corrupt-cache-and-stack-errors/</link>
		<comments>http://lenss.nl/2011/06/reserved-keywords_corrupt-cache-and-stack-errors/#comments</comments>
		<pubDate>Tue, 21 Jun 2011 12:22:36 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[currupt cache]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[keywords]]></category>
		<category><![CDATA[MySql]]></category>
		<category><![CDATA[reserved]]></category>
		<category><![CDATA[stack frame]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1277</guid>
		<description><![CDATA[What a day. Every now and then there are such days where you wished you stayed in bed. Today was one of them. And i was confronted by two weird errors with very non descriptive error message or no error message at all. In both cases the issue was solved without a real solution. This [...]]]></description>
			<content:encoded><![CDATA[<p>What a day. Every now and then there are such days where you wished you stayed in bed. Today was one of them. And i was confronted by two weird errors with very non descriptive error message or no error message at all. In both cases the issue was solved without a real solution. This post is just to vent my frustration of the day. And now that i take the time to write this down i might as well add the issue i ran into last week. Will save that one for last.</p>
<p><strong>Reserved keyword</strong></p>
<p>So i have been banging my head over this issue for way to long today. And had to find out the hard way it was a simple little thing as usual. But <a href="http://www.doctrine-project.org/">Doctrine</a> (version 1 if anybody asks) didn&#8217;t offer me any good info with the error message it was displaying. Nor did <a href="http://www.php.net/">PHP</a> or <a href="http://www.mysql.com/">MySQL</a> (should be <a href="http://mariadb.org/">MariaDB</a> if you ask me).</p>
<p>While working on a very heavy Doctrine based project. I ran into a at first glance weird error. Yesterday i created a class structure. All good and well. The class i was working on was called <em>Shows</em>. But it represented a single <em>Show</em> entity and therefore should have been called <strong>Show</strong>. So i decided to do a rename action. Pretty complex because of different dependencies. But after a few tries i got it right. Except Doctrine was failing with a syntax error. After a code inspection i still couldn&#8217;t spot the issue. The only thing i didn&#8217;t do yet was output the query and run it from a shell. And this failed with the same syntax error message. Damn!</p>
<blockquote><p>INNER JOIN show s ON &#8230;</p></blockquote>
<p>Checked the whole query. Still couldn&#8217;t spot the issue. Then for some weird reason i decided to escape the table name with <a href="http://en.wikipedia.org/wiki/Grave_accent">backticks</a> <strong>`Show`</strong>. Everything worked again. Wow! So Doctrine doesn&#8217;t escape table names. But why did it fail in the first place? By now i had the feeling i was using a reserved keyword. And a check <a href="http://dev.mysql.com/doc/mysqld-version-reference/en/mysqld-version-reference-reservedwords-5-6.html">confirmed</a> this. An error would have been helpful here. I had a bit of luck though. As it turned out the table should have been named different anyway. I made a small workaround for it in my code. But decided that was not the way to go  So the lesson of the day for me was don&#8217;t use reserved words for class / table names. A good thread on the issue can be found <a href="http://www.doctrine-project.org/jira/browse/DBAL-40">here</a>.</p>
<p><strong>APC object corruption</strong></p>
<p>The second issue to bite my ass was a nice one as well. And this time no indication of an error at all. While working on the same classes discusses shortly above. I renamed the class names and the file names on disk. And after a page reload in the browser. The framework was complaining it couldn&#8217;t load the changed class. I checked the class and file names and all were correct. After toying with it for 20 minutes i decided to ask my colleague. And he suggested to restart Apache. for the second time today i was stumped. Everything worked again. Turns out that APC couldn&#8217;t find the already in memory loaded class. After renaming the corresponding filename (seems logical now that i think of it). A restart of Apache flushed the APC cache and therefore the issue. This sounds like a bug though. And requires some further inspection or a bug report. We will see.</p>
<p><strong>PHP Fatal error</strong></p>
<p>Last week while setting up <a href="https://github.com/sebastianbergmann/phpunit/">PHPUnit</a> i ran into a weird issue while testing PHPUnit from a shell on my local desktop. The whole test suite would run from start to end. But at the end would display the following not so descriptive error message.</p>
<blockquote><p>PHP Fatal error:  Exception thrown without a stack frame in Unknown on line 0 </p></blockquote>
<p>This kept me busy for some hours. This happened somewhere in a large framework. And there was no clear sign of what was causing the issue. Some <a href="http://www.google.com/search?client=ubuntu&#038;channel=fs&#038;q=Exception+thrown+without+a+stack+frame+in+Unknown+on+line+0&#038;ie=utf-8&#038;oe=utf-8">googling</a> did reveal some cases in which this error may occur.</p>
<blockquote><ul>
<ul>There was an exception while handling an exception</ul>
<ul>There was an exception while running a destructor</ul>
<ul>There was an exception while closing the session</ul>
<ul>There was an exception while running a shutdown function</ul>
<ul>There was an exception while running a autoload function</ul>
</ul>
</blockquote>
<p>The issue in my case was the fact that the configuration file wasn&#8217;t loaded yet. And therefore the log file location was not set correctly. Logging in this framework is done in a plugin system which is pretty cool. We can basically assign plugins for certain log levels (and more). This was the FileLogger. This all still does not explain why it failed with this particular error message. But a bit of digging in the Log/Plugin system revealed the issue. </p>
<pre name="code" class="php">
register_shutdown_function(array(__CLASS__, 'Shutdown'));
</pre>
<p>Message are stored in a queue and written to file in a register shutdown function. Which was failing because the logfile location was not set correctly. This was causing an exception to be thrown inside the registered shutdown function. And therefore triggering this horrible error message. Be careful with <a href="http://nl.php.net/manual/en/function.register-shutdown-function.php">register_shutdown</a> functions.</p>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2011/06/reserved-keywords_corrupt-cache-and-stack-errors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dutch PHP Conference 2011</title>
		<link>http://lenss.nl/2011/05/dutch-php-conference-2011/</link>
		<comments>http://lenss.nl/2011/05/dutch-php-conference-2011/#comments</comments>
		<pubDate>Mon, 23 May 2011 09:51:39 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[2011]]></category>
		<category><![CDATA[Conference]]></category>
		<category><![CDATA[DPC]]></category>
		<category><![CDATA[dpc11]]></category>
		<category><![CDATA[IBuildings]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1262</guid>
		<description><![CDATA[Last week was the 5th DPC (Dutch PHP Conference) in the Amsterdam Rai. And thanks to my awesome employer i once again had the chance to be there. This year with a full conference ticket (including the tutorial days). And i had a blast. I wanted to do this post earlier this weekend but due [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://lenss.nl/wp-content/uploads/2011/05/dpc11.jpg"><img style="float:left;margin:10px;" src="http://lenss.nl/wp-content/uploads/2011/05/dpc11.jpg" alt="" title="dpc11" width="250" height="188" class="alignleft size-full wp-image-1268" /></a> Last week was the 5th <a href="http://www.phpconference.nl">DPC</a> (Dutch PHP Conference) in the <a href="http://www.rai.nl/">Amsterdam Rai</a>. And thanks to my awesome employer i once again had the chance to be there. This year with a full conference ticket (including the tutorial days). And i had a blast. I wanted to do this post earlier this weekend but due to some current injury i wasn&#8217;t able to. So here goes.</p>
<p>The kick off for the DPC11 were the tutorial days. And they had some pretty cool tutorial lined up for this year. But as always you have to choose. So me and Geoff chose to visit two of the tutorials we would benefit from the most. Since we are in pretty heavy database driven environment. We chose:</p>
<p><strong>Optimizing <a href="http://www.mysql.com/">MySQL</a> Essentials</strong></p>
<p>This session was presented by <a href="http://www.khankennels.com/blog/">Ligaya Turmelle</a> &#038; Raymond DeRoo, And these two have a great chemistry between them. All the ingredients for a good sessions. And a good session it was. Even though i missed the larges part of the first 1.5 hours because i got stuck in traffic. </p>
<p>The second part of the tutorial was aimed at profiling and optimizing slow queries. It was Ligaya time to talk and Raymond took his stand on the soapbox a few times to makes things more clear. Or to interact with the audience in his special way. The session mainly describe how to enable and configure the MySQL slow query log. And what to look for once that is up and running. Ligaya continued with a real world example from joined.in. And show how the medium sized queries could be optimized quite a bit. Although not completely finished. The result was quite nice.</p>
<p>After talking about the slow query log we went into a bit more detail as to how to do query optimization. And what tools to use for the job. MySQl comes with some nice features that can be used in this process. The basics to get more information about your queries</p>
<blockquote><p>* show create<br />
* table status<br />
* show indexes<br />
* explain [ extended ]</p></blockquote>
<p>I made quite a few notes during this sessions. And learned some cool new things. Some of the main items for me were</p>
<p>If possible move where clauses inside the join statements<br />
Don&#8217;t use subselects. But if you really have to use them in the `AS` form </p>
<blockquote><p>SELECT<br />
  t.id,<br />
  (SELECT t2foo FROM table t2 WHERE t2foo = t.bar) AS foo<br />
FROM table t</p></blockquote>
<p>Indexing key order is very important<br />
Use a sequence table to generate date based reports</p>
<p><strong>Doctrine 2</strong></p>
<p>I was really looking forward to the <a href="http://www.doctrine-project.org/">Doctrine 2</a> session with <a href="http://dev.juokaz.com/">Juozas Kaziukėnas</a>. And it was a good session as well. Although a bit fast. And i had some issues getting Doctrine to work on my laptop. But because we make very heavy use of Doctrine 1. I was very interested in what version two has to offer over version 1. And i think Juozas did a great job in explaining the structure of Doctrine 2 and the most basic inner workings. </p>
<p>I was very happy to see the new Doctrine 2 models are completely decoupled from the Doctrine base classes. This is awesome. And makes for a way more portable application then with the Doctrine 1 base. Which basically ties you into using Doctrine forever.</p>
<p><strong>That was tutorial day</strong><br />
That was day one. I had fun although quit painful with my current injury. I really enjoyed the sessions. And on our way out we were presented with a nice surprise. A copy of &#8220;<a href="http://qualityassuranceinphpprojects.com/">Real-World Solutions for Developing High-Quality PHP Frameworks and Applications</a>&#8221; by Sebastian Bergmann and Stefan Priebsch. A great addition to my private library. And to top things of we all got a 20% discount on the 5.3 <a href="http://www.zend.com/services/certification/">ZCE</a> exam. </p>
<p><strong>Next up, Day 2</strong></p>
<p>I missed the opening talk by <a href="http://www.harrieverveer.nl/">Harry Verveer</a> which is a shame. Geoff told me it was a very good inspiring and energetic talk. It got people enthusiastic. That&#8217;s what we need. At arrival it was visible that there were quite some developers here. It&#8217;s always a big difference with the tutorial day. Like the first day i missed a big part of the morning due.. to well you know. But i attended 4 cool sessions non the less.</p>
<p><strong>Cooking up your Development Environment</strong> by <a href="http://www.designdisclosure.com/">Alistair Stead</a></p>
<p>This session was a bit different then what i envisioned. But it turned out to be a gem. Most of the talk was aimed at explaining how to setup and work with the <a href="https://github.com/opscode/chef">Chef</a> application. Before going into explaining chef. Alistair mentioned some other solutions like Capistrano, Puppet or a mix of Bash scripts.</p>
<p>And then he continued about explaining his day to day work day. And how he would setup his virtual work environment each morning by running a simple command that generates a fresh virtual machine to work with. Then he went into detail how Chef Solo (Distributed infrastructure management) and Chef Server (Centralized infrastructure management) work together. And how you can setup and deploy packages on the virtual machines and basically how to manage your instances from a cool and simple web GUI.</p>
<p>He went on explaining this hooks into Amazone&#8217;s AWS and Rackspace cloud services as well. So skies the limit. An awesome tool.</p>
<p><strong>Simplify your External Dependency Management</strong> by <a href="http://blog.bitexpert.de/author/stephan-hochdoerfer/">Stephan Hochdörfer</a></p>
<p>This session was aimed at working better with project dependencies. I was quite interested in this talk. Since we work with svn:externals. Which at times can be quite a pain. Specially when the amount of applications build on a single framework tend to grow. And BC breakage is a sin.</p>
<p>I was a bit sad to see that this session didn&#8217;t really target managing the local dependencies. But was more aimed at handling the dependencies when deploying packages on servers. Until now this has never been an issues. Even though i was a bit disappointed. The sessions did have some valuable information.</p>
<p>And went into some detail how to setup an own PEAR channel to deploy packages but also touched the Java system Maven. Which i did work whit a few years back.</p>
<p><strong>Clean PHP</strong> by <a href="http://sebastian-bergmann.de/">Sebastian Bergmann</a></p>
<p>I expected more from this sessions. And i had the feeling Sebastian was blasting through the talk as if he was out of time. It went very fast. And basically was run down of all the developer principles, acronyms, etc. A good talk. But i expected more from the father of <a href="http://www.phpunit.de">PHPUnit</a>.</p>
<p><strong>Advanced OO patterns</strong> by <a href="http://schlitt.info/">Tobias Schlitt</a></p>
<p>The best session of the day. Tobias is a real speaker. One that say the right things. And makes the audience laugh. I really enjoyed listening to to him talk. But a subject like Advanced OO patterns can only be cool. So i guess i he chose the right talk to give. Like most talkers he gave some props to Martin Fowler and the Gang of Four. For writing on patterns and refactoring. And basically it&#8217;s a refreshment of studying design patterns. Which i do an a daily basis.</p>
<p>There was one real gem however in this session that i hadn&#8217;t come across yet. Which basically is a way to do lazy loading with objects. This is nothing new. But the framework he used for the talk. Used the new 5.3 closures for this. And i really liked that. So besides the fact that i learned a cool pattern. I also learned a new way of using closures in PHP 5.3.</p>
<p><strong>A great conference</strong></p>
<p>That basically was the conference for me. I really was looking forward to listing in on <a href="http://derickrethans.nl/">Derick&#8217;s</a> talk about profiling PHP applications. But due to my condition i had to stay home the last day and miss this talk. A bit sad. Thankfully he has pretty detailed <a href="http://derickrethans.nl/talks/profiling-dpc11.pdf">PDF</a> up on his site about the talk. </p>
<p>Once again <a href="http://www.ibuildings.nl/">IBuildings</a> did a great job in organizing this event. Thanks guys. You once again did an awesome job. I do have some small notes however. During the sessions i heard a lot of speakers say. This is a sessions for 60 minutes. And i only have 45 minutes. So i have to skip some stuff. I mean come on how long was it known that this event was going to happen. Either give the speakers more time. Or speakers adjust your talks. </p>
<p>Besides the fact that i sometimes had the feeling i was visiting the IBuildings headquarters. It was a great event. Hope to see you there next year.</p>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2011/05/dutch-php-conference-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VIM for a PHP developer</title>
		<link>http://lenss.nl/2011/04/vim-for-a-php-developer/</link>
		<comments>http://lenss.nl/2011/04/vim-for-a-php-developer/#comments</comments>
		<pubDate>Sun, 17 Apr 2011 20:04:28 +0000</pubDate>
		<dc:creator>Thijs Lensselink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[color]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[syntax]]></category>
		<category><![CDATA[theme]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://lenss.nl/?p=1208</guid>
		<description><![CDATA[For my coding work i mostly use Zend Studio. And i am a big fan of this IDE. But i also do a lot of work in the shell. And that asks for at least basic vim knowledge. My colleague is a big vim fan. And does most of his work in vim. So last [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.vim.org/" target="_blank"><img src="http://lenss.nl/wp-content/uploads/2011/04/vim_logo.png" alt="" title="vim_logo" width="80" height="80" class="alignleft size-full wp-image-1222" style="float:left;margin:10px;" /></a>For my coding work i mostly use <a href="http://www.zend.com/en/products/studio/">Zend Studio</a>. And i am a big fan of this IDE. But i also do a lot of work in the shell. And that asks for at least basic <a href="http://www.vim.org/">vim</a> knowledge. My colleague is a big vim fan. And does most of his work in vim. So last week i was compiling a cheat-sheet for my self. And came across a <a href="http://www.slideshare.net/ZendCon/vim-for-php-programmers-presentation">slideshow</a> of one of <a href="http://zmievski.org/">Andrei Zmievski</a>&#8216;s talks. This slide show got me inspired enough to start playing around with vim a bit. And this is the result of it.</p>
<p>We need to have vim installed of course.</p>
<blockquote><p>$ sudo aptitude install vim</p></blockquote>
<p>Vim doesn&#8217;t seem to create the user folder automatically. So we need to create these our self. We&#8217;ll start off with a folder for plugins, color schemes and syntax settings.</p>
<blockquote><p>$ mkdir ~/.vim<br />
$ mkdir ~/.vim/{syntax,colors,plugin}</p></blockquote>
<p>Most of the time i will be editing <strong>.php</strong> files. So i want some good syntax support for that. Vim has a nice plugin system. And there does seem to be a syntax file for PHP <a href="http://www.vim.org/scripts/script.php?script_id=1571">available</a>. It&#8217;s a bit outdated. But will do for now. The only thing to do to enable it is copy it to the plugin directory.</p>
<blockquote><p>$ mv php.vim ~/.vim/syntax</p></blockquote>
<p>Now we have a very powerful but basic PHP editor. That&#8217;s nice and all. I would like to at least have some sort of a project manager. And there is a plugin for that as well. <a href="http://www.vim.org/scripts/script.php?script_id=69">Download</a> &#038; copy!</p>
<blockquote><p>$ mv project.vim ~/.vim/plugin</p></blockquote>
<p>Ok that&#8217;s pretty cool. But it still looks like crap. Time for some theme sugar. It actually took me quite some time to find a theme i like. Guess i am picky. The theme / colour scheme i settled for is called wombat. The <a href="http://dengmao.wordpress.com/2007/01/22/vim-color-scheme-wombat/">original</a> file didn&#8217;t do much for me. But i found a <a href="http://www.vim.org/scripts/script.php?script_id=2465">good</a> 256 colour version.</p>
<blockquote><p>$ mv wombat256mod.vim ~/.vim/colors</p></blockquote>
<p><a href="http://lenss.nl/wp-content/uploads/2011/04/wombat-html.png"><img src="http://lenss.nl/wp-content/uploads/2011/04/wombat-html-300x60.png" alt="" title="wombat-html" width="300" height="60" class="alignleft size-medium wp-image-1215" /></a></p>
<p><a href="http://lenss.nl/wp-content/uploads/2011/04/wombat-php.png"><img src="http://lenss.nl/wp-content/uploads/2011/04/wombat-php-300x128.png" alt="" title="wombat-php" width="300" height="128" class="alignleft size-medium wp-image-1216" /></a></p>
<p>That&#8217;s starting to look like a pretty nice setup. Time to make some settings permanent and to enable some other features.</p>
<blockquote><p>$ vim ~/.vimrc</p></blockquote>
<p>And add some settings</p>
<blockquote><p>
set rule<br />
set wrapscan<br />
set number<br />
set backspace=start,indent,eol</p>
<p>set t_Co=256<br />
colorscheme wombat256mod</p>
<p>autocmd FileType php set omnifunc=phpcomplete#CompletePHP
</p></blockquote>
<p>In the meantime i found this interesting post on Matthew Weier O&#8217;Phinney&#8217;s blog about using <a href="http://weierophinney.net/matthew/archives/134-exuberant-ctags-with-PHP-in-Vim.html">ctags , VIM and PHP</a>. That looks like interesting stuff. So let&#8217;s add it. With <a href="http://ctags.sourceforge.net/">ctags</a> it&#8217;s possible to scan a source tree. And compile a sort of index file that vim can use for lookups. </p>
<blockquote><p>$ sudo aptitude install exuberant-ctags<br />
$ mkdir ~/.vim/tags</p></blockquote>
<p>Creating an index file is a piece of cake. Move to a source directory and issue the following command.</p>
<blockquote><p>$ cd /some/path<br />
$ ctags-exuberant -R -f ~/.vim/tags/filename -h &#8220;.php&#8221;<br />
&#8211;exclude=&#8221;.svn&#8221; &#8211;totals=yes<br />
&#8211;tag-relative=yes &#8211;PHP-kinds=+cf<br />
&#8211;regex-PHP=&#8217;/abstract class ([^ ]*)/\1/c/&#8217;<br />
&#8211;regex-PHP=&#8217;/interface ([^ ]*)/\1/c/&#8217;<br />
&#8211;regex-PHP=&#8217;/(public |static |abstract |protected |private )+function ([^ (]*)/\2/f/&#8217;</p></blockquote>
<p>This will scan the whole directory structure recursively while using the regular expressions to extract useful information from the source files it finds. When done and when the parameter <em>&#8211;totals=yes</em> is used the following output is displayed. But probably with different numbers.</p>
<blockquote><p>2375 files, 466018 lines (14628 kB) scanned in 11.7 seconds (1246 kB/s)<br />
199296 tags added to tag file<br />
199296 tags sorted in 0.00 seconds</p></blockquote>
<p>Time to enable tags. I want to use multiple files. Some standard files for common frameworks / libraries. And a tag file per project.</p>
<blockquote><p>$ vim ~/.vimrc<br />
set tags=tags;~/.vim/tags/filename</p></blockquote>
<p>So let&#8217;s start vim and have a look at what we have so far. The first thing we do when vim has started is launch the :Project plugin.</p>
<blockquote><p>$ vim<br />
:Project</p></blockquote>
<p><a href="http://lenss.nl/wp-content/uploads/2011/04/vim-project-1.png"><img src="http://lenss.nl/wp-content/uploads/2011/04/vim-project-1-300x175.png" alt="" title="vim-project-1" width="300" height="175" class="alignleft size-medium wp-image-1219" /></a></p>
<p><a href="http://lenss.nl/wp-content/uploads/2011/04/vim-project-2.png"><img src="http://lenss.nl/wp-content/uploads/2011/04/vim-project-2-300x174.png" alt="" title="vim-project-2" width="300" height="174" class="alignleft size-medium wp-image-1220" /></a></p>
<p>The project plugin took some time to get used to. But it&#8217;s a very convenient plugin. And easy to get the hang of. It&#8217;s possible to create the project settings by hand. But the plugin comes with a build in tool for this. While in <em>:Project</em> mode and hitting <em>\C</em> will make it easy to create new projects.</p>
<blockquote><p>$ vim<br />
:Project<br />
\C</p></blockquote>
<p>This will guide you through the process with a few short and simple questions.</p>
<blockquote><p>Enter the Name of the Entry: [ project name ]<br />
Enter the Absolute Directory to Load: [ absolute path ]<br />
Enter the CD parameter: [ path to move into ]<br />
Enter the File Filter: [ file filter : *.php ]</p></blockquote>
<p>When that&#8217;s done the screen will be in edit mode inside the .vimproject file. Displaying something like this.</p>
<blockquote><p>
Project name=/path/to/project CD=/path/to/project filter=&#8221;*.php&#8221; {<br />
  filename.ext<br />
  folder&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
}</p></blockquote>
<p>It&#8217;s possible to alter the project setup here. Like adding more files. Or even adding files from other locations outside of the project.</p>
<blockquote><p>Project name=/path/to/project CD=/path/to/project filter=&#8221;*.php&#8221; {<br />
  filename.ext<br />
  folder&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>  External=/some/other/path CD=/some/other/path filter=&#8221;*.php&#8221; {<br />
    filename.ext<br />
  }<br />
}</p></blockquote>
<p>When done editing. Just do like normally in vim.</p>
<blockquote><p>:w</p></blockquote>
<p>Pretty cool we have a project browser on the left. That is easy to navigate with the arrow keys. And a work canvas on the right.</p>
<p>Time to test the ctags created index files. Place the cursor at the beginning of a string that you want to lookup. And hit <strong>CTRL + ]</strong> and <strong>CTRL + T</strong> to get back. Another cool way to open the source file is by using horizontal split windows by using <strong>CTRL + W ]</strong>.</p>
<p>Testing auto-complete is just as easy. Type some php core function name partly <em>str_</em> and hit <strong>CTRL + x</strong> and <strong>CTRL + o</strong>. This will display the following scrollable drop down..</p>
<p><a href="http://lenss.nl/wp-content/uploads/2011/04/vim-autocomplete.png"><img src="http://lenss.nl/wp-content/uploads/2011/04/vim-autocomplete-300x134.png" alt="" title="vim-autocomplete" width="300" height="134" class="alignleft size-medium wp-image-1212" /></a></p>
<p>That&#8217;s about it. I had good fun exploring all the features and possibilities. And have only scratched the surface. One more thing i found on Matthew&#8217;s blog was a way to test and run PHP script from vim. Awesome stuff. You can read about it <a href="http://weierophinney.net/matthew/archives/164-Vim-Productivity-Tips-for-PHP-Developers.html">here</a>. Although i like vim. I don&#8217;t think i will be leaving ZS any time soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://lenss.nl/2011/04/vim-for-a-php-developer/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
