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.