Category: PHP

Performance tips for web applications

I have recently came by the article “High performance websites” in yahoo developer network. This article pointed 13 key points to speed up your application. These are

1. Make Fewer HTTP Requests
2. Use a Content Delivery Network
3. Add an Expires Header
4. Gzip Components
5. Put CSS at the Top
6. Move Scripts to the Bottom
7. Avoid CSS Expressions
8. Make JavaScript and CSS External
9. Reduce DNS Lookups
10. Minify JavaScript
11. Avoid Redirects
12. Remove Duplicate Scripts
13. Configure ETags

I was trying to improve performance for a web application recently keeping them in mind. Let me describe how to do some of them technically.

Making fewer HTTP requests:
Each time file loads from your web server, it generates an http request. So you can reduce number of http requests by caching some contents which are almost static or changes very rarely. if these contents are loaded from browser cache, there will be no request for them over HTTP. You can use apache’s mod_expire module to cache specific tyyou (image, swf etc) of contents in your site. The following line in httpd.conf loads mod_expire successfully.

LoadModule expires_module modules/mod_expires.so

After that, write the following lines in .htaccess to cache all the image, swf and javascripts for one month from the current date, with the help of mod_expire

ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType application/x-javascript A2592000
ExpiresByType application/x-Shockwave-Flash A2592000

If you are confused by the letter “A” with number of seconds associated with it, it actually means “Access time”

For reducing number of HTTP requests, you can also merge all your css files and javascript files into one css and js file.

Use a content delivery network
Yeah, that works really cool. You can serve your static contents more effectively from popular content delivery network (CDN) like akamai or Amazon S3. The benefit of using popular CDNs is that these CDNs are scaled and distributed and really knows how to serve your content faster than ever.

Add an Expiry Header
Expiry tags helps your browser to understand when to invalidate cache for a cached content. So you can ask how to add expiry header to your content. You can do it by injecting HTTP headers while delivering it from your server to end user’s machine i.e browser. Apache’s mod_expire module does the same thing, by MIME type of contents. But it doesn’t help to cache a single file or multiple files. So if you want to cache a specific file, you can do it using following PHP code.

<?php
header("Expires: ".gmdate("D, d M Y H:i:s", time()+600)." GMT");
header("Cache-Control: max-age=600");
?>

This will set the expiry time 600 seconds from the time of content delivered.

Gzip components
While delivering any data from web server to browser, you can apply gzip compression over it. These gzipped data are decompressed when received by brwsers and treated as regular data. Almost all of the modern browsers supports gzip compression. To compress your content, you can do it either automatically using Apache’s mod_deflate or manually via your code. If you like to do it using mod_deflate, then you have to enable mod_deflate first and then modify your .htaccess file to make use of that. The following line in httpd.conf enables mod_deflate with apache

LoadModule deflate_module modules/mod_deflate.so

Now if you want to make use of mod_deflate and compress your content on the fly while delivering, you can add the following line in your .htaccess file.

AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-javascript

Or you can write PHP code for delivering gzipped contents. The following piece of code delivers any javascript file as a gzipped one.

<?php
//gzipjs.php
ob_start("ob_gzhandler");
header("Content-type: text/javascript; charset: UTF-8");
header("Cache-Control: must-revalidate");
$offset = 60 * 60 * 24 * 3;
$ExpStr = "Expires: " .
gmdate("D, d M Y H:i:s",
time() + $offset) . " GMT";
header($ExpStr);
include(urldecode($_GET['js']));
?>

To deliver a javascript file (say prototype.js) using gzipjs.php you can load your scripts like this

<script type=”text/javascript” src=”gzipjs.php?js=prototype.js” ></script>

But hey, don’t just include any file passed to it (as i did it here in gzipjs.php). I wrote the code quickly to demonstrate the process. In practice you must (M.U.S.T) sanitize the supplied argument before including. Otherwise it could be a very dangerous security breach.

Minify Javascripts
Minifying means compressing javascripts by removing unnecessary white space, comments and others. You can make use of customized rhino engine which is used by dojo’s shrinksafe. Rhino is a nifty tool for doing these things.

