Dec 7, 2006

Profiling PHP with Xdebug and WINCacheGrind

Ok..so this is really short, no BS tutorial, on how to profile your PHP application under windows

Step 1
Download windows modules for your version of PHP from http://www.xdebug.org/

Step 2
Write this lines at your php.ini file


zend_extension_ts="c:/wamp/php/ext/php_xdebugXXXXXXX.dll"
; general settings
xdebug.auto_trace=0
xdebug.collect_includes=1
xdebug.collect_params=1
xdebug.collect_return=0
xdebug.default_enable=1
xdebug.extended_info=1
xdebug.show_local_vars=1
xdebug.show_mem_delta=1
xdebug.max_nesting_level=100
xdebug.trace_format=0
xdebug.trace_output_dir="c:/XXXXXXXX/"
xdebug.trace_options=0
xdebug.trace_output_name=timestamp

; debugger settings
xdebug.remote_autostart=0
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_host=127.0.0.1
xdebug.remote_mode=req
xdebug.remote_port=9000

; profiler settings
xdebug.profiler_append=1
xdebug.profiler_enable=1
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_dir="c:/XXXXXX/"



now, important stuff
replace XXXX's in line
zend_extension_ts="c:/wamp/php/ext/php_xdebugXXXXXXX.dll"
with name of Windows module from step 1

Also instead of c:/XXXXXX/ write path where you want to keep profiling and debug files.


Step 3
Save your php.ini and restart your web server, start your local script and cachegrind files should appear in directory from step 2

Important notice, when you debug or profile large scripts (forums, blogs, etc) profiler writes a lots of data, so be careful to have enough free space, and check constantly

Step 4
When you are done,refer to step 2 and change line
xdebug.profiler_enable=1
into:
xdebug.profiler_enable=0 , and restart Apache again.
This will stop profiling process, and every time you wish to start profiling you must change it back to 1, and restart Apache.


Step 5
Download win cachegrind from http://sourceforge.net/projects/wincachegrind/
install, and set working directory to the same direcotry as in step 2, load your files and enjoy.

Now fun part begins, you should search for functions that takes most of your execution time, and try to optimize that code...

Few general advices for fast application are:
-As less includes as possible.
-Avoid too many database connections, try to use JOINS in your SQL query to get most meaningful data.
-Avoid array sort and count inside loops.
-when ever possible use caching of database data.

Dec 6, 2006

PHP function to get mondays from some date

This is nice little function that returns all Monday that passed from specified date.



<?php

/*
#  getWeeks function;
#  author: Dragan Bajcic
#  http://hosaka.blogspot.com
#  usage: getWeeks(2006,2) - returns an array of all Mondays since second week of 2006
# inspired by: http://www.php.net/manual/en/function.date.php#68269
*/

function getWeeks($year,$week_no){
   
$week = 0;
   
$day = 2;
   
$mo = 1;
   
$mondays = array();
   
$today=time();
   
$i =$week_no;

   
$test =  strtotime(date("r", mktime(0, 0, 0, $mo,$day, $year)) . "+" . $i . " week");


   while (
$today >= $test) {

       
array_push($mondays,date("d-m-Y", $test));

         
$i++;
       
$test =  strtotime(date("r", mktime(0, 0, 0, $mo,$day, $year)) . "+" . $i . " week");


   }
   return
$mondays;
}
/*
#######################################################
# Get all weeks and mondays starting from week #45,2006
#######################################################
*/
$mondays=getWeeks(2006,45);


print
"weeks:<br/>";
foreach (
$mondays as $ws){

   echo
date("d M Y", strtotime($ws))." - ".date("d M Y",strtotime($ws)+(7*24*60*60))."<br/>";


}

print
"mondays:<br/>";
foreach (
$mondays as $ws){

   echo
date("d M Y", strtotime($ws))."<br/>";


}

/*output:

weeks:
20 Nov 2006 - 27 Nov 2006
27 Nov 2006 - 04 Dec 2006
04 Dec 2006 - 11 Dec 2006
mondays:
20 Nov 2006
27 Nov 2006
04 Dec 2006

*/

?>