Thursday, December 31, 2009

fontreplace - PHP/jQuery Font Replacement (FLIR)

Lately I was quite into web design and interface so much that I started exploring sIFR and FLIR. Yesterday I decided to develop a FLIR for PHP and jQuery.

You can download the fontreplace package at: http://www.mediafire.com/?0o511knwywm (122 kB, zip format).

Features:
  • PHP 4.4.2 and above compatible
  • Uses jQuery Javascript Framework
  • Transparent background for CSS background support
  • Lightweight
  • Reads font color, font size, and font dynamically.
  • Detects whether user has font before loading from server
  • 100% SEO Friendly and minimal code changes
  • Supports font color RGBA with alpha.
  • Tested working on IE7, IE8, FF 2.0, 3.0, 3.5, Safari (Win) 4.0 and Chrome 3.0, 4.0

The demo and example is inside the zip file. Place the content of the zip file on a PHP-enabled server and run it on the browser.

Sunday, December 27, 2009

The Art of Password Protection in PHP

While I was working on some algorithm on PHP earlier on, I began to thought about the methods of password protection when I was still a novice in PHP, till now where I stand. Here's a little bit on how I went through the stages of password protection.

The Art of Password Protection, MD5, SHA1, Salting, php code

Of course my website wasn't hack and I wasn't that bad NOT to hash the password at all. When I started off building my first website, betaPod, I actually used MD5 for password to be hashed. Afterwhich, I learnt about how MD5 passwords can be rainbow-tabled and cracked, and came to know about what is called salting.

Then when I thought that if salting is not enough, I came up with positions of the salt based on the password entered, which makes the hash very unique and secured.

You can definitely use the code in the image.

Wednesday, November 25, 2009

Issues with multiple requests on PHP

Again today I was answering questions on StackOverflow when I came across the question about not being able to load pages when downloading/loading large files.

If you are using session, I suggest you use session_write_close() before you output the file to the browser.

This is because when the session is opened on one page, you cannot load another page until the session has been written and released. session_write_close() is called automatically when your script ends, but because your outputting process takes time before your script end, your session file is locked and thus other pages cannot be viewed.

However, if you are using different browser and/or system, it will be ok because the session file locked is unique to each SESSION ID.

Look at: http://php.net/manual/en/function.session-write-close.php

However do take note that after session_write_close(), you cannot call session_start() or there will be a warning. Also if you make changes to $_SESSION, it will not take effect.

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!

Thursday, August 27, 2009

PHP new development site/manual

I was browsing the web earlier on, and I chanced upon one of the PHP website development server at http://pb11.php.net/

Some comments:
the interface (UI) is definitely much better and everything's clearer.
however, the layout and contents are much about the same from the current one.

So you can try it out at http://pb11.php.net/

Take note that the mirror is unofficial and is not updated to the latest.

Monday, August 24, 2009

Optimize your code: Keep functions out of statements!

It's always said that we should think out of the box. In any programming language, we should write functions out of certain statements statements.

Consider this:
<?php

$arr = array(/* 10000 elements */);
for($i = 0; $i < count($arr); $i++){
// ...
}

?>


If you work this out slowly using a debugger or what, you would have noticed that count($arr) will be called for each iteration of the for loop! Each time you call count($arr), count() actually works out your array size and if your array is huge, the script will be stuck at this loop for a few seconds.

So what about doing something like this?
<?php

$arr = array(/* 10000 elements */);
$l = count($arr);
for($i = 0; $i < $l; $i++){
// ...
}

?>

Isn't this logically cleaner and faster in execution?

This also applies to while loop.

PHP Arrays - End vs Indices

I've looked through the PHP Arrays function list lately while working on some php scripts that requires lots of interaction with Arrays. It came to me that the following 2 are the identical:

$value = end($array);
$value2 = $array[count($array)-1];

But which is more efficient?

In a test, I tested both with a 1000 elements array. A total of 5 tests were ran and an average of 0.00040926s for using end() and 0.00041699s for using $arr[count($arr)-1].

That was only a single dimension array. Which means that all the elements are non-arrays. The moment i ran on a 2 dimensional array, the test results differ! Again I ran 5 tests, and an average of 0.00070285s for using end() and 0.00040769s for $arr[count($arr)-1].

Why? end() has to move the internal pointer of the array all the way to the end of the array. However, end() is still useful for arrays whose keys are not numeric.

The codes for the test can be found on pastebin at http://thephpcode.pastebin.com/f7fa7d00c

Friday, August 14, 2009