So, how to do it? Download custom_rhino from dojo’s shriksafe page. After that compress your javascripts using following command.

java -jar custom_rhino.jar -c infile.js > outfile.js

That means you must have JRE installed in your machine to execute the command shown above (rhino is developed using java). Now if you have number of script files and you want to compress them all at once, without applying his command for each of them, you can make a nifty batch file to do it for you. Here is the code. It will compress each script files into script.js.packed file.

for /F %%F in ('dir /b *.js') do java -jar custom_rhino.jar -c %%F > %%F.packed 2>&1

Place custom_rhino.jar file and all your script files in same directory and run it. All your scripts will be packed.

I hope these tips will really boost up performance of your web application. This is just a basic article and I didnt go details of these tips. There are also other ways (like javascript on demand) which will also help increasing the performance.

Don’t forget to check other options from the original article at yahoo developer network.

Reference
1. http://betterexplained.com/articles/speed-up-your-javascript-load-time/
2. http://www.fiftyfoureleven.com/weblog/web-development/css/the-definitive-css-gzip-method
3. http://httpd.apache.org/docs/2.0/mod/mod_expires.html
4. http://httpd.apache.org/docs/2.0/mod/mod_deflate.html
5. http://developer.yahoo.com/performance/rules.html

I am joining Trippert Inc.

Trippert Inc

I am joining Trippert, an US based social networking company for travelers, from day after tomorrow. Though i started working unofficially with these excellent guys from couple of days ago. Primarily my responsibility is to extend Trippert’s developer group here in Bangladesh. Beside that I will be responsible for managing projects and implementing QA.

Trippert is developed over CakePHP having MySQL as database server. If you want to know what is Trippert being developed for, here a small excerpt from the site


What’s Trippert about?

Trippert celebrates the handful of experiences that define a trip. When you look back on a two-week trip, there are always a few key moments that made it amazing: a lazy day at a beach cafe, an architectural wonder, a great party, a romantic vista, a street market. Whatever the moment is for you, it is what you will remember in five years and what we want you to share on Trippert.

We don’t expect to offer the traditional travelogue features – travel diaries, step-by-step maps that retrace a trip, etc. Instead, we want to provide the best tool for you to add great photos and articles, to discover unexpected places, to save what you like, and to leave inspired to take a trip.

List of RSS Feeds I read almost everyday

I am sharing a list of RSS feeds that I read almost everyday. And which one is my favorites RSS reader? Well, I use GoogleReader because of it’s excellent features like star and feed history. also I like it’s feed sharing feature.

