<?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>Patrick&#039;s playground</title>
	<atom:link href="http://www.vankouteren.eu/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.vankouteren.eu/blog</link>
	<description>Random thoughts, problems and solutions</description>
	<lastBuildDate>Mon, 23 Apr 2012 06:37:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Daycamp 4 Developers #4 Business 101.</title>
		<link>http://www.vankouteren.eu/blog/2012/03/daycamp-4-developers-4-business-101/</link>
		<comments>http://www.vankouteren.eu/blog/2012/03/daycamp-4-developers-4-business-101/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 16:10:33 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[Conference]]></category>
		<category><![CDATA[Daycamp 4 developers]]></category>
		<category><![CDATA[dc4d]]></category>
		<category><![CDATA[freelance]]></category>
		<category><![CDATA[self-employed]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=313</guid>
		<description><![CDATA[Last Saturday the fourth edition of daycamp 4 developers took place. This time’s topic was all about freelancing, entrepreneurship and taking care of your career-life-balance.  Next to some familiar speakers there were also experts from other fields completing the line-up. This blogposts is a summary of the things I’ve learned during this conference, I’ve mixed [...]]]></description>
			<content:encoded><![CDATA[<p>Last Saturday the fourth edition of daycamp 4 developers took place. This time’s topic was all about freelancing, entrepreneurship and taking care of your career-life-balance.  Next to some familiar speakers there were also experts from other fields completing the line-up. This blogposts is a summary of the things I’ve learned during this conference, I’ve mixed them up with my own experiences and opinion, of which this blogpost is a result.<span id="more-313"></span></p>
<p><strong>Time and Money</strong></p>
<p>Lorna Jane Mitchell kicked off the event with her talk on time tracking, planning, estimating and invoicing.</p>
<p>Time tracking is essential for you and your customers. As a freelancer you’re often paid per hour. Therefor you should have a good time tracking system to be able to invoice all the time you’ve spent on the project. (Of course you can also negotiate to be paid per day, or even get a fixed price for a project. Especially the latter one pushes the risk to your side, so most developers like to be paid per hour). Lorna Jane uses <a title="Harvest" href="http://www.getharvest.com/" target="_blank">Harvest </a>for time tracking. Personally I also have good experiences with <a title="Kimai" href="http://www.kimai.org/" target="_blank">Kimai</a>.</p>
<p>One of the first important statements was that not everything is billable (e.g. training, conferences, work that goes into your own venture, corresponding, marketing, blogging etc.)! If 5 to 6 hours per day (based on an 8-hour day) are billable, that’s a lot! Therefor you should carefully decide your rates, write them down, and really stick to them. There’s no use working underpaid. This also affects your image and might influence next project offers. There will probably allways be someone willing to work for less per hour, accept that and focus on your own business.</p>
<p>When you have your rates and your sight is o none or more projects, you should do some proposals / pitches (selling yourself, your solutions and/or ideas). Be sure to outline what you will provide, the details of the project and the benefits and the costs and benefits of it. Your story is very important for acquiring a project even though you might not be the cheapest developer. Real companies prefer quality over money.</p>
<p>If all goes well a contract is set up. Be sure to check the conditions (more on that later in Tara Aaron’s talk) and be sure to agree on: a payment method (how are you going to be paid?), the invoice date, frequency (weekly basis? monthly basis? Other frequencies..), payment terms and a last important one: the valuta. Is your invoice in euro? Pounds? Dollars? (Also note the exchange rate if you’re invoicing in a foreign valuta!)</p>
<p>Once you got the project and the contract is signed, the planning starts. This is one of the things I could learn a lot from. First: add deadlines to your calendar. Then block out time for appointments. Now you’re calendar skeleton is set up, you can book your work into the gaps in your calendar, but <span style="text-decoration: underline;">don’t overschedule!</span> Once the schedule is filled, you can ask yourself: when can I deliver X? Can I also take on Y. Again: <span style="text-decoration: underline;">don’t overschedule.</span> If you don’t have spare time as a freelancer, you’re doing something wrong.</p>
<p>Regarding invoicing and taxes, it’s important to track information ongoingly. Not only your time, but also all tax-related stuff. As we are developers, Financial and tax-related stuff is often not one of our strongest points, so you might want to consider asking an accountant to handle this for you. He or she also often knows about particular regulations of which your company can benefit.</p>
<p>&nbsp;</p>
<p><strong>So you want to be self-employed?</strong></p>
<p>&nbsp;</p>
<p>The second talk about being self-employed was given by Jacques Woodcock. His keys to making it great:</p>
<ul>
<li>Go through shit</li>
<li>Working for a company provides you great experience. The better the company, the better it will be for you</li>
<li>Build skills</li>
<li>Build a network</li>
<li>Know your services</li>
</ul>
<p>I’ve also learned a term that wasn’t explained to me before: moonlighter. A moonlighter is someone who works for x hours after work.</p>
<p>When you’re starting your own company / freelancing career, you should consider your service offerings. Some questions that you should answer include:</p>
<ul>
<li>What do you offer?</li>
<li>What do your competitors offer? Can you do all of it?</li>
<li>Will you be hunting for everything or for a niche?</li>
<li>Will you need contractors?</li>
</ul>
<p>Basically there is a decision to be made regarding your service model and based on that you identify your competitors. If you want to do it all, your competitors will be agencies. Most often these companies will be larger than you. This, however does not mean that you don’t stand a chance. As a startup / freelancer you should fully utilize your agility and flexibility to your advantage. You can switch between markets / projects / resources quicker when you’re on your own.</p>
<p>Of course you can also supply a niche market. This allows you to work for companies as well as agency, hence increasing your potential customers and network.</p>
<p>Next to the service model, you need to decide what exactly you want to offer. Offering a service means direct revenu, but you got to keep working. However, there’s no need for money in the bank to start, but you need work.</p>
<p>If you choose to provide Software as a Service, you first have to invest and revenue comes later (if revenue will come..). But when you’re done your (basically) done and caching. Without further work (theoretically..). However, as you need to develop the software first, there’s a need for 6 or more months of money in the bank to ensure your life upkeep.</p>
<p>The consensus about entrepreneurship: As an entrepreneur, you need to be able to identify opportunities and to take chances. You are tied to your company and you need to work harder than when working for an employer. The satisfaction, however, should compensate this.</p>
<p>&nbsp;</p>
<p><strong>Planning your business for the long term</strong></p>
<p>&nbsp;</p>
<p>Thursday Bram’s talk on business plans and the execution of them starts where the story of Jacques Woodcock ends: so you’ve decided you want to be self-employed. Now what?</p>
<p>Now you’ve got a lot to think about. Therefor you need a business plan. Your busines plan is the roadmap to succes. Typically this plan has a span of only 3 to 5 years. It outlines the route to take to reach, maintain and grow revenues. Many people are scared of the idea of writing a business plan, but Thursday emphasised that the outline can be very simple (bullet points, a checklist etc.)</p>
<p>A business is an investment. You have to pay your bills, you have to pay yourself, you have to pay other stuff like hardware, software, conferences etc. The most important point of this presentation, at least to my opinion, is to always start with the numbers. You have the need for a full-time income, while the bills and other stuff must also be paid. All these numbers should be taken into account when deciding on your rates. The freelancing attendees’ rates were ranging between 55 and 85 euro per hour.</p>
<p>Please note: The numbers you calculate based on the information above are for now. They don’t allow for growth. You have to assume that you will need more in the future!</p>
<p>&nbsp;</p>
<p><strong>Put it in writing</strong></p>
<p>&nbsp;</p>
<p>Tara Aaron, a total non-technical speaker. On a developers conference. Awesome!</p>
<p>Something which a lot of developers are concerned about is Intellectual Property, how to protect it and when it is transferred. This is something you have to pay attention to when composing the contract. Details of the contract should contain:</p>
<ul>
<li>The payment</li>
<li>The duration and termination of the project</li>
<li>A project plan and/or statement of work</li>
<li>Intellectual Property language</li>
<li>‘Legalese’</li>
</ul>
<p>When selling your software, you are selling your source code, as well as your Intellectual Property unless stated otherwise (and agreed upon by both parties of course). To retain your code and Intellectual Property, licensing might be a better option.</p>
<p>As the American legal system is different from the European (in my case: Dutch) legal system, not all information was useful for me. Especially for Dutch developers, there is the blog of <a title="Arnoud Engelfriet" href="http://www.arnoud.engelfriet.net/" target="_blank">Arnoud Engelfried</a> who has also written a book on legal terms and software. Be sure to check that out!</p>
<p>&nbsp;</p>
<p><strong>Is it good for the company?</strong></p>
<p>&nbsp;</p>
<p>With the focus on being self-employed, this talk by John Mertic might seem to be given at the wrong conference. However, the practical aspects are also applicable to freelancers accepting a project at a company. For example: an internal project.</p>
<p>For making the project a success, you have to:</p>
<ul>
<li>Know the people: Who are the people that make things happen and who are just the ‘talkers’.</li>
<li>Know the issues: What are the actual problems, rather than annoying artifacts</li>
<li>Know the history: How did it get this far? Was it developed in-house? Was it consulted?</li>
<li>Know the process: How do you get things done? Do you need 1 or 20 signatures?</li>
</ul>
<p>So, how to set up a proposal for improving things (and convincing the people who make the actual ‘yes’ or ‘no’ decision): Look at the metrics. What are the costs now (in terms of both time and money) ? What will the costs be in the future? How does the proposed project improve the organization?</p>
<p>Business people don’t want you to tell a story for an hour. Use PowerPoint, Keynote or any other presentation software to create a presentation for them. They don’t read documents. Presentations force you to summarize and present the main story you want to tell. After all: you have to tell a story to sell your story.</p>
<p>For telling and selling this story, you can use the Narrative Framework:</p>
<ul>
<li>What do you do now, what are the pain points in it, and what needs to be done to improve them?</li>
<li>What you’d like to see happen</li>
<li>What it takes to get there</li>
</ul>
<p>&nbsp;</p>
<p><strong>Career &amp; Life Management</strong></p>
<p>&nbsp;</p>
<p>The last talk was given by the excellent Paul M. Jones and was all about the thin line between work and life (the so-called work-life-balance). Life is not all about work. ‘You need to take care of your shit’.  That means: pay off your debts, have 3 to 6, or even better: 9 months of expenses in cash. Think about your insurances (what happens to your wife, kids etc. when you die unexpectedly?). Think about your retirement and possibly about the college of your kids. Take the time out to think about it, settle it, review it from time to time.</p>
<p>The summary of the career management is in an iteration form:</p>
<ol>
<li>Always be looking for work</li>
<li>Choose between jobs. Aim for a job which provides you with more resources (which doesn’t only mean more money..) than you currently have</li>
<li>Go to 1.</li>
</ol>
<p>Simple. Short. Clear.</p>
<p>Of course this does not completely map 1:1 to your life and your life style, but the message is clear: progress in your professional career and reflect this in your life. If you’re standing still, you and your close relatives are standing still while others around you progress. Think of L’Oreal: “Because you’re worth it.”.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>So, this was Daycamp 4 Developers #4 summarized. It was awesome. A big thank you to Cal Evans for organizing the conference. Looking forward to #5!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2012/03/daycamp-4-developers-4-business-101/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Practical: creating a REST application with Silex</title>
		<link>http://www.vankouteren.eu/blog/2012/02/practical-creating-a-rest-application-with-silex/</link>
		<comments>http://www.vankouteren.eu/blog/2012/02/practical-creating-a-rest-application-with-silex/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 10:46:10 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Silex]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=302</guid>
		<description><![CDATA[Okay, you’ve read LornaJane’s blogpost series on REST, you’ve attended the Techademy Silex/REST workshop to hear Stefan Koopmanschap talk about Silex and Joshua Thijssen about REST, seen the post of Dave Marshall on REST so what now? Try and create a REST example application with Silex of course! This blogpost describes my steps creating this [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, you’ve read LornaJane’s <a title="blogpost series on REST" href="http://www.lornajane.net/posts/2012/building-a-restful-php-server-understanding-the-request" target="_blank">blogpost series on REST</a>, you’ve attended the Techademy <a title="Silex / REST workshop" href="http://techademy.nl/januari-2012-silex-rest/" target="_blank">Silex/REST workshop</a> to hear Stefan Koopmanschap talk about Silex and Joshua Thijssen about REST, seen <a title="Dave Marshall on REST" href="http://davedevelopment.co.uk/2012/02/16/how-im-doing-rest.html" target="_blank">the post</a> of Dave Marshall on REST so what now?</p>
<p>Try and create a REST example application with Silex of course! This blogpost describes my steps creating this example application from front to back.</p>
<p>The order in which I’ve written down and done things is not pre-defined. There are multiple orders to achieve the same result. This is just the way I did it.<span id="more-302"></span></p>
<p>First off: If you use a web server, be sure to check whether or not the IonCube extension is loaded. This is because IonCube &lt; v 2.0.9 doesn’t work with PHAR files.</p>
<p>So let’s start off by checking if Silex will run on the server:</p>
<p>Set up directory structure. I chose to have a folder ‘lib’ for storing silex.phar and other optional external stuff and to have a folder ‘http’ where all web accessible scripts are located. Purely based on personal taste. (I don’t like a document root full of files).</p>
<p>Download silex.phar from <a title="http://silex.sensiolabs.org/" href="http://silex.sensiolabs.org/" target="_blank">silex.sensiolabs.org</a> and put the phar file in the lib dir. Get the .htaccess file from the website and put it in the http dir. Put create an index.php file with the following contents:</p>
<p>&nbsp;</p>
<p>Now navigate your browser to &lt;your webhost url&gt;/&lt;this project’s folder&gt;/http/index.php/hello/&lt;your name&gt;. It should display ‘Hello, &lt;your name&gt;’. If not, the line $app[‘debug’] = true; will help you with a stacktrace. Once you got Silex working, go to the next step.</p>
<p>&nbsp;</p>
<p><strong>REST</strong></p>
<p>We want to perform four operations on resources: POST, GET, PUT and DELETE. These correspond to Create, Read, Update and Delete. But note: <a title="CRUD =/= REST" href="http://www.rgoarchitects.com/nblog/2009/06/23/CRUDIsBadForREST.aspx" target="_blank">CRUD =/= REST</a>, but <a title="it helps" href="http://blog.dhananjaynene.com/2009/08/crud-is-not-only-good-for-but-is-the-only-consistent-way-to-build-rest-over-http/" target="_blank">it helps</a>!</p>
<p>As Silex is able to determine the differences between all four HTTP methods, we don’t have to worry about that. Because Silex contains the HttpFoundations of Symfony2, it allows us to define the HTTP status code and message very easy. The only thing left to do is to define when to return what. Let’s look into more detail on that.</p>
<p>&nbsp;</p>
<p><strong>Response codes</strong></p>
<p>For creation of a resource, the POST header will be used. On succes, we return a HTTP response code 201, created. The body will contain the newly created resource. On failure we return a response code 400: Bad request.</p>
<p>For reading a resource we use the GET header. On succes, we return a response code 200, OK, with the resource content. When a resource cannot be found, we return an HTTP response code 404: Not found with no content.</p>
<p>For updating a resource the PUT header is used. On success we return a response code 200, OK, with the (updated) resource content. When an error occurs, we return a response code 400: Bad request.</p>
<p>For deletion of a resource the DELETE header is used. On success, we return a response code 204, No content, with (guess what..) no content, as the resource doesn’t exist any more. When the request cannot be processed, we return a response code 400: Bad request.</p>
<p>&nbsp;</p>
<p><strong>Data source</strong></p>
<p>So let’s use a database for storing our (small amount of) data. The (SQL) schema can be found in data/database.sql. In Silex we define a connection ($app[‘con’]) which is opened before execution and closed afterwards. For this, the methods before() and after() are used.</p>
<p>&nbsp;</p>
<p><strong>Returning data types</strong></p>
<p>Let’s add some complexity.. we want to be able to return xml and json. There are several options to determine which data to return. In this example we’ll return a format based on the extension provided, but it could also be done by looking at the request (which format the requesting party will accept).</p>
<p>For putting the results in the appropriate format we use Twig, which is the default templating engine (although you have to download is ‘install’ it separately). We also assign twig to $app and we’re set to go with it.</p>
<p>For picking up the format itself, we use the {format} variable in the routing. We use this to determine the template for twig to render. The templates are located in lib/twig/templates (which is also defined in the script).</p>
<p>&nbsp;</p>
<p><strong>Resource setup</strong></p>
<p>As said earlier: REST =/= CRUD. Here’s another one: database schema =/= resource. Some ORM software implementing the Active Record may give you this idea, but there’s a difference. A resource is a ‘natural’ resource. You can construct a resource from data from various tables and/or rows. This is also done in the books resource: we not only use records from the books table, but also from genre and author.</p>
<p>&nbsp;</p>
<p><em>Creating a resource: POSTing data</em></p>
<p>Line 121 starts the function which will create a genre resource. First off we check if all data is present to create the resource. In this case it’s simply the genre name. If not all data is present, the request is not okay and we return a 400 Response (Bad Request) to the requester. Next we will check if that genre already exists to prevent duplicate genres. If the genre already exists we provide an HTTP 301 to denote to the requester that that particular genre resource already exists on another resource location. If the genre doesn’t exist yet, we create it and return the newly created resource to the user,  with an HTTP 201 (Created).</p>
<p>&nbsp;</p>
<p><em>Getting a resource: GETting data</em></p>
<p>The get method is defined at line 100. This is pretty straightforward: either a resource exists or it doesn’t exist. We query the database for the requested genre. If it doesn’t exist, we return an HTTP 404 (Not Found), else we return an HTTP 200 with the requested resource.</p>
<p>&nbsp;</p>
<p><em>Updating a resource: PUTting data</em></p>
<p>At line 168, the put method is defined. This operation checks if all data is present. If not, it returns an HTTP 400. After that it checks if the resource actually exists. If it doesn’t exist we return the common HTTP 404. If it does exist, we update the data and return the updated resource with an HTTP 200 to show that all went well.</p>
<p>&nbsp;</p>
<p><em>Deleting a resource: DELETE data</em></p>
<p>The delete method is defined at line 219. This is a pretty straightforward again: If the resource doesn’t exist we just return a 404. If it does exist, we delete it from the database. As the resource doesn’t exist any more, we confirm deletion by sending back an empty message to the client with an HTTP 204 (No Content) header.</p>
<p>&nbsp;</p>
<p><strong>Time for some code!</strong></p>
<p>&nbsp;</p>
<p>The full project, including Silex, twig and the twig templates can be found on my <a title="my downloads page" href="http://www.vankouteren.eu/downloads/">downloads page</a>.</p>
<p>&nbsp;</p>
<p><strong>Notes</strong></p>
<p>These are my first steps in creating a RESTful implementation in Silex. I know that the code is not optimal, nor does it separate concerns in an MVC way. This is just a ‘quick’ example as a supplement to all theoretical examples without any practical examples.</p>
<p>However: any feedback is very welcome. I’ll be adding more code and, given enough to talk about, blogposts in the near future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2012/02/practical-creating-a-rest-application-with-silex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP SPL data structure: SplFixedArray</title>
		<link>http://www.vankouteren.eu/blog/2011/09/php-spl-data-structure-splfixedarray/</link>
		<comments>http://www.vankouteren.eu/blog/2011/09/php-spl-data-structure-splfixedarray/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 14:51:31 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[memory usage]]></category>
		<category><![CDATA[speed]]></category>
		<category><![CDATA[SplFixedArray]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=267</guid>
		<description><![CDATA[PHP 5.3 introduced some new data structures. The talk of Jurriën Stutterheim on PFCongres 2011 on SPL structures and their performance triggered me to have a closer look at the performance of these structures. I was kind of fooled by two comments on the PHP.net page, so it was time to find out myself. For [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushPhp.js"></script>
<p>PHP 5.3 introduced some new data structures. The talk of Jurriën Stutterheim on<a title="PFCongres" href="http://www.pfcongres.nl/"> PFCongres 2011</a> on SPL structures and their performance triggered me to have a closer look at the performance of these structures. I was kind of fooled by two comments on the <a title="SplFixedArray PHP.net page" href="http://www.php.net/manual/en/class.splfixedarray.php">PHP.net page</a>, so it was time to find out myself.</p>
<p><span id="more-267"></span>For people familiar with Java the SplFixedArray is not a strange structure as they are common structures in this language. PHP only used arrays in the past.</p>
<p>The common array structure may contain all kind of keys (one can use strings, integers and even combine them) and under the hood PHP uses a hashing algorithm to create a unique array index for these keys. So actually under the hood these arrays are comparable to Java HashMaps. Like a database can create indexes on keys, PHP creates an index on the hashed indexes to speed up item retrieval from the array. However: hashing does not guarantee a unique output for every unique input. It may well be that two completely different keys result in a same hashed value. A hashing algorithm can sort this out in its own way (there are various way to do this, but I think this is out of the scope of this post right now), so there's another level of complexity here.</p>
<p>The new SplFixedArray has a pre-defined size and can only contain integer keys. As the size is limited this saves memory and the indexing is done more efficient. It does away with all hashing related issues which saves time. Now the question is: how much time does it save me?</p>
<p><strong>Hey: we're running PHP, not Java.. I didn't have to bother with memory usage, why would I do that now all of a sudden?</strong></p>
<p>You don't have to if you don't like to, but there may be a lot to gain for you. Especially when you are using a lot of arrays of which you know the size beforehand as well as the positions of items. In an environment which often is under heavy load the benefits of SplFixedArray may come in handy for you. (And updating software is cheaper than updating hardware..)</p>
<p><strong>Numbers</strong></p>
<p>As I said I was fooled at first by two comments on the <a title="PHP.net SplFixedArray" href="http://www.php.net/manual/en/class.splfixedarray.php">PHP.net manual</a>: <a title="SplFixedArray test 1" href="http://www.php.net/manual/en/class.splfixedarray.php#92214">this one</a> and <a title="SplFixedArray test 2" href="http://www.php.net/manual/en/class.splfixedarray.php#94179">this one</a>.</p>
<p>The first one tests the speed of insertions in the regular array and the speed of insertions in the SplFixedArray and returns all positives for the SplFixedArray.</p>
<p>The latter one claims to be more realistic, but results in a fatal error directly because the author is trying to insert items on positions outside the range of the SplFixedArray (index out of bounds exception, also common in Java). If this is a realistic example I would reconsider using PHP <img src='http://www.vankouteren.eu/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>I've compiled a simple script to test the speeds and memory sizes of array vs SplFixedArray. To (kind of) prevent small background processes influencing the results these tests are done multiple times and averaged. The results are shown below. Please note that these results may vary every time you execute the script. However: the larger the size of the array, the less variance occurs and the more reliable the numbers are.</p>
<p><em>script:</em></p>
<p><pre class="brush: php">&lt;?php

$maxSize = (int) $_GET['size'];
$times = (int) $_GET['times'];

set_time_limit(0);

echo &quot;&lt;h2&gt;Number of repeated tests: &quot; . $times . &quot;&lt;/h2&gt;&quot;;
echo &quot;&lt;table border='1'&gt;&quot;;
echo &quot;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Items&lt;/th&gt;&lt;th&gt;Time Array&lt;/th&gt;&lt;th&gt;Memory Array&lt;/th&gt;&lt;th&gt;SplFixedArray&lt;/th&gt;&lt;th&gt;Memory SplFixedArray&lt;/th&gt;&lt;th&gt;Array/SplFixedArray ratio&lt;/th&gt;&lt;th&gt;Speed increase by SplFixedArray&lt;/th&gt;&lt;th&gt;Memory reduction by SplFixedArray&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&quot;;
echo &quot;&lt;tbody&gt;&quot;;

for($size = 1000; $size &lt; $maxSize; $size *= 2) {
	
	echo &quot;&lt;tr&gt;&lt;td align='right'&gt;&quot; . $size . &quot;&lt;/td&gt;&quot;;
	
	$arrTotal = 0;
	$arrMemUsage = 0;
	for($time = 0; $time &lt; $times; $time++){
		$mStart = memory_get_usage();
		$container1 = array();
		for($s = microtime(true), $i = 0; $i &lt; $size; $i++) {
			$container1[$i] = 1;
		}
		
		$arrMemUsage += (memory_get_usage() - $mStart);
		$arrTime = (microtime(true) - $s);
		$arrTotal += $arrTime;
	}
	
	$avgArrMem = ($arrMemUsage / $times);
	$avgArr = ($arrTotal / $times);
	echo &quot;&lt;td align='right'&gt;&quot; . $avgArr  . &quot;&lt;/td&gt;&quot;;
	echo &quot;&lt;td align='right'&gt;&quot; . $avgArrMem . &quot;&lt;/td&gt;&quot;;
	// Cleanup to REDUCE the influence of memory blocks on the result
	unset($arrTotal);
	unset($arrMemUsage);
	unset($container1);
	
	$splFixedArrTotal = 0;
	$splFixedArrMemUsage = 0;
	for($time = 0; $time &lt; $times; $time++){
		$mStart = memory_get_usage();
		$container2 = new SplFixedArray($size);
		for($s = microtime(true), $i = 0; $i &lt; $size; $i++) {
			$container2[$i] = 1;
		}
		
		$splFixedArrMemUsage += (memory_get_usage() - $mStart);
		$splFixedArrTime = (microtime(true) - $s);
		$splFixedArrTotal += $splFixedArrTime;
	}
	
	$avgSplFixedArrMem = ($splFixedArrMemUsage / $times);
	$avgSplFixedArr = ($splFixedArrTotal / $times);
	echo &quot;&lt;td align='right'&gt;&quot; . $avgSplFixedArr . &quot;&lt;/td&gt;&quot;;
	echo &quot;&lt;td align='right'&gt;&quot; . $avgSplFixedArrMem . &quot;&lt;/td&gt;&quot;;
	// Cleanup to REDUCE the influence of memory blocks on the result
	unset($splFixedArrTotal);
	unset($splFixedArrMemUsage);
	unset($container2);
	
	// Calculate ratio
	echo &quot;&lt;td align='right'&gt;&quot; . ($avgArr / $avgSplFixedArr) . &quot;&lt;/td&gt;&quot;;
	// Calculate speed increase percentage
	echo &quot;&lt;td align='right'&gt;&quot; . number_format(((($avgSplFixedArr - $avgArr) / $avgArr) * -100), 4) . &quot; %&lt;/td&gt;&quot;;
	// Calculated memory reduction percentage
	if ($avgArrMem == 0){
		echo &quot;&lt;td align='right'&gt;NaN&lt;/td&gt;&lt;/tr&gt;&quot;;
	}
	else {
		echo &quot;&lt;td align='right'&gt;&quot; . number_format(((($avgSplFixedArrMem - $avgArrMem) / $avgArrMem) * -100), 4) . &quot; %&lt;/td&gt;&lt;/tr&gt;&quot;;
	}
	
	// Cleanup to REDUCE the influence of memory blocks on the result
	unset($avgArr);
	unset($avgSplFixedArr);

}

echo &quot;&lt;/tbody&gt;&lt;/table&gt;&quot;;

?&gt;</pre></p>
<p><em>results:</em></p>
<p><a href="http://www.vankouteren.eu/blog/wp-content/uploads/2011/09/arrayvssplfixedarrayresult.jpg">Results (regular table didn't fit the page)</a></p>
<p><strong>So what does it say?</strong></p>
<p><strong></strong>Well regarding the memory the usage has been decreased by around 58% in this case. This, of course, is due to the fact that the SplFixedArray has a limited size and therefor a (pre-defined) limited space in the memory reserved. There is some gain in speed as well.</p>
<p><strong>So is it better to use?</strong></p>
<p>That really depends. The SplFixedArray has some advantages, but also some drawbacks compared to the common array. It should be used where it fits: if you need an array of a size which can be pre-defined and where you need integer keys. It's also a good (at least, I think.. but I started with Java..) habit to use the appropriate data structures.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2011/09/php-spl-data-structure-splfixedarray/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using SimpleAdapter for populating simple_list_item_2 with Strings</title>
		<link>http://www.vankouteren.eu/blog/2011/09/using-simpleadapter-for-populating-simple_list_item_2-with-strings/</link>
		<comments>http://www.vankouteren.eu/blog/2011/09/using-simpleadapter-for-populating-simple_list_item_2-with-strings/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 06:29:00 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[JAVA]]></category>
		<category><![CDATA[ListView]]></category>
		<category><![CDATA[simpe_list_item_row_2]]></category>
		<category><![CDATA[SimpleAdapter]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=264</guid>
		<description><![CDATA[I don't know it it's my searching skills which are fading or the lack of examples, but I wasn't able to find a simple example on how to use the simple_list_item_2 which is built into Android. I've used some custom layouts to establish the same result, and sometimes some extras (display an icon on the [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushPhp.js"></script>
<p>I don't know it it's my searching skills which are fading or the lack of examples, but I wasn't able to find a simple example on how to use the simple_list_item_2 which is built into Android. I've used some custom layouts to establish the same result, and sometimes some extras (display an icon on the right for example). However, now I wanted to use the built-in feature, but had to search quite some time. If you experience the same, hopefully this post will save you time.</p>
<p><span id="more-264"></span>I know: it's basic, but I'm still learning Android, so I think I may behave like a n00b at the moment <img src='http://www.vankouteren.eu/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>So, what do we need for setting up the list:</p>
<ul>
<li>screen layout</li>
<li>activity</li>
<li>list content</li>
</ul>
<p>Let's go! First create a layout:</p>
<p>&nbsp;</p>
<p>Note that the list has an id called '@android:id/list'. This enables us to directly use the list in the Activity as it's going to extend ListActivity.</p>
<p>In the Activity itself we define an ArrayList containing HashMaps from String to String. Basically this means that we create a list which will contain key, value pairs which we are going to control (This is similar to associative arrays in PHP). We will use the key 'line1' for the upper line and 'line2' for the lower line. With the variables from and to we map the values of the keys we supply (this is the from variable) to the TextViews of the simple_list_item_row_2 (the to variable). These are called text1 and text2.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2011/09/using-simpleadapter-for-populating-simple_list_item_2-with-strings/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Custom checkboxes for CheckBoxPreferences on Android</title>
		<link>http://www.vankouteren.eu/blog/2011/09/custom-checkboxes-for-checkboxpreferences-on-android/</link>
		<comments>http://www.vankouteren.eu/blog/2011/09/custom-checkboxes-for-checkboxpreferences-on-android/#comments</comments>
		<pubDate>Thu, 01 Sep 2011 22:10:39 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[JAVA]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=261</guid>
		<description><![CDATA[For an App I'm writing I need to use custom checkboxes in a PreferenceScreen. I want to use the CheckboxPreferences as it's designed for that. Many searches lead to StackOverflow, but caused me a stack overflow as well as they didn't work. In this (short) post I outline my findings and provide a working solution [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushPhp.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushXml.js"></script>
<p>For an App I'm writing I need to use custom checkboxes in a PreferenceScreen. I want to use the CheckboxPreferences as it's designed for that. Many searches lead to StackOverflow, but caused me a stack overflow as well as they didn't work. In this (short) post I outline my findings and provide a working solution step by step.<span id="more-261"></span></p>
<p><strong>Step 1</strong></p>
<p>You need a custom checkbox. This can be defined in a drawable. In this case I've called the file checkbox.xml and placed it in the drawable folder. The code defines the images for two states: if the checkbox is enabled and when it's disabled. For this file looks like this:</p>
<p><pre class="brush: xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;selector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
    &lt;item android:state_checked=&quot;true&quot;
          android:drawable=&quot;@drawable/checkbox_checked&quot; /&gt; &lt;!-- checked --&gt;
    &lt;item android:state_checked=&quot;false&quot; 
    	android:drawable=&quot;@drawable/checkbox_unchecked&quot; /&gt; &lt;!-- default --&gt;
&lt;/selector&gt;</pre></p>
<p><strong>Step 2</strong></p>
<p>We need a layout for customized preferences. This layout defines the same stuff as the ' regular'  preference does (text, summary etc.). Note the last part in the following file (called checkbox_preference.xml and placed in the layout folder). It loads our custom checkbox!</p>
<p><pre class="brush: xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!-- Copyright (C) 2006 The Android Open Source Project Licensed under the 
    Apache License, Version 2.0 (the &quot;License&quot;); you may not use this file except 
    in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
    Unless required by applicable law or agreed to in writing, software distributed 
    under the License is distributed on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES 
    OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
    the specific language governing permissions and limitations under the License. --&gt;

&lt;!-- Layout for a Preference in a PreferenceActivity. The Preference is able 
    to place a specific widget for its particular type in the &quot;widget_frame&quot; 
    layout. --&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;fill_parent&quot; android:layout_height=&quot;wrap_content&quot;
    android:minHeight=&quot;?android:attr/listPreferredItemHeight&quot;
    android:gravity=&quot;center_vertical&quot; android:paddingRight=&quot;?android:attr/scrollbarSize&quot;&gt;

    &lt;RelativeLayout android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot; android:layout_marginLeft=&quot;15dip&quot;
        android:layout_marginRight=&quot;6dip&quot; android:layout_marginTop=&quot;6dip&quot;
        android:layout_marginBottom=&quot;6dip&quot; android:layout_weight=&quot;1&quot;&gt;

        &lt;TextView android:id=&quot;@+android:id/title&quot;
            android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;
            android:singleLine=&quot;true&quot; android:textAppearance=&quot;?android:attr/textAppearanceLarge&quot;
            android:ellipsize=&quot;marquee&quot; android:fadingEdge=&quot;horizontal&quot; /&gt;

        &lt;TextView android:id=&quot;@+android:id/summary&quot;
            android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;
            android:layout_below=&quot;@android:id/title&quot; android:layout_alignLeft=&quot;@android:id/title&quot;
            android:textAppearance=&quot;?android:attr/textAppearanceSmall&quot;
            android:maxLines=&quot;4&quot; /&gt;

    &lt;/RelativeLayout&gt;

&lt;CheckBox android:id=&quot;@+android:id/checkbox&quot;
		android:layout_width=&quot;wrap_content&quot;
		android:layout_height=&quot;wrap_content&quot;
		android:button=&quot;@drawable/checkbox&quot; /&gt;

&lt;/LinearLayout&gt;</pre></p>
<p><strong>Step 3</strong></p>
<p>Now the code below is the actual layout which you inflate with your SharedPreferences in your Activity. The layout attribute is used to put the custom layout with the custom checkbox as an item in there.</p>
<p><pre class="brush: xml"> &lt;PreferenceScreen xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;

	&lt;PreferenceCategory
		android:title=&quot;@string/category_title&quot;&gt;
		
	&lt;CheckBoxPreference
	android:key=&quot;preferenceKey&quot;
	android:title=&quot;@string/preferenceTitle&quot;
	android:defaultValue=&quot;false&quot;
	android:layout=&quot;@layout/checkbox_preference&quot;
	/&gt;
	&lt;/PreferenceCategory&gt;
&lt;/PreferenceScreen&gt;</pre></p>
<p><strong>Step 4</strong></p>
<p>There is no step 4. You're done! It shouldn't be that hard to find and use these things. Unfortunately many same questions, but more different (and often not / not completely working replies / solutions) are posed on sites like StackOverflow which makes it harder to find the real solution. Hopefully this post is a worthy addition to the interwebs and a valuable resource for Android designers facing the same problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2011/09/custom-checkboxes-for-checkboxpreferences-on-android/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Propel and the zero date issue</title>
		<link>http://www.vankouteren.eu/blog/2011/06/propel-and-the-zero-date-issue/</link>
		<comments>http://www.vankouteren.eu/blog/2011/06/propel-and-the-zero-date-issue/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 11:58:47 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[0000-00-00]]></category>
		<category><![CDATA[Propel 1.5.4]]></category>
		<category><![CDATA[Propel 1.6.0]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=255</guid>
		<description><![CDATA[Today I was unpleasantly surprised by a change in behavior when upgrading Propel from version 1.5.4 to 1.6. I frequently use zero dates in MySQL ('0000-00-00') and these dates are affected by the upgrade. As it was deployment time I had to find a solution quickly. This post outlines what the problem is and what [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushPhp.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushXml.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushSql.js"></script>
<p>Today I was unpleasantly surprised by a change in behavior when upgrading Propel from version 1.5.4 to 1.6. I frequently use zero dates in MySQL ('0000-00-00') and these dates are affected by the upgrade. As it was deployment time I had to find a solution quickly. This post outlines what the problem is and what I did to solve it.<span id="more-255"></span><br />
So what's all the fuzz about? It's about a query like this:<br />
<pre class="brush: php">$contractObjectCollection = ContractQuery::create()
            -&gt;filterByOrderId($this-&gt;getID())
            -&gt;condition('contractToAfterNow', 'Contract.ContractTo &gt; ?', date('Y-m-d'))
            -&gt;condition('contractToIsNul', 'Contract.ContractTo = ?', '0000-00-00')
            -&gt;combine(array('contractToAfterNow', 'contractToIsNul'), 'or', 'contractToCondition')
            -&gt;condition('contractFromIsFilledIn', 'Contract.ContractFrom &lt;= ?', date('Y-m-d'))
            -&gt;combine(array('contractToCondition', 'contractFromIsFilledIn'))
            -&gt;orderByContractFrom('asc')
            -&gt;orderByContractId('asc')
            -&gt;find();</pre></p>
<p>This query gathers contracts which are active (e.g. valid, started and not ended) at this moment.<br />
In Propel 1.5.4 this code translates to the following query:<br />
<pre class="brush: sql">SELECT contract.* FROM `contract` WHERE contract.ORDER_ID='1' AND ((contract.CONTRACT_TO &gt; '2011-06-07' OR contract.CONTRACT_TO = '0000-00-00') AND contract.CONTRACT_FROM &lt;= '2011-06-07') ORDER BY contract.CONTRACT_FROM ASC,contract.CONTRACT_ID ASC</pre></p>
<p>However, in Propel 1.6.0 the code translates to:<br />
<pre class="brush: sql">SELECT contract.* FROM `contract` WHERE contract.ORDER_ID='1' AND ((contract.CONTRACT_TO &gt; '2011-06-07' OR contract.CONTRACT_TO = '-0001-11-30') AND contract.CONTRACT_FROM &lt;= '2011-06-07') ORDER BY contract.CONTRACT_FROM ASC,contract.CONTRACT_ID ASC</pre></p>
<p>Instead of putting 0000-00-00 in the query, the date is translated to -0001-30-11. (Should I read this as 30th of November 1969?)<br />
As my code relies heavily on the outcome of the query, I had to find a quick solution. After some informing on IRC I learned that there seems to be an issue concerning these zero dates (Propel prefers using NULL instead of 0000-00-00, but my application is a legacy application).<br />
The actual solution comes down to writing the query by hand, using the (Debug)PDO instance for querying and using the PropelObjectFormatter to hydrate the results back into the objects you want to be working with.</p>
<p>&nbsp;</p>
<p>And that's it. It cost me a little time to figure this out, but my deployment was saved.</p>
<p><strong>Slight note</strong><br />
Please note that Propel normally puts all fields separately in the SELECT statement, but that I've shortened it by putting down the * sign</p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2011/06/propel-and-the-zero-date-issue/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Your Plesk Watchdog in 2011</title>
		<link>http://www.vankouteren.eu/blog/2011/01/your-plesk-watchdog-in-2011/</link>
		<comments>http://www.vankouteren.eu/blog/2011/01/your-plesk-watchdog-in-2011/#comments</comments>
		<pubDate>Fri, 14 Jan 2011 07:55:17 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[Plesk]]></category>
		<category><![CDATA[Webhosting]]></category>
		<category><![CDATA[2011]]></category>
		<category><![CDATA[Watchdog]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=235</guid>
		<description><![CDATA[Plesk users (version 8.x up to 10.x as far as I've heared) are getting errors from the Watchdog module. Parallels is coming out with an update for this error in the future, but they can't tell when (yet). These errors occur on daily basis and are actually pretty easy to fix. You might have two [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushPhp.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushXml.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushSql.js"></script>
<p>Plesk users (version 8.x up to 10.x as far as I've heared) are getting errors from the Watchdog module. Parallels is coming out with an update for this error in the future, but they can't tell when (yet). These errors occur on daily basis and are actually pretty easy to fix. You might have two errors (after each other), but this fix will solve them <a href="http://forum.parallels.com/showpost.php?p=435312&amp;postcount=73" target="_blank">both</a>.</p>
<p><span id="more-235"></span></p>
<p>The first error which occurs since the first of January 2011 is the following one:</p>
<p><pre class="brush: sql">ERROR: WDExc

Error occurred while processing database query: 'MySQL query failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group by service_id, type, round(unix_timestamp(time) / 200, 0) having count(val' at line 3'

0: wdlib.php:1089

wd__db_query(string 'select service_id, type, unix_timestamp(min(time)) as min_time, unix_timestamp(max(time)) as max_time, avg(value) as avg

from module_watchdog_sys_stat where

group by service_id, type, round(unix_timestamp(time) / 200, 0) having count(value) &gt; 1 limit 10000;')

1: pack-sysstats:63

pack_statistics(integer '200', boolean  false, boolean  false)

2: pack-sysstats:44</pre></p>
<p>At the time being I was running Plesk 9.5.2. As Plesk 10 was out, I thought that would fix the problem. It kind of did, as I got a different error message:</p>
<p><pre class="brush: php">/usr/local/psa/libexec/modules/watchdog/cp/pack-sysstats: line 1: ?php: No such file or directory

/usr/local/psa/libexec/modules/watchdog/cp/pack-sysstats: line 2: syntax error near unexpected token `&quot;The file {$_SERVER['SCRIPT_FILENAME']} is part of Plesk 9 distribution. It cannot be run outside of Plesk 9 environment.\n&quot;'

/usr/local/psa/libexec/modules/watchdog/cp/pack-sysstats: line 2: `    die(&quot;The file {$_SERVER['SCRIPT_FILENAME']} is part of Plesk 9 distribution. It cannot be run outside of Plesk 9 environment.\n&quot;);'</pre></p>
<p>Fortunately I got some help through Twitter (@ParallelsPanel) and the Parallels Forum. The fix can be found <a title="Watchdog 2011 fix" href="http://forum.parallels.com/showpost.php?p=434456&amp;postcount=42" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2011/01/your-plesk-watchdog-in-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing packages on Synology NAS through ipkg</title>
		<link>http://www.vankouteren.eu/blog/2010/09/installing-packages-on-synology-nas-through-ipkg/</link>
		<comments>http://www.vankouteren.eu/blog/2010/09/installing-packages-on-synology-nas-through-ipkg/#comments</comments>
		<pubDate>Thu, 16 Sep 2010 10:01:00 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[ipkg]]></category>
		<category><![CDATA[nas]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[synology]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=231</guid>
		<description><![CDATA[Recently I bought a Synology DS210j NAS. This is a linux-based NAS with an ARM processor. As this basically is a full linux server, there are some interesting options for geeks familiar with the command-line. As I am a developer, I would like to be able to use version control for my projects. The NAS [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushPhp.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushXml.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushSql.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushCpp.js"></script>
<p>Recently I bought a Synology DS210j NAS. This is a linux-based NAS with an ARM processor. As this basically is a full linux server, there are some interesting options for geeks familiar with the command-line.<span id="more-231"></span><br />
As I am a developer, I would like to be able to use version control for my projects. The NAS offers the possibility to install Subversion. The Synology wiki is excellent regarding instructions for installing the package manager (ipkg), Subversion. I prefer vim over vi. Vi is already installed on the NAS, but vim isn't. This can be easily installed through ipkg as well.<br />
This post will not fully describe the steps of installing all the mentioned stuff (this is well documented at the wiki), but it will describe some items to notice when installing.</p>
<ol>
<li>First enable the command-line to be available. This can be done through the administration panel (go to <em>Network Services &gt; Terminal</em>). You can choose between Telnet or SSH. (<a href="http://forum.synology.com/wiki/index.php/Overview:_What_is_CLI,_how_do_I_access_it,_SSH_or_Telnet%3F" target="_blank">Source</a>). Don't forget to enable the port (23 or 22 respectively) in the firewall so you can access the command-line.</li>
<li>Create a shared folder through the administration panel (<em>Privileges &gt; Shared Folder</em>). Call it anything you want. I called it plain 'svn'.</li>
<li>Create an SVN user through the administration panel (<em>Privileges &gt; User</em>) and give this user Read/write privileges through the Privileges setup tab. You will need this user later on.</li>
<li>Although the NAS is linux-based, it doesn't have a package manager yet. Although it isn't necessary to have this, it makes life easier for you. You can install the ipkg bootstrap. After that you can use the ipkg package manager to install packages easily. For installing the right bootstrap, you first need to know what kind of processor is present in your NAS. You can check that <a title="What kind of CPU does my NAS have" href="http://forum.synology.com/wiki/index.php/What_kind_of_CPU_does_my_NAS_have" target="_blank">here</a>. After that, you can install the ipkg bootstrap by following the instructions at the bootstrap section on <a title="installing ipkg bootstrap" href="http://forum.synology.com/wiki/index.php/Overview_on_modifying_the_Synology_Server,_bootstrap,_ipkg_etc" target="_blank">this page</a>.</li>
<li>After that, you can use the <em>ipkg install</em> command. To install vim, you can type 'ipkg install vim'. When using vim the arrow keys may not work. To fix this hit the Esc key and type :set term=builtin_ansi then hit enter.  If you don’t want to have to keep entering that command each time you start vim then you can create a configuration file called .vimrc and place it in your home folder: <em>vim /home/root/.vimrc</em> Put the following two lines in the file:<br />
<pre class="brush: cpp">:set term=builtin_ansi
:set ruler</pre><br />
The :set ruler will enable the line and column number your cursor is on when editing a text file. (<a href="http://www.jedge.com/docs/configure%20ipaq%20for%20use.pdf" target="_blank">source</a>)</li>
<li>The above steps weren't all 100% clear to me. To install Subversion, proceed to follow <a href="http://forum.synology.com/wiki/index.php/Step-by-step_guide_to_installing_Subversion#Install_Subversion_Package" target="_blank">this wiki entry</a> beginning at the 'Installing Subversion Package' section. You've performed the first couple of steps already.</li>
</ol>
<p>&nbsp;</p>
<p><strong>Upgrading PEAR to 1.9.4: out of memory</strong></p>
<p>When I was trying to upgrade PEAR from version 1.9.1 to 1.9.4 I encountered two problems.</p>
<p>Two packages could not be found. This was not 100% clear from the error message (the packages could not be initialized, error on line 0). Fortunately ipkg could install the two packages (bzip and xslt) and the problem was solved.</p>
<p>When upgrading pear ('pear upgrade pear'), the installer used too much memory resources. As pear runs on PHP itself, this problem can be solved by opening the php ini file (location: /opt/etc/php.ini) and raising the default memory_limit (in my case memory_limit = 8M) to a higher value. After that PEAR upgrades just fine.</p>
<p>&nbsp;</p>
<p><strong>Thanks</strong></p>
<p>Thumbs up for Synology for not only creating a great (and stable) product, but also for the good documentation on a lot of subjects you can come up with!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2010/09/installing-packages-on-synology-nas-through-ipkg/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Starting a CLI script from PHP</title>
		<link>http://www.vankouteren.eu/blog/2010/06/starting-a-cli-script-from-php/</link>
		<comments>http://www.vankouteren.eu/blog/2010/06/starting-a-cli-script-from-php/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 10:05:45 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[background process]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[exec]]></category>
		<category><![CDATA[ignore_user_abort]]></category>
		<category><![CDATA[passthru]]></category>
		<category><![CDATA[pcntl]]></category>
		<category><![CDATA[shell_exec]]></category>
		<category><![CDATA[system]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=205</guid>
		<description><![CDATA[For quite some time I've searched for a way to start a command line script from within a page in PHP without using the crontab. Basically I just wanted to start a script which does some processing in the background. The solution is pretty simple, but it took me some time to find it.We all [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushPhp.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushXml.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushSql.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushCpp.js"></script>
<p>For quite some time I've searched for a way to start a command line script from within a page in PHP without using the crontab. Basically I just wanted to start a script which does some processing in the background. The solution is pretty simple, but it took me some time to find it.<span id="more-205"></span>We all know the crontab: it can execute a script at a particular moment for you, based on what you define to be the moment. But what if you want to execute a background at the moment you would like to?</p>
<p>PHP defines four methods which can execute commands: <a title="exec" href="http://www.php.net/manual/en/function.exec.php" target="_blank">exec</a>, <a title="passthru" href="http://www.php.net/manual/en/function.passthru.php" target="_blank">passthru</a>, <a title="shell_exec" href="http://www.php.net/manual/en/function.shell-exec.php" target="_blank">shell_exec</a> and <a title="system" href="http://www.php.net/manual/en/function.system.php" target="_blank">system</a>. These methods wait for the script to finish and collect the output generated by that script. However, when a user leaves the page, closes his browser or stops the script, the background script which is executed is also stopped. To prevent this, people tend to use other options like <a title="pcntl" href="http://php.net/manual/en/book.pcntl.php" target="_blank">pcnt</a>l or <a title="cURL" href="http://www.php.net/manual/en/book.curl.php" target="_blank">cURL</a>. Using these extensions might offer a solution, but for simply starting a script they are much too verbose.</p>
<p>The solution presented is applicable in the situation where you just need to start a script and you don't want users to be able to stop the script after starting. And the solution is....</p>
<p>The function <a title="ignore_user_abort" href="http://www.php.net/manual/en/function.ignore-user-abort.php" target="_blank">ignore_user_abort()</a>.</p>
<p>By putting this function in front of a shell_exec execution, the script still starts the script executed by shell_exec. However, it doesn't care any more if the user aborts the calling script. In my situation, the CLI script updates a status file and a progress file. When running, the status file contains an integer which denotes that the CLI script is running. This prevents the script from being run again while it's already running. Furthermore, the progress file is updated so the progress can be checked by other scripts.</p>
<p><strong>Source</strong></p>
<p><strong><a href="http://stackoverflow.com/questions/265073/php-background-processes">http://stackoverflow.com/questions/265073/php-background-processes</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2010/06/starting-a-cli-script-from-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP multidimensional array to plain text tree structure</title>
		<link>http://www.vankouteren.eu/blog/2010/04/php-multidimensional-array-to-plain-text-tree-structure/</link>
		<comments>http://www.vankouteren.eu/blog/2010/04/php-multidimensional-array-to-plain-text-tree-structure/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 12:33:05 +0000</pubDate>
		<dc:creator>Patrick van Kouteren</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[multidimensional array]]></category>
		<category><![CDATA[Tree]]></category>

		<guid isPermaLink="false">http://www.vankouteren.eu/blog/?p=197</guid>
		<description><![CDATA[Not for the first time I've searched for a way to visualize a multidimensional array in a tree view in my web browser without directly using echo or print. I wasn't able to find a concrete solution for this previously. However, this time I was put on the right track by a post of Kevin [...]]]></description>
			<content:encoded><![CDATA[            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushPhp.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushXml.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushSql.js"></script>
            <script type="text/javascript" src="http://www.vankouteren.eu/blog/wp-content/plugins/wordpress-code-snippet/scripts/shBrushCpp.js"></script>
<p>Not for the first time I've searched for a way to visualize a multidimensional array in a tree view in my web browser without directly using echo or print. I wasn't able to find a concrete solution for this previously. However, this time I was put on the right track by a post of <a href="http://kevin.vanzonneveld.net/techblog/article/convert_anything_to_tree_structures_in_php/" title="Convert anything to Tree Structures in PHP">Kevin van Zonneveld</a>. <span id="more-197"></span>I've given it my own (quick and dirty as can be seen from the code) twist to get it to work. By just calling:</p>
<p><pre class="brush: php">print implode(ArrayFunctions::toString($array));</pre></p>
<p>The array is shown as a tree structure on the screen.<br />
The implementation is as follows:</p>
<p><pre class="brush: php">&lt;?php
class ArrayFunctions {
  public static function toString($array){
    $result = array();
    $depth = 0;
    foreach($array as $k =&gt; $v) {
            $show_val = ( is_array($v) ? &quot;&quot; : $v );
 
            // show the indents
            $result []= str_repeat(&quot;  &quot;, $depth);
            if($depth == 0) {
                // this is a root node. no parents
                $result []= &quot;O &quot;;
            } elseif(is_array($v)) {
                // this is a normal node. parents and children
                $result []= &quot;+ &quot;;
            } else {
                // this is a leaf node. no children
                $result []= &quot;- &quot;;
            }
 
            // show the actual node
            if ($show_val == &quot;&quot;) {
                $result []= &quot;&lt;strong&gt;{$k}&lt;/strong&gt;:
&quot;;
            }
            else {
                $result []= $k . &quot; (&quot;.$show_val.&quot;)&quot;.&quot;
&quot;;
            }
 
            if(is_array($v)) {
                // this is what makes it recursive, rerun for childs
                $temp = self::toTree($v, ($depth+1));
                foreach($temp as $t) {
                    $result []= $t;
                }
            }
        }
        return implode($result);
    }
 
    private static function showtype($show_val) {
        // convert bools to text and quote 'text bools'!
        if (is_string($show_val) &amp;&amp;
           ($show_val == &quot;true&quot; || $show_val == &quot;false&quot;)) {
            return &quot;\&quot;{$show_val}\&quot;&quot;;
        }
        elseif (is_bool($show_val) &amp;&amp; $show_val === true) {
            return &quot;true&quot;;
        }
        elseif (is_bool($show_val) &amp;&amp; $show_val === false) {
            return &quot;false&quot;;
        }
        elseif (is_null($show_val)) {
            return &quot;null&quot;;
        }
        else {
            return $show_val;
        }
    }
 
    private static function toTree($pieces, $depth = 0) {
        foreach($pieces as $k =&gt; $v) {
            // skip the baseval thingy. Not a real node.
            //if($k == &quot;__base_val&quot;) continue;
            // determine the real value of this node.
            $show_val = ( is_array($v) ? &quot;&quot; : $v );
 
            $show_val = self::showtype($show_val);
 
            // show the indents
            $result []= str_repeat(&quot;  &quot;, $depth);
            if($depth == 0) {
                // this is a root node. no parents
                $result []= &quot;O &quot;;
            } elseif(is_array($v)) {
                // this is a normal node. parents and children
                $result []= &quot;+ &quot;;
            } else {
                // this is a leaf node. no children
                $result []= &quot;- &quot;;
            }
 
            // show the actual node
            if ($show_val == &quot;&quot;) {
                $result []= &quot;&lt;strong&gt;{$k}&lt;/strong&gt;:
&quot;;
            }
            else {
                $result []= $k . &quot;: &lt;i&gt;{$show_val}&lt;/i&gt;
&quot;;
            }
 
            if(is_array($v)) {
                // this is what makes it recursive, rerun for childs
                $temp = self::toTree($v, ($depth+1));
                if (is_array($temp)) {
                    foreach($temp as $t) {
                        $result []= $t;
                    }
                }
                else {
                    $result []= $t;
                }
            }
        }
        return $result;
    }
}
?&gt;</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.vankouteren.eu/blog/2010/04/php-multidimensional-array-to-plain-text-tree-structure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