MySQL transaction (rollback+commit) - better with PHP

Lately I've been working on a project that has MySQL tables with relationship to each other. I have several functions that accesses the Database, and one function to call all these functions. However, I need to know that if one of the function that accesses the database fails, I need to do a rollback.

Here's how we can do it:

<?php
function addShop($shop){

$ok = true;
$ok = $ok && mysql_query('START TRANSACTION');

$ok = $ok && shops_AddShop($shop);
$ok = $ok && ($shop['id'] = mysql_insert_id());
$ok = $ok && shops_UpdateCategories($shop);

if($ok){
mysql_query('COMMIT');
}else{
mysql_query('ROLLBACK');
}

return $ok;
}

?>


If one of the MySQL queries failed, I can do a rollback and reverse the appropriate changes. It's much better taking advantage of the short circuit evaluation as talked about earlier on.

In that case you will have a more stable application.

Getting function name in a function

I came to this time when I was doing recursive functions. I thought that if I change the function name, I will have to change the name again in the codes within the function. Consider the function below.

<?php

function a($v){
$ret = array();
if(is_array($v))
{
foreach($v as $k){
$ret[] = a($k);
}
}else{
$ret = $v;
}
return $ret;
}

?>


If i were to change the function name, and I forgot to change the one within the code, I will cause myself an error and debug intensively.

However using backtrace, I am able to get the function name when inside a function. The function below enables you to get the function name when called.

<?php

function func_name(){
$bt = debug_backtrace();
$ret = '';
if(isset($bt[1]) && isset($bt[1]['function'])){
$ret = $bt[1]['function'];
}
return $ret;
}

?>


So to get the first function working even after changing function name:

<?php

function a($v){
$ret = array();
if(is_array($v))
{
$f = func_name();
foreach($v as $k){
$ret[] = $f($k);
}
}else{
$ret = $v;
}
return $ret;
}

?>


And there you have it!

This function was extracted from the php class (/class/php.class.php) of the fast and lightweight PHP framework - Samstyle PHP Framework 1.2.9 Alpha

Sunday, August 9, 2009

Happy Birthday Singapore!

We, the citizens of Singapore, pledge ourselves as one united people, regardless of race, language or religion, to build a democratic society, based on justice and equality, so as to achieve happiness, prosperity and progress for our nation.

Happy Birthday Singapore!

Friday, August 7, 2009

Calculating Age using Birthday in PHP

Here's some food for the thoughts: calculating age using birthday in PHP.

<?php

function getAge($birthday){
$dt = strtotime($birthday);
// convert the birthday to a standard format (UNIX epoch)
$a = gmdate('Y') - gmdate('Y',$dt);
// find the difference of years
return $a; // return the age.
}

?>


And here we have, a simple Age calculating function which is useful when displaying age on User profiles or calculating age restriction and so on.

For example, you can put this against a movie age rating checker:
<?php

$bday = '1993-04-05';
$age = getAge($bday);

$movies = getPGMovies();

if($age >= 21){
// R21 and below can be watched
$movies= array_merge($movies,getR21Movies());
}
if($age >= 18){
// M18 and below can be watched
$movies= array_merge($movies,getM18Movies());
}
if($age >= 16){
// NC16 and below can be watched
$movies= array_merge($movies,getNC16Movies());
}
// display $movies
?>

Wednesday, August 5, 2009

Improving and Speed up Conditional Expressions

This is something cool and you can implement in your PHP scripts, and also you should make this a habit for most of your programming languages - and that is Short Circuit Evaluation.

Consider the following code:

<?php

function a(){
echo 'a';
return true;
}

function b(){
echo 'b';
return false;
}

if(b() && a()){
echo 'c';
}

?>


When run, the output is only 'b'. Reason being that when the if statement is run, the checks from bracket then left to right. If the first expression evaluates into false, the second will not be run.

Now take a look at the OR comparison operator.

<?php

function a(){
echo 'a';
return false;
}

function b(){
echo 'b';
return true;
}

if(b() || a()){
echo 'c';
}

?>


This time, the output is 'bc'. Reason being that the expression in IF will be evaluated to the first true. if the first true is found, the rest will not be executed.

This allows you to speed up your application. Think about the following code:

<?php

$url = htmlentities($_POST['url']);

if($url == '' || validate::url($url)){
echo 'URL is not valid.';
}else{
echo 'Valid URL provided';
}

?>


It'll help to save time if the string is empty - since Short Circuit Evaluation parses that $url is empty, so it's a true and it won't bother to execute the rest of the expression.