1. Ajaxian : http://www.ajaxian.com/index.xml
2. Cow’s Blog : http://cow.neondragon.net/xml.php
3. IBM Developer Works (Web) : http://www.ibm.com/developerworks/views/web/rss/libraryview.jsp
4. IBM Developer Works (Open Source) : http://www.ibm.com/developerworks/views/opensource/rss/libraryview.jsp
5. Designer Folio : http://feeds.feedburner.com/dezinerfolio
6. Digg Technology : http://digg.com/rss/containertechnology.xml
7. DZone Latest Front Page Links : http://www.dzone.com/feed/frontpage/rss.xml
8. Freelance Switch : http://feeds.feedburner.com/FreelanceSwitch
9. HacksZine : http://hackszine.com/index.xml
10. International PHP Magazine News : http://www.php-mag.net/magphpde/psecom,id,26,noeid,26,.html
11. JSLabs High Performance Web Apps : http://feeds.feedburner.com/jaslabs
12. LifeHack : http://www.lifehack.org/feed/
13. Mashable : http://feeds.feedburner.com/Mashable
14. Maxdesign : http://www.maxdesign.com.au/feed/
15. Newsvine (PHP) : http://www.newsvine.com/_feeds/rss2/tag?id=php&d=v
16. PHP Freaks : http://www.phpfreaks.com/feeds/articles.xml
17. PHP Magazine : http://www.phpmagazine.net/syndicate.xml
18. PHP Coding Practise: http://php-coding-practices.com/feed/
19. PHP Developer : http://phpdeveloper.org/phpdev.rdf
20. PHP Geek : http://www.phpgeek.com/wordpress/feed
21. PHP Architct News : http://www.phparch.com/phpa.rss
22. Planet Ajaxian : http://planet.ajaxian.com/index.xml
23. Planet PHP : http://planet-php.org/rdf/
24. Programmable Web : http://feeds.feedburner.com/ProgrammableWeb
25. ROScripts : http://feeds.feedburner.com/ArticlesAndProgrammingTutorials
26. Sitepoint Blogs : http://www.sitepoint.com/blogs/feed/
27. Sitepoint News : http://www.sitepoint.com/recent.rdf
28. Smashing Magazine : http://www.smashingmagazine.com/wp-rss.php
29. Jonathan Snooks Blog : http://snook.ca/jonathan/index.rdf
30. TechCrunch : http://feeds.feedburner.com/Techcrunch
31. Technorati Javascript Links : http://feeds.technorati.com/search/Javascript
32. Technorati PHP Links: http://feeds.technorati.com/search/PHP
33. Veerle’s Blog : http://feeds.feedburner.com/veerlesblog
34. Web2List : http://feeds.feedburner.com/Web2list
35. Zen Habits : http://feeds.feedburner.com/zenhabits
36. Del.icio.us PHP Tags : http://del.icio.us/rss/tag/php
37. PHPExperts Forum : http://rss.groups.yahoo.com/group/phpexperts/rss
38. 456 Berea Street : http://www.456bereastreet.com/feed.xml
39. Particle Tree : http://feeds.feedburner.com/particletree
40. Simple Bits : http://simplebits.com/xml/rss.xml

Just a followup, I quit from Pageflakes as well.

Well, this is just a followup of my previous post http://hasin.wordpress.com/2007/06/13/so-i-am-free-again-farewell/
that I quit from my part time contract of pageflakes as well. The termination of contract will be effective from 1st of august.

Well, same thing about Pageflakes. Learned a lot of new things there, a great working environment with someone like Omar Al Zabir, shiplu, amit, chitta, mouly, robin, sakib, nirjhar, shahed, mehfuz, mithun, asif, arafat, ashraf, awnik, raisul, chitta and christoph. I will miss you a lot.

Thanks for all your support.

Using ActiveRecord Library Separately from CodeIgniter

CodeIgniters ActiveRecord library is a nice implementation (though modified) of ActiveRecord design pattern. It comes bundled with CodeIgniter. So if you want to use Just this library in your application individually instead of using full CodeIgniter framework, what to do?

Today I’ve spent some time and separate the ActiveRecord library from CodeIgniter. Now you can use it via a class named ActiveRecordFactory. Here’s how to do it (I separate only the MySQL driver) .

I separate the “database” folder under the “system” directory of CodeIgniter. Then I removed all folders in database/drivers except “mysql”. (I need only MySQL, :D)

