A Raid to the local Bookstore

Permanent Link: A Raid to the local Bookstore 31. Januar 2009 Comment One Comment

When it comes to buying books i am so 1992. I do buy some at onlineshops, but most time i need to be there  i the local bookstore. Today i found some books i had on my watchlist for a time:

The Productive Programmer

Anyone who develops software for a living needs a proven way to produce it better, faster, and cheaper. The Productive Programmer offers critical timesaving and productivity tools that you can adopt right away, no matter what platform you use. Master developer Neal Ford not only offers advice on the mechanics of productivity-how to work smarter, spurn interruptions, get the most out your computer, and avoid repetition-he also details valuable practices that will help you elude common traps, improve your code, and become more valuable to your team.

from: Amazon

Beeing productive as a programmer is always an issue. And since we have newbies to the programming bizz in our company it is maybe a good way to get around the beast Code Complete.

Implementation Patterns

The Kent Beck Signature Book series was nice from the beginning on. Starting with the read of Patterns of Enterprise Application Architecture I bought (but did not already read) all of that series. Getting a new one into my fingers is nice. I guess the thing goes the same direction as the above stated, just  a bit more focus on the "how to ake great api" part.

Great code doesn’t just function: it clearly and consistently communicates your intentions, allowing other programmers to understand your code, rely on it, and modify it with confidence. But great code doesn’t just happen. It is the outcome of hundreds of small but critical decisions programmers make every single day. Now, legendary software innovator Kent Beck–known worldwide for creating Extreme Programming and pioneering software patterns and test-driven development–focuses on these critical decisions, unearthing powerful “implementation patterns” for writing programs that are simpler, clearer, better organized, and more cost effective.

from: Amazon

Art of Capacity Planning

Success on the web is measured by usage and growth. Web-based companies live or die by the ability to scale their infrastructure to accommodate increasing demand. This book is a hands-on and practical guide to planning for such growth, with many techniques and considerations to help you plan, deploy, and manage web application infrastructure. The Art of Capacity Planning is written by the manager of data operations for the world-famous photo-sharing site Flickr.com, now owned by Yahoo! John Allspaw combines personal anecdotes from many phases of Flickr's growth with insights from his colleagues in many other industries to give you solid guidelines for measuring your growth, predicting trends, and making cost-effective preparations. Topics include: Evaluating tools for measurement and deployment Capacity analysis and prediction for storage, database, and application servers Designing architectures to easily add and measure capacity Handling sudden spikes Predicting exponential and explosive growth How cloud services such as EC2 can fit into a capacity strategy ….

from: Amazon

Far away from guidelines like "How o write a performant php script" etc. Just a more strategic guide of how to plan survival of the next big wave of users on your website. Pretty small book, but a good companion if you are in the "lots of users" bizz. Helps open the eyes for the things that happen outside of your code, and might get you a hint of sleeping well even with a growing  wewbapp.

Die Kunst des Webtrackings

Since our app and daily work is about webtracking, this handy little 300 page book just hits the shelfes in the right moment, just waiting to be picked up.

see: Amazon.de

No interesting books about php, just a good one about zend framework would be nice, but as far as i know, there is not yet anything.

Maybe someone who is stopping by here has a hint what can be next of my neverending list of books, best related to the stuff posted here. ;)

Using array_unique() with multidimensional arrays

Permanent Link: Using array_unique() with multidimensional arrays 31. Januar 2009 Comment Comments (19)

There's one problem with array_unique(): It doesn't work with multidimensional arrays. Here's an example:

$array = array(
array(
'id' => 123,
'name' => 'Some Product',
'ean' => '1234567890123'
),
array(
'id' => 123,
'name' => 'Some Product',
'ean' => '4852950174938'
),
array(
'id' => 123,
'name' => 'Some Product',
'ean' => '1234567890123'
),
);
$uniqueArray = array_unique($array);
var_dump($uniqueArray);

Two elements are exactly the same, but one element has a different EAN, yet the var_dump() returns the following:

array(1) {
[0]=>
array(3) {
["id"]=>
int(123)
["name"]=>
string(12) "Some Product"
["ean"]=>
string(13) "1234567890123"
}
}

Obviously this is unexpected behaviour. array_unique() threw out the second element, which is clearly not the same as Element 1 and 3. The easiest way I came across is using md5 hashes for comparison of the elements. All you need is to iterate over the first dimension, serialize it and create a MD5 hash of it for comparison:

/**
* Create Unique Arrays using an md5 hash
*
* @param array $array
* @return array
*/
function arrayUnique($array, $preserveKeys = false)
{
// Unique Array for return
$arrayRewrite = array();
// Array with the md5 hashes
$arrayHashes = array();
foreach($array as $key => $item) {
// Serialize the current element and create a md5 hash
$hash = md5(serialize($item));
// If the md5 didn't come up yet, add the element to
// to arrayRewrite, otherwise drop it
if (!isset($arrayHashes[$hash])) {
// Save the current element hash
$arrayHashes[$hash] = $hash;
// Add element to the unique Array
if ($preserveKeys) {
$arrayRewrite[$key] = $item;
} else {
$arrayRewrite[] = $item;
}
}
}
return $arrayRewrite;
}

$uniqueArray = arrayUnique($array);
var_dump($uniqueArray);

Now the result is the one array_unique() should have already given:

array(2) {
[0]=>
array(3) {
["id"]=>
int(123)
["name"]=>
string(12) "Some Product"
["ean"]=>
string(13) "1234567890123"
}
[1]=>
array(3) {
["id"]=>
int(123)
["name"]=>
string(12) "Some Product"
["ean"]=>
string(13) "4852950174938"
}
}

This works with as many dimensions as you like.

Hello i am the new guy

Permanent Link: Hello i am the new guy 30. Januar 2009 Comment No Comment

My Name is  Sebastian Schürmann and i am the new guy on board. Dominik allowed me to use this blog as well to express my thoughts about

  • Development
  • Agile stuff
  • and so on

First post follows soon.

Extending interfaces

Permanent Link: Extending interfaces 21. Januar 2009 Comment No Comment

What many people don't know is that you cannot only extend classes in PHP but also interfaces:

interface First_Interface
{
public function show();
}

interface Second_Interface extends First_Interface
{
public function update();
}

class Product implements Second_Interface
{
public function show() {}
public function update() {}
}

You have to remember though that extending is not possible when you have the same function in both interfaces:

interface Second_Interface extends First_Interface
{
    public function show();
    public function update();
}

This will lead to a PHP Fatal Error:
PHP Fatal error:  Can't inherit abstract function First_Interface::show() (previously declared abstract in Second_Interface) in /tmp/interfaces.php on line 8

Fatal error: Can't inherit abstract function First_Interface::show() (previously declared abstract in Second_Interface) in /tmp/interfaces.php on line 8