Thursday, July 30, 2009

Calling PHP functions from Javascript using/via AJAX

This has been quite a topic for some time - the ability for PHP functions to be called from Javascript. Well, yesterday I did it by implementing this feature into Samstyle PHP Framework.

This is similar to ASP.NET AJAX Extension's Webservice, where you can directly call Methods in classes of your ASP.NET website.

Download and experiment with this new feature at http://code.google.com/p/samstyle-php-framework/. Only available in the framework after version 1.2.6 BETA.

But again remember, PHP is a server-side script, which shouldn't have access from a client-side script like javascript. here we're doing AJAX calls back to the server to call the function.

Sunday, July 26, 2009

PHP: Generate random color code

Hello! today I was surfing the net again reading up articles when I came across this website which has a few codes on several uses. but their snippets were quite full of flaws and vulnerability.

well, I am going to talk about one of their code snippets: http://phpsnips.com/snippet.php?id=34 - Generating random color code.

Here's mine, a function that generates CSS-compatible colour code in hexadecimal:
<?php

function rand_colorCode(){
$r = dechex(mt_rand(0,255)); // generate the red component
$g = dechex(mt_rand(0,255)); // generate the green component
$b = dechex(mt_rand(0,255)); // generate the blue component
$rgb = $r.$g.$b;
if($r == $g && $g == $b){
$rgb = substr($rgb,0,3); // shorter version
}
return '#'.$rgb;
}

$code = rand_colorCode();
echo 'This code is '.$code.'';

?>


Isn't this much better than the one posted at phpsnips.com? Note that this function doesn't utilize the functions in GD, but you can use the RGB in GD.

Thursday, July 23, 2009

Using single instead of double quotes in PHP

Today I was reading up on some articles on the web when I suddenly gave thought about the codes I have always been doing.

