Monday, November 2, 2009

Getting value from an object (or instance of a class) in PHP 5

Just earlier on I was working on the String class in the Samstyle PHP Framework. I was glad that I read the PHP manual and found this magical method in PHP5 OOP called __toString().

Using __toString(), you can actually return a value for the object/instance of a class.

See the example below:

class MyClass{

  function __construct(){
    // constructor
  }

  function __toString(){
    // to String
    return 5;
  }

}

$inst = new MyClass();

echo $inst; // echos 5

How powerful!

Friday, October 30, 2009

jQuery-like chaining in PHP's Object Oriented Programming

It's interesting to see how object methods in PHP can be chained just like jQuery's chaining.

jQuery's chaining:

$("div").children(".firstbtn").hide().fadeIn();

In PHP, it is also possible to chain similarly.

Using the string class from Samstyle PHP Framework, we can do chaining in PHP like this:

echo $str->trim()->replace('a', 'b')->value();

To do chaining in PHP, simply add a return statement at the end your methods where appropriate.

return $this;

Advisable to only do this kind of chaining for Action methods, meaning to say that these methods are only doing actions which are not supposed to return value.

Hope this helps!

Monday, October 12, 2009

file_get_contents() vs fread() - Speed Test and Benchmarking

File access is commonly found in any PHP application. Be it caching, or reading data from a file or what. Lately I've been wondering, whether the use of file_get_contents() over fread() is a good practice (i always prefer file_get_contents()).

So this morning I ran a test between this 2 methods of reading a file. The script I used to run is at http://thephpcode.pastebin.com/f2e84fab1

So here's the result from the tests of 5 runs:
 fread() (seconds)file_get_contents() (seconds)
Mean0.036740.01322
Min0.0307109355926510.0098111629486084
Max0.045550823211670.016166925430298


So here it's clear that file_get_contents() is much faster than fread(), mainly because fread() consists of an overhead additional loop and several functions.

Saturday, October 10, 2009

Using Bit Shifting to Divide / Multiply

To think of it, I rarely use bitwise operators in my coding - especially with all the convenience of other operators (can you imagine calculating bits whole day?).

But seriously when I was reading on Bitwise operators, I realised that ($n / 2) == ($n >> 1). So i tested out and...

By shifting bits, we can actually do multiplication and division. But however, this is only true when ($n / $x) is still a integer.


$n = 1600;

var_dump(($n / 2) == ($n >> 1));
var_dump(($n / 4) == ($n >> 2));
var_dump(($n / 8) == ($n >> 3));
var_dump(($n / 16) == ($n >> 4));

var_dump(($n * 2) == ($n << 1));
var_dump(($n * 4) == ($n << 2));
var_dump(($n * 8) == ($n << 3));
var_dump(($n * 16) == ($n << 4));


I ran some tests on which one is faster, and found that bitshifting is actually much faster.

Here are the results:
 Normal (seconds)Bitshift (seconds)
Mean0.124070.10461
Min0.1229791641240.104335069656
Max0.1260280609130.105180025101
Post to the testing script: http://thephpcode.pastebin.com/f1f6ec979

So when you do some simple math in programming, you know ways to speed things up.

Pre vs Post Increment in PHP

Earlier on I was browsing Google Code, and I chanced upon JSpeed - a javascript optimizer. I saw that they actually change post increments to pre-increments. I wondered why and thought I could ask this on Stack Overflow.

One theory came up to be "preincrement (++i) adds one to the value of i, then returns i; in contrast, i++ returns i then adds one to it, which in theory results in the creation of a temporary variable storing the value of i before the increment operation was applied". -- http://physical-thought.blogspot.com/2008/11/pre-vs-post-increment-speed-test.html

So I thought, what about PHP?

I went on to test it on PHP with a FOR loop and I have the following code:
<?php

$time_start = microtime_float();

for($i = 0; $i<10000000;$i++){

}

$time_end = microtime_float();
$loadedin = (float)($time_end - $time_start);
echo $loadedin.' s
';

$time_start = microtime_float();

for($i = 0; $i<10000000;++$i){

}

$time_end = microtime_float();
$loadedin = (float)($time_end - $time_start);
echo $loadedin.' s
';