Note: This possibility is also described in the PHP documentation for interfaces (Example #3)

JavaScript loops profiled

Permanent Link: JavaScript loops profiled 20. Januar 2009 Comment Comments (2)

Today I was curious and wanted to know which way of looping in JavaScript fastest. So far, I always use for var i in array, since someone once told me, it is the fastest way. For testing I created an Array with 10000 elements:

ids = [];
for (var i = 1; i <= 10000; i++) {
ids.push(i);
}

I used the JavaScript Profiler of Firebug for profiling. The testsystem was: Intel Dual Core T2500 @ 2.00 GHz, 2 GB RAM, Ubuntu 8.04, Firefox 3.0.5 (only installed addon is Firebug). I profiled each loop variation 5 times and took the average time for comparison. The loop variations did nothing but loop and were the following:

Loop 1:

for(var i = 0; i < ids.length; i++) {}

Loop 2:

for (var i in ids) {}

Loop 3:

function process(element, index, array) {}
ids.forEach(process);

When I started the test, I didn't think there would be such huge differences in the performance of those three:

JavaScript loops profiled

Here are the profiling results in detail, in case you're interested (all times in ms):

Loop 1:
1,428
0,842
0,987
0,833
0,831

Loop 2:
6,084
4,471
6,040
6,256
6,509

Loop 3 (number in brackets is the profiled runtime of the function process() - see declaration above)
33,055 (16,439)
33,262 (16,489)
33,792 (17,044)
34,682 (17,312)
35,875 (17,637)

Using count() in for()-loops

Permanent Link: Using count() in for()-loops 16. Januar 2009 Comment Comments (3)

Since I just stumbled across it again, here's a common "mistake" often done, which can be avoided very easily. Situation is an array, that is looped over using for(). It might look something like this:

$elements = array(
'Element 1',
'Element 2',
'Element 3',
'Element 4',
'Element 5',
);

for ($i = 1; $i <= count($elements); $i++) {
print('Processing Element #' .$i . PHP_EOL);
}

This is bad coding style because the count() is in the loop header. In this case everytime the loop moves on to the next element, the function count() is called (here 5 times), although the size of the array never changes. The right (and more performant) way to do this, would be:

$elementsCount = count($elements);
for ($i = 1; $i <= $elementsCount; $i++) {
print('Processing Element #' .$i . PHP_EOL);
}

Now count() is only called once and the code does exactly the same.

Detecting mobile devices

Permanent Link: Detecting mobile devices 13. Januar 2009 Comment Comments (6)

Nowadays it is getting more important to having his website also readable for mobile clients. While there is the possibility of using WURFL for detection, WURFL seems to be a bit overhead when you only want to display simple contents (mostly text). I agree, that you should use WURFL, or similar, if you're planning on providing media contents, such as videos. Still, you have to keep at the back of your mind, that it is very unlikely that you will have users using a 3 year old Siemens Mobile Phone browsing your website. The target consumers are definately iPhone users or any other user with a newer mobile phone.

When browsing to your website, people want to type the known adress (e.g. www.phpdevblog.net) instead of a new adress (e.g. www.phpdevblog.net/mobile). So obviously the best way would be to detect users using mobile devices and redirecting them to the mobile adress or using another Front Controller or… (the decision is up to you). An easy way is to check the users Useragent in order to detect mobile devices. I will show you two examples, one covering server-side detection (using php - obviously) and the other covering client-side detection using JavaScript. Both ways should cover most mobile devices, if you have any additions please let me know! Thank you

Edit on Februar 3rd, 2009: I added the needed string for Android phones to the arrays

Server-Side detection:

class Client
{
/**
* Available Mobile Clients
*
* @var array
*/
private $_mobileClients = array(
"midp",
"240x320",
"blackberry",
"netfront",
"nokia",
"panasonic",
"portalmmm",
"sharp",
"sie-",
"sonyericsson",
"symbian",
"windows ce",
"benq",
"mda",
"mot-",
"opera mini",
"philips",
"pocket pc",
"sagem",
"samsung",
"sda",
"sgh-",
"vodafone",
"xda",
"iphone",
"android"
);

/**
* Check if client is a mobile client
*
* @param string $userAgent
* @return boolean
*/
public function isMobileClient($userAgent)
{
$userAgent = strtolower($userAgent);
foreach($this->_mobileClients as $mobileClient) {
if (strstr($userAgent, $mobileClient)) {
return true;
}
}
return false;
}

}

$client = new Client();
$client->isMobileClient($_SERVER['HTTP_USER_AGENT']);

Client-Side detection:

function Client() {
}

Client.prototype.mobileClients = [
"midp",
"240x320",
"blackberry",
"netfront",
"nokia",
"panasonic",
"portalmmm",
"sharp",
"sie-",
"sonyericsson",
"symbian",
"windows ce",
"benq",
"mda",
"mot-",
"opera mini",
"philips",
"pocket pc",
"sagem",
"samsung",
"sda",
"sgh-",
"vodafone",
"xda",
"iphone",
"android"
];

Client.prototype.isMobileClient = function(userAgent)
{
userAgent=userAgent.toLowerCase();
for (var i in this.mobileClients) {
if (userAgent.indexOf(this.mobileClients[i]) != -1) {
return true;
}
}
return false;
}

var client = new Client();
client.isMobileClient(navigator.userAgent);

Seven dwarfs, eh things about me you don’t really want to know

Permanent Link: Seven dwarfs, eh things about me you don’t really want to know 9. Januar 2009 Comment No Comment

Since I got selected by Ralf Eggert to tell 7 random and weird things about me, here is my first non-coding related post in this blog:

  • I did my first webpage in MS Word(!) back in 1998 and uploaded it with a 14,4k modem (Those were the days!)
  • Like Ralf, I have a red-green color blindness
  • According to my gf my shorts have strange colors
  • I finished playing Half-Life 2 today and started with HL2 Episode One
  • David Hasselhoff is my personal hero ;D
  • I don't like Sushi
  • Favorite quote: Eat your vegetables! (From the movie "Shoot 'Em Up")

Now it's the turn of the following 7 people:

And here are the rules

  • Link your original tagger(s), and list these rules on your blog.
  • Share seven facts about yourself in the post - some random, some wierd.
  • Tag seven people at the end of your post by leaving their names and the links to their blogs.
  • Let them know they’ve been tagged by leaving a comment on their blogs and/or Twitter.

Strange behaviour of date()

Permanent Link: Strange behaviour of date() 2. Januar 2009 Comment Comments (4)

Recently I used time and date functions to calculate an ETA and remaining running time for a longer running script. When showing the remaining time using the date() function I encountered some strange behaviour:

According to the documentation date() expects the second parameter to be a UNIX Timestamp, which - as we all know - starts at 01.01.1970 00:00:00. Meaning when you print out date('H:i', 0) you'd expect to get 00:00. For some reason this is not the case:

php > print date('H:i', 0);
01:00

Does anyone know why this is the case? In my script I did a workaround by simply substracting one hour, which isn't the best style obviously.

(Note: I used the php interactive shell you can run by executing php -a to print out the date)

< Dezember 2008 | Februar 2009 >