The other day I was talking to my friend about using single or double quotes, and I persisted on using single quotes instead of double quotes while writing string in PHP. My friend asked why: and here's why we use single quote (') instead of double (").

When writing double (") quotes, PHP parses for variables and control characters (e.g. \n, \r, \t, ...) inside the string:

<?php

$str = "testing";
echo "my string: $str";
// outputs string(18) "my string: testing"

?>


Where possible, use single quotes (') to write strings:

<?php

$str = 'testing';
echo 'my string: '.$str;
// outputs string(18) "my string: testing"

?>


In conclusion: Single quotes speeds things up.

Monday, July 20, 2009

Samstyle PHP Framework v1.2.0 released

Finally Samstyle PHP Framework v1.2.0 is released! As promised, most features listed on the project home page are implemented in the v1.2.0 release.

You can download a copy of the framework and start using it by visiting the project home page at http://code.google.com/p/samstyle-php-framework/.

it is the stable version and you can use it.

Upcoming 1.2.1 will include a Form Javascript validator which you can create using the validator class.

Should you need any help with framework, you can write a comment here, or on the Google code side, or email me.

Sunday, July 19, 2009

PHP Code crashes Apache

Today i was reading up DoS and DDoS on Wikipedia when i came across this thing about Forkbomb (a kind of wabbit). So I tried it out on my own localhost server.

This was what i wrote in the file:
<?php

while(include(basename($_SERVER['PHP_SELF'])));

?>


Then I run the script on my browser. as expected, "apache.exe" crashes right after the script ran. The script will keep running and including itself, which in turns run more loops.

However, the amazing thing is that, apache recovered itself and my localhost is able to run again. If you have noticed, apache actually runs on 2 processes, both "apache.exe". When the main process crashes, the secondary process detects this crash and then load the server again, thus preventing downtime.

Tuesday, July 14, 2009

PHP GD: Creating a security captcha in PHP

I was working on an application yesterday when I had to write a captcha security check on the form. So I came up with the following script to generate an image with random code. The script will also rotate the code a little in the image and randomize the position of the code on the image. a random background will also be selected (random background image should be 100px by 30px).

<?php
session_start();

// note that $_GET['k'] is a static key that you can enter when getting the image.
// generate the key and store into session
$_SESSION['captchasecurity'] = md5(mt_rand().time().$session_hash).$session_hash.md5($_GET['k'].mt_rand());
// create a shorter key for display
$key = dechex(crc32($_SESSION['captchasecurity']));

// disable the client side caching
header('Content-type: image/png');
header('Cache-Control: max-age=0');
header('Expires: '.gmdate('r',time()-3600*24*365));
header('Pragma:');

// randomize the background image
$r = mt_rand(0,3);
$captcha = imagecreatefrompng('img/captcha'.$r.'.png');

$cl = mt_rand(0,50);
$c = imagecolorallocate($captcha, $cl, $cl, $cl);
$line = imagecolorallocate($captcha,233,239,239);

$txtx = imagefontwidth(5) * strlen($key) +10;
$txty = imagefontheight(5);

$timg1 = imagecreate($txtx,$txtx);
$ba = imagecolorallocatealpha($timg1,0, 0, 0,127);
imagefilledrectangle($timg1, 0, 0, $txtx, $txtx, $ba);
imagesavealpha($timg1, true);

$tc = imagecolorallocate($timg1, $cl, $cl, $cl);
imagestring($timg1, 5, 0, $txtx/2 - $txty/2, $key, $tc);

$tca = imagecolorallocatealpha($timg1, 255, 255, 255,127);
$timg = imagerotate($timg1, mt_rand(-5,5), $tca);
imagesavealpha($timg, true);
imagecopy($captcha, $timg, mt_rand(2,22), mt_rand(3,6), 0, $txtx/2 - $txty/2, $txtx, $txtx);

// output the captcha image
imagepng($captcha);

// free up memory
imagedestroy($timg);imagedestroy($timg1);
imagedestroy($captcha);
?>


To check whether the code entered by the user against the one generated, simply do the following:
<?php

// case sensitive check. CRC32 hash is in low case.
if($_POST['captchacode'] != dechex(crc32($_SESSION['captchasecurity']))){
// the code is wrong
}else{
// code is correct.
}

?>


Get the full code on Pastebin: http://thephpcode.pastebin.com/f21c1ed80

Note that this captcha script has been tested to be successful on my localhost. I cannot guarantee 100% bot proof. You are advised to step up the security in your own application.

Monday, July 13, 2009

Speeding up conditional (IF/ELSE) statements

Do you know that conditional statements can be actually sped up if you use the appropriate statements and expressions?

Take a look at the following 2 codes:

<?php
if($test==5){
print 't';
}else{
print 't2';
}
?>


and

<?php
($test == 5) ? print 't' : print 't2';
// reason that i am using print is
// because echo cannot be used.
?>


The second code block is actually faster than the first. I looped both codes 10 times and I got the following results: 4.31537628174E-5s for IF/ELSE (first code) and 1.50203704834E-5s for (second code) respectively. A difference of 2.8133392334E-5 seconds.

However, the shortcoming of the second code block is that you can only put in one function in the condition at one time.

Meaning to say you cannot do this:
<?php
($test == 5) ? print 't';$i++ : print 't2';
?>

This will give a syntax error on PHP.

Sunday, July 5, 2009

Creating include-only PHP files

Sometimes you just want the files to be included, but not called directly. you might want to do this for security or what other reasons. here's the simple code:

<?php

if(basename(__FILE__) == basename($_SERVER['PHP_SELF'])){exit();}

?>


if name of the file requested is the same as the current file, the script will exit directly. place this at the top of the scripts you want to set include-only.

However, take note that if the name of your included file is the same as your main file, it will get kicked out as well. As a developer, the convention is to name your files differently. e.g. users.php and users.inc.php

Microsoft with PHP (on Windows IIS 7)

If you're thinking whether deploying PHP applications on your IIS or Windows Servers is possible - the answer is Yes.

Lately Microsoft have shown their support for PHP through IIS 7 on their website (http://www.microsoft.com/windowsserver/compare/php-on-windows/).

To use PHP on IIS 7, simply add the PHP dynamic linking library into the Filter extensions of IIS 7 through the management console, you will be able to load PHP on IIS7.

To learn more, you can start from http://php.iis.net/

Arrays Loop Benchmarking: foreach vs while

Yes yes, i am current obsessed with loads of PHP speed tests on my local machine. But today I worked on something interesting: foreach vs while loops for Arrays.

Remember one of my posts titled "PHP Loop Benchmarking - WHILE vs FOR"? It talks about your PHP scripts can be speed up using while loops instead of for loops?

Well, for Arrays, this is not the case at all.

In my test, i create an array with 100000 elements. Here's how I create the benchmarking array:
$a = array();
while($i++ < 100000){
$a[] = dechex(crc32(mt_rand().time()));
}


Then I move on to measure time taken to run through the array with a FOREACH loop:
foreach($a as $k){

}

The foreach run took 0.00826096534729 seconds.

Next, I measure the time taken to run through the array, with a WHILE loop:
$z = -1;
while($z++ < count($a)){
$k = $a[$z];
}

Amazingly, the run took 0.0426709651947 seconds - approximately 5 times slower than FOREACH loop.

Then I moved on to optimize the while loop. Instead of calling the count() function at every step, I will store the number of elements into a variable before the loop.
$z = -1;
$i = count($a);
while($z++ < $i){
$k = $a[$z];
}

As expected, the run speeds up and it took 0.0160219669342 seconds.

The reason behind the while loop being slow, is the fetching of element with "$k = $a[$z];". Once i removed that line, the optimized while loop (3rd test run) ran at 0.00645399093628 seconds - 0.002 s faster than FOREACH.

Note that the timings taken are an average of 5 runs spreaded across 5 mins (i.e. 1 run per minute) for the most accurate timings. Please note that the timings may differ from computer to computer. I am using Intel QuadCore 2.4GHz, 4GB RAM, Windows XP SP3, XAMPP 1.7.1, PHP 5.2.9.

Saturday, July 4, 2009

Using include() in caching

Caching in a dynamically generated website is a great trick to speed things up. Can you imagine if 5000 users come to your web page at the same time, and you have to grab data from the database, manipulate, validate then output the data 5000 times? That'd take a great load of time.

Instead, when using caching, the server load will be greatly reduced and thus speeding things up. The 5000 users come to your webpage at the same time, only the first user grabs data from the database, manipulate, validate, output then save the output. The following 4999 users just have to grab the output from the cache and that's it!

I was working on the caching module of Samstyle PHP Framework today. Googling around, I discovered that many examples on PHP output caching out there on the web uses include() to retrieve and display data from the cache.

Some articles are:

This is very dangerous. Any executable PHP code in the cached file will also be executed as you are using an include(). Malicious code may be injected into the cache by exploiting this security leak.

For example if you are doing a search page. And the user is able to enter some search keywords into the box. He/she hits enter and the query is run. When you are displaying the result, you also display what the user has searched for. So the query is displayed.

Everything is cached - including the query that the user has entered. Think about it, what if the user had entered PHP codes into the query box and hit enter. Then he/she refreshes the page - the code gets executed!

The user can then use unlink() to delete all the files on your server and so on.

Instead of using include() for reading cache file, you could have directly used readfile(), which reads the file and writes directly to output buffer. This means that no code will be executed in the cache file on the server.

Samstyle PHP Framework

Hi all!

I am opening my framework to be open source. More details of it can be found at http://code.google.com/p/samstyle-php-framework/.

The framework aims to be the fastest, easiest, scalable, easily deployable and most expandable framework for PHP that is available. Since it is open source, anyone can contribute to it by branching it. It has MVC and an extension over the model.

If you wish to become a committer/member working on Samstyle PHP Framework, do contact me.

Cheers
Sam Yong

Friday, July 3, 2009

PHP Functions - too dynamic?

Today I was working on an application, where I found it strange when my application function is not working as I wanted it to be.

After a quick debug, I found out that it's because:

<?php
func($param1,$param2,$param3); // the way i am calling the function

function func($params){
// i declared func this way, and accepted $params as array of parameters 1, 2 and 3.
}
?>


Ended up, function "func" read in only $param1 and not $param2 and $param3. On top of that, it does not display any error or warning.

Note that when calling any PHP functions, you can specify additional parameters/arguments than what is defined in declaration. However, you cannot specify number of parameters less than declared.

Enabling extensions/dll in PHP of XAMPP

It has become common that as we work on our application locally, we might need to enable more and more extensions. For example, cURL and hash, they are not enabled on XAMPP's PHP by default.

What are extensions?
Extensions are DLLs (dynamically linked libraries) written in C and compiled, and that are added, enabled, disabled into PHP through the PHP configuration file php.ini. These extensions do not change your coding experience or the language, but in fact, they add on new sets of functions to your existing functions in PHP.

To enable the dynamic extensions you need in PHP, simply go to C:\xampp\apache\bin, open up php.ini, and search for "Windows Extensions" or "extension=".

Then, find the entry where your required DLL is written. If a ";" is at the front, remove it - that will uncomment the line so that PHP loads the extension.

Lastly, restart Apache server using XAMPP Control Panel and you should be able to use functions from your extension already.

Note that this works for any other servers as well as long as you are using PHP. but the configuration file might differ.

Thursday, July 2, 2009

Array vs Class - which is better?

The other day I was discussing with my friend and we talked about Array and Classes. of course in Samstyle PHP Framework, I actually dropped the usage of classes. There are reasons why I went for arrays instead of classes.

With the help of PHP: Arrays vs. Objects - 't Bijstere spoor (http://www.rooftopsolutions.nl/article/148), I actually wrote a piece of code that tests for memory usage of Array and Class.

For Array memory testing:
$data = array();
echo memory_get_usage().' b<br/>';

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

$data[] = array(
'property1' => md5(microtime()),
'property2' => md5(microtime()),
'property3' => md5(microtime()),
);

}
echo memory_get_usage().' b<br/>';


The memory usage difference was 549064 bytes for using Arrays.

For Class memory testing:
class Test {

public $property1;
public $property2;
public $property3;

}

echo memory_get_usage().' b<br/>';

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

$test = new Test();
$test->property1 = md5(microtime());
$test->property2 = md5(microtime());
$test->property3 = md5(microtime());
$data[] = $test;

}
echo memory_get_usage().' b<br/>';


The memory usage difference was 573224 bytes for using Classes.

Arrays actually has a less memory usage (549064 bytes to create 1000 arrays) compared to Classes (573224 bytes to create 1000 classes).

Well, in terms of speed, we did the same thing, except measuring time. Arrays (0.0161869525909s to loop 1000 times) are actually faster compared to classes (0.0189130306244s to loop 1000 times).

Therefore in terms of speed and performance, Arrays won over Classes.

On top of that, Arrays allows you to use the FOREACH($ARR as $KEY => $VALUE) loop, which is easier and better for us programmer, instead of statically writing each property of the class.

However, Arrays do not support instances, unlike Classes. Classes can define methods which allows the code to look cleaner and more efficient.

Note that the timings taken are an average of 5 runs spreaded across 5 mins (i.e. 1 run per minute) for the most accurate timings. Please note that the timings may differ from computer to computer. I am using Intel QuadCore 2.4GHz, 4GB RAM, Windows XP SP3, XAMPP 1.7.1, PHP 5.2.9.

Monday, June 29, 2009

Echo vs Output buffer

Here I am again. Lately i've been working on my framework - Samstyle PHP Framework - and now i am here to share with you about Echo versus Output Buffering.

Just today I have tested and proved why output buffering then echo is always better than a direct echo. For this, i created a script that will first run:

$u = 10000;
while($u-- > 0){echo 'testing 123<br/>';}


then next run the following:

$u = 10000;
$b = '';
while($u-- > 0){$b.= 'testing 123<br/>';}
echo $b;


(Psst for reasons why I used a while loop over for loop, look at: )
and then I calculated time taken to execute each of the code.

I found that buffering the output in a variable first (in this case $b) then output, is much faster compared to direct output.

For the first run, it took 0.183017015457 seconds. As for the second run, it took 0.0580809116364 seconds. That's an amazing speed improvement of more than 1/3 of the original code.

Even running only 100 times instead of 10000 times, there's still a significant difference between the speed of the 2 runs. Try that now!

Note that the timings taken are an average of 5 runs spreaded across 5 mins (i.e. 1 run per minute) for the most accurate timings. Please note that the timings may differ from computer to computer. I am using Intel QuadCore 2.4GHz, 4GB RAM, Windows XP SP3, XAMPP 1.7.1, PHP 5.2.9.

Tuesday, June 23, 2009

Image Comparison Tool

Remember the Image Comparison script i had mentioned earlier on? I have compiled it into a Windows console application.

Download the free Image Comparison Tool:


Usage: imgcmp image1.ext image2.ext

Cheers to all! It will return in percentage as output on the console.

Sunday, June 21, 2009

PHP GD: Getting pixel information

Hello there! It's Sam Yong here again. Earlier on I was developing a PHP script for comparing 2 images and find out their similarity. I was rather successful with it.

Well, today I am going to discuss about PHP's GD library - how to get the Red, Green, Blue information of a pixel of an image resource.

Firstly, when we want to get a pixel's color information from an image, we use imagecolorat. The function returns a 24 bit RGB information in Integer. So by shifting the bits, you will be able to get the individual Red, Green, Blue components of the RGB information in integer.

<?php

// retrieve rgb info from $img resource at ($x,$y)
$rgb = imagecolorat($img,$x,$y);

if($rgb){
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
}

?>


Note that each color has a value that runs from 0 to 255 (8 bit).

Friday, June 19, 2009

Variable Variables

Have you really thought about how dynamic PHP can be? Well seriously if you haven't, check this out! Variable variables.

<?php

$a = 'hello';
$hello = 'hello world!';
echo $$a;

// outputs as "hello world!"

?>

Why? $$a is evaluated automatically by PHP into $hello, since $a is 'hello'.

Wednesday, March 25, 2009

Setting up local Mail (SMTP, POP3, IMAP) Server on XAMPP

While I was doing a PHP project on my localhost using XAMPP, i realised I needed a local mail server in order to send out mails from my own workstation for testing. To come to think of it, XAMPP provides MercuryMail - but it's user-unfriendly interface and low level support makes it very difficult to use.

Previously when I was on Windows XP Professional Edition, I was able to install IIS with SMTP server and configure as such for PHP on Apache (XAMPP) to send out mails via IIS SMTP mail server.

However when I shifted to Windows Vista Home Premium, i realised that IIS7 do not come with a SMTP mail server. So I tried finding an alternative mail server for my computer.

I remembered about a software called hMailServer which I used on a website server. It was quite easy to use and have great UI. So i decided to give it a try. I downloaded and installed hMailServer.

To configure your computer to properly send mail, you need to do the following:
1) When you first open hMailServer Administrator, you need to add a new domain.
2) Click on the "Add Domain ..." button at the Welcome page.
3) Under the domain text field, enter your computer's IP, in this case it should be 127.0.0.1.
4) Click on the Save button.
5) Go to Settings>Protocols>SMTP and select "Delivery of Email" tab
6) Enter "localhost" in the localhost name field.
7) Click on the Save button.