I modified the class definition at database/drivers/mysql_driver.php
Previously It Was : class CI_DB_mysql_driver extends CI_DB {
Now : class CI_DB_mysql_driver {

I modified the class definition at database/DB_driver.php
Previously It Was : class CI_DB_driver {
Now : class CI_DB_driver extends CI_DB_mysql_driver {

And finally I create a ActiveRecord Factory to instantiate codeigniters Active Record Properly. Here is the code

File: database/ActiveRecordFactory.php


<?
/**
 * This is a Factory to create an instance of Code Igniters Active Record Class
 *
 * @author Hasin [http://hasin.wordpress.com]
 */

define(BASEPATH,"./");
include_once (
"drivers/mysql/mysql_driver.php");
include_once (
"DB_driver.php");
include_once (
"DB_active_rec.php");
include_once (
"DB_result.php");
include_once (
"drivers/mysql/mysql_result.php");

function log_message(){/*just suppress logging*/}

Class ActiveRecordFactory {
    private static 
$dsn;
    private static 
$CIAR;
    public static function 
Factory($dsn=null)
    {
        if (!empty(
$dsn)) self::$dsn $dsn;
        if (empty(
self::$CIAR))
        {
            if (!empty(
self::$dsn))
            
self::$CIAR = new CI_DB_active_record($dsn) ;
            else 
            throw new 
Exception("Please give a DSN in this format 'driver://username:password@hostname/database'");
        }
        return 
self::$CIAR;
    }
}
?>

Now You can test The ActiveRecord library like this

<?
include(“database/ActiveRecordFactory.php”);
$activerecord = ActiveRecordFactory::Factory(“mysql://user:password@localhost/test”);
$activerecord = ActiveRecordFactory::Factory();

$activerecord->select(“name”);
$activerecord->where(“id=”,”10″);
$activerecord->orwhere(“id=”,”19″);
print_r($activerecord->get(“users”)->result_array());

$activerecord->select(“name”);
$activerecord->where(“id=”,”10″);
$activerecord->orwhere(“id=”,”19″);
echo $activerecord->get(“users”)->num_rows();

$activerecord->insert(“users”,array(“name”=>”CodeIgniter”,”pass”=>”CI Rocks”));
?>

You can download the complete example from here http://hasin.javapark.net/ActiveRecord.zip

An interesting bug in ReflectionParameter object in PHP 5.2.1

I came across an interesting bug last night. I searched for the reference and found that Sebastian Bergman reported quite similar bug in 11 Jun 2005 (Bug # 33312) which is currently marked as closed. I tested that bug reported by Sebastian and well, its fixed.

But there is still the following bug alive in ReflectionParameter object, I tested it against the PHP version 5.2.1 . So what is this bug? The reflection parameter cannot retrieve the default value of a parameter if the next parameter has no default value. PHP simply omits all the variables before that variable and return only values after that variable (I am sorry for my poor english). To regenerate the bug, you can execute the following script

[sourcecode language=”php”]
<?
class TestClass
{
public function __construct($a , $b=6 , $c = "hh", $d, $e=76)
{

}
}

$class = new ReflectionClass("TestClass");
$method= $class-&gt;getMethod("__construct");
$parameter = $method-&gt;getParameters();

foreach ($parameter as $param)
{
if ($param-&gt;isDefaultValueAvailable())
{
if (is_null($param-&gt;getDefaultValue()))
echo $param-&gt;getName()." : null \n";
else
echo $param-&gt;getName()." : ".$param-&gt;getDefaultValue()."\n";
}
}
?>
[/sourcecode]

The above code returns only “e : 76” which is definitely not the expected value. And if you modify the TestClass like below

[sourcecode language=”php”]
class TestClass
{
public function __construct($a = "1", $b , $c = "string", $e=76)
{

}
}
[/sourcecode]

it will output
c : string
e : 76

Its a bug, right? I donno if already reported! And I didn’t test it in 5.2.2 but i guess it’s still there.

Nusphere PHPEd 5.0 Review

I am using PHPEd for couple of months and I’ve recently upgraded to their latest edition, 5.0. So I cant resist myself from writing a review of this product.

Best features
Latest edition of PHPEd (Version 5.0, build 5019) comes with many new exciting features, a splashing look-n-feel and improved debugging functionalities for professional PHP developers. PHPEd is available in the market for quite a long time and it is popular with handful of its useful features. The latest release of PHPEd improves their editor at next level where you will really find yourself flexible to develop PHP application. Let’s look at the best feature of PHPEd that always excites me.

Browser style code navigation
Splitable edit window
Fully Unicode compatible
Excellent debugging with DBG
Excellent Code-Insight facility
Embedded Firefox
Quick HTML Objects
DB Form wizard
Embedded NuSOAP Tool
Smart Full screen Coding
Integration with Shell Menu
Built in profiler

Drawbacks
Distribution of old libMySQL (Well, just because of new licensing scheme of MySQL)
Old Help Files
Absence of old code completion for some libraries

phped.png

Splittable Editing Window
This is one of the coolest features which come to my everyday use. By splitting the code window in two parts I can simultaneously work on two portion of the same file, keeping anyone as a reference.

Unicode compatibility
PHPEd comes with Unicode compatibility, this is one of the major featured I was looking in PHP editors for years. You can switch to your desired encoding anytime from tools menu->IDE Settings

Debugging with DBG
The debugging in PHPEd is cool with DBG as the backend debugger. You can set break points, watch variables and do other things with it.

Excellent code Navigation
Another feature I really liked is the different way of “code insight” – You can see the methods and variables inside your project. You can view all the classes, or all the methods under all the classes or even the methods from a single file. This thing helped a lot. And you can also search for any function inside your project using this code explorer tool.

Embedded Firefox
Yeah it’s true; it was so much fun having Firefox as the embedded browser. In PHPEd recent version you can use Firefox as embedded browser.

DB Form wizard
PHPEd can write PHP code to interact with your tables. It creates the HTML form and PHP code for CRUD operation.

Embedded support for NuSOAP
PHPEd has built-in support for NuSOAP library for creating soap servers and clients.

Smart Full screen Coding
That’s another thing I really like!! Hit the Alt+F10 and just coding!!! – Very nice feature for me!

Integration with Shell Menu
That’s another very useful feature I agree, it comes very handy to perform shell operations. PHPEd interacts with shell directly from the project explorer.

And beside these, yeah, code folding is also available.

Built in profiler
Yes, and that’s really nice. You can profile your application directly from inside PHPEd instead of setting up xdebug and WinCacheGrind. This is a very cool feature for PHP developers.


Drawbacks

Some drawbacks are there, too. One major problem that I face with PHPEd is that it has some problem with intellisense for some libraries like SPL and others. But they provide you some workaround to quick fix that. Another problem I found is old help files for Smarty, PHP and MySQL. But that won’t be a big problem if you have your own.

Counting occurrence of a word in a String :: Benchmarking of PHP functions

Today I was just thinking what are the possible ways to count the occurrence of a specific word inside a string. I found some possible ways finally and I just benchmarked them. Wanna see the result?? – for sure you will find it interesting too.

<?
function microtime_float()
{
   list(
$usec$sec) = explode(” “microtime());

   return ((float)$usec + (float)$sec);
}

$str “I have three PHP books, first one is ‘PHP Tastes Good’,
 next is ‘PHP in your breakfast’ and the last one is ‘PHP Nightmare'”
;

$start microtime_float();
for (
$i=0$i<10000$i++)
{

    $cnt count(split(“PHP”,$str))-1;
}
$end microtime_float();

echo “Count by Split+Count took : “.($end$start).” Seconds\n”;

$start microtime_float();

for ($i=0$i<10000$i++)
{
    
preg_match_all(“/php/i”,$str,$matches);

    $cnt count($matches[0]);

}
$end microtime_float();
echo 
“Count by Preg_Match+Count took : “.($end$start).” Seconds\n”;

$start microtime_float();

for (
$i=0$i<10000$i++)
{

    str_replace(“PHP”,“PP”,$str,$cnt);
    
//echo $cnt;
}
$end microtime_float();

echo “Count by str_replace took : “.($end$start).” Seconds\n”;

$start microtime_float();

for ($i=0$i<10000$i++)
{
    
str_ireplace(“PHP”,“PP”,$str,$cnt);

    //echo $cnt;
}
$end microtime_float();
echo 
“Count By str_ireplace took : “.($end$start).” Seconds\n”;

$start microtime_float();

for (
$i=0$i<10000$i++)
{

    $cnt count(explode(“PHP”,$str))-1;
    
//echo $cnt;
}
$end microtime_float();

echo “Count By Explode+Count took : “.($end$start).” Seconds\n”;

$start microtime_float();

for (
$i=0$i<10000$i++)
{
    
$word_count = (array_count_values(str_word_count(strtolower($str),1)));

    ksort($word_count);

    
$cnt $word_count[‘php’];
}
$end microtime_float();
echo 
“Count By Array Functions took : “.($end$start).” Seconds\n”;

$start microtime_float();
for (
$i=0$i<10000$i++)

{
    $cnt count(preg_split(“/PHP/i”,$str))-1;
}
$end microtime_float();

echo “Count By preg_split+Count took : “.($end$start).” Seconds\n”;

$start microtime_float();
for (
$i=0$i<10000$i++)
{

    $cnt substr_count($str“PHP”);
}
$end microtime_float();
echo 
“Count By substr_count took : “.($end$start).” Seconds\n”;

?>

And the result is

First Run
Count by Split+Count took : 0.44112181663513 Seconds
Count by Preg_Match+Count took : 0.46423101425171 Seconds
Count by str_replace took : 0.23512482643127 Seconds
Count By str_ireplace took : 0.39766597747803 Seconds
Count By Explode+Count took : 0.25045800209045 Seconds
Count By Array Functions took : 1.1077101230621 Seconds
Count By preg_split+Count took : 0.30741000175476 Seconds
Count By substr_count took : 0.21060705184937 Seconds

Second Run

Count by Split+Count took : 0.68125295639038 Seconds
Count by Preg_Match+Count took : 0.60020899772644 Seconds
Count by str_replace took : 0.2877471446991 Seconds
Count By str_ireplace took : 0.47500586509705 Seconds
Count By Explode+Count took : 0.31055402755737 Seconds
Count By Array Functions took : 1.3551599979401 Seconds
Count By preg_split+Count took : 0.40205383300781 Seconds
Count By substr_count took : 0.24432802200317 Seconds

Third Run
Count by Split+Count took : 0.50134515762329 Seconds
Count by Preg_Match+Count took : 0.53588891029358 Seconds
Count by str_replace took : 0.25469994544983 Seconds
Count By str_ireplace took : 0.34696006774902 Seconds
Count By Explode+Count took : 0.23176002502441 Seconds
Count By Array Functions took : 1.0504789352417 Seconds
Count By preg_split+Count took : 0.28686618804932 Seconds
Count By substr_count took : 0.20796585083008 Seconds

Fourth Run
Count by Split+Count took : 0.4736020565033 Seconds
Count by Preg_Match+Count took : 0.48813104629517 Seconds
Count by str_replace took : 0.29280996322632 Seconds
Count By str_ireplace took : 0.51396799087524 Seconds
Count By Explode+Count took : 0.34470105171204 Seconds
Count By Array Functions took : 1.4177949428558 Seconds
Count By preg_split+Count took : 0.36489319801331 Seconds
Count By substr_count took : 0.27841401100159 Seconds

If you are interested to know the machine configuration, these tests ran on a Celeron 1.6GHz processor based laptop with 768 MB of RAM. And I am using PHP 5.1.1

My book "WordPress Complete" has been slashdotted 8

Today I get the news from my Editor at Packt Publishing, David Barnes that my book “WordPress Complete” has been reviewed today in slashdot and scored 8 out of 10 — I am very happy today.

You can visit it from here http://books.slashdot.org/article.pl?sid=07/04/25/1554235

And you can buy the book from here WordPress Complete at Amazon

Thanks to all my friends, colleagues, editors and friends in packt, pageflakes and somewherein – I am very happy today.

Prelude to foundation: Its time to go for a better PHP Framework

I remember those old days when I had to write everything by myself. I wrote huge libraries to work with MySQL. Then I learned PostgreSQL and SQLite but didn’t rewrote my old library to work with those, I was running short of time. So I forsake the opportunity to write a db library which works with them. What I did was plain code relevant to database specific portions. Oh ya, that was a long time ago.

Soon after that I came to know adoDB which made my dream come true. I was so much happy getting my all db specific works done in a much more smarter way. I get rid of database portability issues. I was very happy that time.

I learned smarty soon after I realize that my codes are getting ugly with all the inline HTMLs and PHPs. Nothing could be smarter than separating the presentation logic from the business layer. I am a big smarty fan since that time. It saves my sleep for many nights.

But again I am recurrently suffering from maintainability issues. I was not surprised to find that my code is becoming huge unmanageable giant and it takes huge time for refactoring the application. I was very sad those days. Oh what a disaster that was.

When working with my team members located remote places, I fall into a deep shit. How can we manage and track the changes done by us? Even I was getting strange code in my routine which I bet was not written by me!! It was a terrific job (more…)