function microtime_float(){
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}


?>


Amazingly, pre-increment is much faster than post-increment in PHP. Look at the results:
 Pre-inc (seconds)Post-inc (seconds)
Mean0.686950.74147
Min0.6859259605410.740597963333
Max0.688167810440.743010044098


Thus I conclude that pre-increment is useful in for loops than post-increment. It is much faster through the iterations.

Wednesday, September 23, 2009

Session Denial: session id contains illegal characters

This morning I woke up, went over to StackOverflow (Yes I admit lately I've been quite active answering questions on SO) and I saw this question: Session hijacking or attack?

The asker, Toto, saw these in his error logs:
[22-Sep-2009 21:13:52] PHP Warning: session_start() [function.session-start]: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in /var/my_files/class.session.php on line 67 
[22-Sep-2009 21:13:52] PHP Warning: Unknown: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in Unknown on line 0
[22-Sep-2009 21:13:52] PHP Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct () in Unknown on line 0


The first thing I thought before answering question was that obviously the user had tampered with the PHP session cookie (The cookie name is "PHPSESSID" by default).

So what we can do to prevent these errors is to simply reset the ID whenever the session fails to start:

<?php

$ok = @session_start();
if(!$ok){
session_regenerate_id(true); // replace the Session ID
session_start(); // restart the session (since previous start failed)
}

?>

Note that users tampering/changing the PHPSESSID to generate this error does not affect your server or read/write files on your server. It may be an attempt to generate great amount of log entries into your error logging file and so on. Thus with this solution, you can prevent such things from happening, yet allowing smooth load for normal users.

this piece of security protection has been added to Samstyle PHP Framework (after v1.2.11).

Friday, September 4, 2009

PHP speed up: Quote your strings

I've wanted to post this earlier, but i've been busy lately. So yeah, here's a tip off on how to speed things up for new or beginner php developers.

You might have noticed, PHP error level by default is set to E_ALL & ~E_NOTICE, which means all errors except notices are reported.

Take a look at the following snippet:
<?php

$test = cool;
echo $test;

?>


You might have noticed that it works fine. The output is still "cool".

But when you set the error level to E_ALL, you get to see an additional line like this one:
Notice: Use of undefined constant cool - assumed 'cool' in /public_html/quotestring.php on line 3

This means what when the line "$test = cool;" is parsed, PHP actually look up whether a constant "cool" exists. If not, it will assume that it is the string "cool". This means that extra time is taken to find the constant.

We ran a test to compare between quotes and no-quotes for a string, and also compared between double quotes and single quotes. the result was amazing (the output on browser):

Notice: Use of undefined constant cool - assumed 'cool' in /public_html/quotestring.php on line 4
cool
0.000458002090454 s
cool
9.05990600586E-6 s
cool
8.10623168945E-6 s

The first one is without quotes (look up constants then decide that it is a string). The 2nd one is using double quotes (look if there are variables or control characters to parse then output) and the last one is using single quotes (just output).

The full PHP code for the test results can be found on Pastebin at the following link:
http://thephpcode.pastebin.com/f7bb6a1f9

So remember to quote your strings with single quotes and occasionally use double quotes to speed things up. I am Sam Yong, signing off.

Monday, August 31, 2009

PHP GD: allow PHP to decide image type

It is at times quite troublesome having the need to detect what image type is the file, then decide which function (imagecreatefromjpeg, imagecreatefrompng or imagecreatefromgif) to use for the image. Well, here's a simple solution.

<?php

$src = "http://example.com/image.jpg";
$image = imagecreatefile($src);

function imagecreatefile($f){
$content = file_get_contents($f);
return imagecreatefromstring($content);
}

?>


That's a great and easy way. However, the bad thing is that there will be an overhead of a function and a large variable $content. Having the variable $content in the function scope allows the variable to be disposed at the end of the function, saving memory.

To fix the large variable, you can do this instead:
<?php

$src = "http://example.com/image.jpg";
$image = imagecreatefile($src);

function imagecreatefile($f){
return imagecreatefromstring(file_get_contents($f));
}

?>


Hope it helps!