It should then be able to send mail.

If you need to send mail using a FROM addressee of another computer, you need to allow deliveries from External to External accounts. To do that, follow these steps:
1) Go to Settings>Advanced>IP Ranges and double click on "My Computer" which should have IP address of 127.0.0.1
2) Check the Allow Deliveries from External to External accounts checkbox.
3) Save settings using Save button.

Now you should be able to send email from your PHP project using mail() function or your ASP.NET application via your own computer's SMTP mail server.

UPDATE - 1st September 09
I was working with local application to send mail when I debugged that Windows Live Hotmail (the email from Microsoft) has denied all emails coming from dynamic IPs (which most residential computers are using). So this means that emails from your localhost cannot be sent to Hotmail accounts (e.g. @hotmail.com, @live.com ...). A workaround for this is for you have a Gmail account, and follow the following steps:

1) Go to Settings>Protocols>SMTP and select "Delivery of Email" tab
2) Enter "smtp.gmail.com" in the Remote Host name field.
3) Enter "465" as the port number
4) Check "Server requires authentication"
5) Enter your Google Mail address in the Username field
6) Enter your Google Mail password in the password field.
7) Check "Use SSL"

and save. it will relay to Google Mail and then be sent to the intended recipients. Take note that whatever you write in the From header will be replaced with your gmail address. eg. you wrote From: user@example.com, it will be replaced by Google to example@gmail.com. For more about this see http://lifehacker.com/111166/how-to-use-gmail-as-your-smtp-server

Sunday, February 15, 2009

PHP Output Buffering

wow, it's been awhile already but i'm back to post more PHP-related articles. lately i'm busy working on another project for Microsoft Imagine Cup - the round 1 ends on 27 Feb 09.

Normally when most PHP programmers codes their PHP application, they'll have something like this - PHP in HTML:
<ul>
<li><b><?php echo $tabs[0]; ?></b></li>
<li><b><?php echo $tabs[1]; ?></b></li>
<li><b><?php echo $tabs[2]; ?></b></li>
</ul>


Why not have your HTML codes buffered in your own PHP variable and process it before echo to output like this?
<?php
$buffer .= '<ul>';
$buffer .= '<li><b>'.$tabs[0].'</b></li>';
$buffer .= '<li><b>'.$tabs[1].'</b></li>';
$buffer .= '<li><b>'.$tabs[2].'</b></li>';
$buffer .= '</ul>';';

echo $buffer;
?>


Also when you buffer using the 2nd method, you can reduce the need of removing whitespaces and newline characters in the HTML output, thus increasing the efficiency of your application.

With the $buffer variable, you can also post-process the buffer by applying custom tags. an example:
<?php
$buffer .= '<ul>';
$buffer .= '<li><b><$tab1$></b></li>';
$buffer .= '<li><b><$tab2$></b></li>';
$buffer .= '<li><b><$tab3$></b></li>';
$buffer .= '</ul>';';

echo str_ireplace(array('<$tab1$>','<$tab2$>','<$tab3$>'),array($tab[0],$tab[1],$tab[2]),$buffer);
?>


Isn't that great? Hope this helps for you. I am Sam Yong, your multi-disciplinary software developer major in PHP, signing off.

Tuesday, February 3, 2009

Trimming each line: trim() function

Just a few days ago, i ran into this problem of needing to trim off spaces in front and behind of each line of a string with multiline. so i came up with this simple function to do the job.

function trimlines($s,$t){
$e = explode("\n",$s);
foreach($e as $i => $a){$e[i] = trim($a,$t)}
return implode("\n",$e);
}


Optimized-for-speed version:
function trimlines($s,$t){
$e = explode("\n",$s);$z = count($e);
while($z-->0){$e[z] = trim($e[z],$t)}
return implode("\n",$e);
}


simple, ain't it?

Tuesday, January 13, 2009

PHP: Getting Secondary Internet Protocol (IP) Address

You'll probably get the Remote IP Address of your users by using the server variable $_SERVER['REMOTE_ADDR']. However, if your users are being proxy servers or using dynamic IP address, you won't get the actual IP Address of your users using $_SERVER['REMOTE_ADDR'].

Probably you need the following code to help you to get the actual IP address of your users.

function getIP() {
$IP = '';
if (getenv('HTTP_CLIENT_IP')) {$IP =getenv('HTTP_CLIENT_IP');}
elseif (getenv('HTTP_X_FORWARDED_FOR')) {$IP =getenv('HTTP_X_FORWARDED_FOR');}
elseif (getenv('HTTP_X_FORWARDED')) {$IP =getenv('HTTP_X_FORWARDED');}
elseif (getenv('HTTP_FORWARDED_FOR')) {$IP =getenv('HTTP_FORWARDED_FOR');}
elseif (getenv('HTTP_FORWARDED')) {$IP = getenv('HTTP_FORWARDED');}
else {
$IP = $_SERVER['REMOTE_ADDR'];
}
return $IP;
}


How does this get the actual IP?
When servers send data to a client through a proxy, the protocol will still send the actual IP address through the environment variables in order for the proxy to be able to identify which client to send to.

You should use this abreast (side by side) with $_SERVER['REMOTE_ADDR']. This function returns $_SERVER['REMOTE_ADDR'] if there's no secondary IP address.

Pastebin: http://thephpcode.pastebin.com/f24c2ec13

Sunday, January 11, 2009

MySQL: Grouping by most occurence in Column

I was developing a Content Management System (CMS) software when I encountered this issue of displaying most occurrence. So I managed to do this:

mysql> SELECT `DesireColumn`, COUNT(`DesireColumn`) AS `occurances` FROM `table` GROUP BY `DesireColumn` ORDER BY `occurances` DESC

This query groups rows with same value in `DesireColumn`, then sorts the result by the number of occurances. It's useful to me, and I hope that it's useful to you too.

Saturday, January 10, 2009

Code Monkey - Jonathan Coulton

something out of programming for all programmers - Code Monkey by Jonathan Coulton.

http://www.jonathancoulton.com/2006/04/14/thing-a-week-29-code-monkey/

I think you can download the song straight from his blog.
More about what is a code monkey: http://en.wikipedia.org/wiki/Code_Monkey

Cleaning/Stripping/Removing empty lines using PHP Regex (Regular Expressions)

Removing empty lines from whole chunk of HTML/CSS/Javascript output would do great effects. With the function below which uses preg_replace (Perl-Compatible Regular Expressions - PCRE Regex), you can easily strip off empty lines, which can improve your application's workload and speed.

function removeEmptyLines($s)
{
return preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $s);
}


Use the function to clean buffers of HTML, CSS or Javascript before outputting to browsers/clients. It will do a great deal of magic.

Sunday, January 4, 2009

Why exit(); after Header redirect

You'll probably need a few HTTP 302 or 301 redirect in your PHP application when you develop it. To do a redirect, you can easily call:

if(!$valid){
  header($_SERVER['SERVER_PROTOCOL'].' 302 Found');
  header('Location: nextpage.php');
}
unlink('tmp/2A4E22F1.dat');

However, many people do not know that even after this header is called, the code after this line still executes! In the above code, the temporary file "2A4E22F1.dat" is still deleted. Therefore, you must add a exit(); after this redirect.


if(!$valid){
  header($_SERVER['SERVER_PROTOCOL'].' 302 Found');
  header('Location: nextpage.php');
  exit();
}
unlink('tmp/2A4E22F1.dat');

Since it is not valid and you did a redirect, the temporary file is not deleted. This is sometimes what developers miss out when doing redirects. hope it helps!