Archive for the PHP Category

Working on Netbeans 6.5, and loving it

Posted in Opinions, PHP, Programming with tags on November 26, 2008 by rubayeet

windowslivewriter_netbeansdatabaseexplorergetssmarterwithe_1ea_netbeans-65

Netbeans has recently released version 6.5 of their powerful IDE. It comes with PHP support which can either be downloaded as a plug-in or installed as a stand-alone module. I’ve started working with it few days ago and am really impressed with it. Here are a a few things that I like about it:

User friendly

Creating new projects is really easy. They can be created either from scratch or from existing source files. The interface is clean and useful. It has file and project explorer, a navigation panel to quickly access the methods/members of your class files, a pallet to create HTML pages in drag-and-drop manner and lots more.

Code Assistance

It provides your basic PHP/JavaScript/HTML/CSS code auto-complete features like most other IDEs. Interestingly you can add your PHP framework/library files in the include path of your project and have the IDE suggest methods/members of the classes you have included in your script. It also supports code assistance for JQuery, Prototype and Scriptaculous.

Lightweight

It has a smaller footprint on system resource compared to Eclipse PDT and Aptana Editor, and even its predecessor Netbeans 6.1. It loads much faster than those on my Windows XP machine. I am yet to try it out on Ubuntu.

It free!

Yes. The last but not the least!

The thing that I don’t like about it, that it no longer separates the project specific files from the source files, as the 6.1 did. I work on Windows Desktop connected to a Linux server through Samba share. So I am left with ‘nbproject’ folders on the development server, which I have to manually remove when migrating the sources to production server.

Still Netbeans 6.5 is a decent 8 out of 10 on my book.

Download Link:

http://www.netbeans.org/downloads/index.html

Here’s a couple of screencasts to get started with the IDE:

http://blogs.sun.com/netbeansphp/entry/demo_of_the_php_support
http://blogs.sun.com/netbeansphp/entry/demo_of_the_php_distribution

MySQL Prepared Statements and PHP : A small experiment

Posted in MySQL, PHP with tags , , on October 7, 2008 by rubayeet

Consider a PHP-MySQL application where the information of 1000 users is being retrieved from the database by running a for loop:

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

$query = "SELECT * FROM user WHERE user_id = $i";

//run the query and fetch data

}

In each iteration, the first thing the MySQL engine does is to parse the query for syntax check. Then it sets up the query and runs it. Since the query remains unchanged during each iteration(except for the value of user_id), parsing the the query each time is definitely an overhead. In such cases use of prepared statements is most convenient. A prepared statement is just like a typical query, except that it has ‘placeholders’ that are supplied values at run time. The prepared statement in this case will look like this:

"SELECT * FROM user WHERE user_id = ?"

Notice the placeholder(‘?’) for the value of user_id in the query. Now MySQL engine needs to parse the query only once, then execute it 1000 times by binding the placeholder with PHP script supplied value for user_id. This pre-parsing of the query results in a significant performance boost.

The MySQL Improved extension in PHP, more commonly known as MySQLi, provides an API to work with prepared statements. The documentation at the online PHP manual is good enough to get you started on how to use them on your PHP application, so I’ll not go through it. Instead, I am going to share the results of my personal experiments on comparing performances of traditional and prepared SQL statements.

I conducted the experiment on a demo project which has large amount of data. I wrote two separate scripts on our development server, both of which performed the same operation: joining two related tables (one of which has over 150,000 records, the other has 350,000) and fetching some data . One script used regular SQL statement, the other employed prepared statement techniques. Each script was executed three times and the time required to fetch the data was measured at each pass.

The First script: traditional SQL statement

//Get the Database link
$dbLink = getDBLink();


$timeStart = microtime(true);


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


$query = "SELECT article_id, article_name, username as author FROM articles a LEFT JOIN user u ON (a.author_id = u.user_id) WHERE article_id = $i";


if($result = $dbLink->query($query))

$obj = $result->fetch_object();

else die("Failed to execute query: $dbLink->error");


$result->close();


}


$timeEnd = microTime(true);
$dbLink->close();


//measure the time difference
$timeDiff = $timeEnd - $timeStart;

echo "Total time: $timeDiff seconds";

Output:

First Pass -> Total time: 25.5793459415 seconds
Second Pass -> Total time: 25.1708009243 seconds
Third Pass -> Total time: 25.2259421349 seconds

Average: 25.32536300023 seconds

The Second Script : using prepared statement

$dbLink = getDBLink();

$query = "SELECT article_id, article_name, username as author FROM article a LEFT JOIN user u ON (a.author_id = u.user_id) WHERE article_id = ?";


$stmt = $dbLink->stmt_init();


if(!$stmt->prepare($query))
die("Failed to prepare statement: ".$dbLink->error);

$timeStart = microtime(true);

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

//bind the parameter
$stmt->bind_param('i',$i);
//execute the statement
$stmt->execute();
//bind the result, fetch it, then free it
$stmt->bind_result($articleId, $articleName, $author);
$stmt->fetch();
$stmt->free_result();

}

$timeEnd = microTime(true);

$stmt->close();
$dbLink->close();

//measure the time difference
$timeDiff = $timeEnd - $timeStart;

echo "Total time: $timeDiff seconds";

Output:

First Pass -> Total time: 20.1434290409 seconds
Second Pass -> Total time: 20.182309866 seconds
Third Pass -> Total time: 20.6448199749 seconds

Average: 20.32351962726 seconds

The task takes 20% less time for prepared statement, a significant performance boost.

Other than performance, it can also improve application security by guarding against SQL Injections. Check out this informative blog post on that topic.

Harrison Fisk at MySQL AB wrote a very good article on MySQL prepared statements. Don’t forget to check out the section ‘When should you use prepared statement?’ if you read it.

Should Readability suffer for Performance?

Posted in PHP, Programming with tags , , , on September 3, 2008 by rubayeet

Being a PHP developer, I often spend my spare time at work by browsing through blogs and articles on good coding practices, performance optimizations, tips, tutorials and so on. There have been some very resourceful and informative writings on these topics which helped me a lot. However there are some optimization tips on these articles that I found to be trivial, which may gain you a few nanoseconds of faster code at the expense of poor readability. For example, this article introduces a faster approach for detecting the length of a string:

if (strlen($foo) < 5) { echo "Foo is too short"; }

vs

if (!isset($foo{5})) { echo "Foo is too short"; }

The second approach, according to the article, is faster. May be, but should I quit using strlen() from now on? As far as I know, in a professional environment, the quality of code is not only measured by how fast it runs(performance) but also how easy it is to comprehend(readability) by someone other than the coder. It is more convenient to use strlen() to check the string length, because even if someone didn’t know the method, he/she could have guessed what it does from its name. Why obfuscate the code for a performance improvement that is barely comprehensible?

Another example of this, pushing an item in an array:

array_push($stack, $var) vs $stack[] = $var;

The second approach is claimed to be faster. I’ll still use the first one though. Its clear and convenient, I don’t mind if its a bit ’slow’.

Finally there is an ongoing debate on the use of __autoload(). It clearly is better than require/include/require_once because includes the scripts at runtime, making the code cleaner and more manageble. However it has been said autoload() and other magic methods decrease performance and their use should be avoided. Personally I would prefer to use autoload() since I code for maintainability. Performance can be optimized at the hardware level.

Update: The SPL autoload functions can be used instead of __autoload() to improve performance.

PHP ‘Good’ Practices

Posted in PHP, Programming on August 27, 2008 by rubayeet

This article lists a number of coding practices that should be followed in professional environments. Most of these practices are not of my invention, they have been accumulated from numerous blog and forum posts throughout the Internet written by expert PHP developers. I am just listing them here, along with few of my own conventions as a personal checklist for code review. If you are benefited by any of these, I’ll take that as a bonus :-)

Disclaimer: I didn’t go with the usual ‘Best Practice’ term as I am personally opposed to it. A certain coding practice should not be called best if everyone follows it. Someone could come up with a better convention, thus invalidating the previous. Hence the title ‘PHP Good Practice’(I think ‘Best Practice so far’ should be a more accurate term, but it doesn’t sound as cool).

1. Use ‘===’ instead of ‘==’ for equality. ‘===’ compares both the types and values of its operands, unlike ‘==’ which only compares values. (That is why 0 == ‘0′ returns true in PHP, but what about 0 == ‘test’ ? Take a look.)

2. Avoid function calls within for() loop control blocks. For example,

for( $i=0; $i<count($x); $i++ )

The count($x) is called at every iteration. Rather call it before the for loop.

3. When dealing with strings, see if you can use the string library functions and avoid the regex. For example, suppose you are looking for a certain word (say ‘XML’) inside a string. You can simply use strpos() instead of preg_match(), since the word you are looking for is unchanging.

4. An improper use of strpos() would be like this:

if(strpos($substring,$string)){ //do something}

strpos() returns the position of the first occurrence of the substring within a string, otherwise returns false. The above condition will fail if you are looking for ‘abc’ inside ‘abcdef’, because PHP treats 0 and false to be equal. The following code better handles this situation

if(strpos($substring,$string) !== FALSE)
{ //do something}

This further proves the point number 1.

5. Use single quotes for wrapping strings. PHP looks for variables inside double quotes making things slower.

6. If a class method can be static, declare it static. Speed improvement is by a factor of 4.

7. var_dump() is better than print_r() for debugging as it prints both type and value of the data. You cannot tell an empty string from NULL using print_r().

8. $row[’id’] is 7 times faster than $row[id].

9. To find out the time when the script started executing, $_SERVER[’REQUEST_TIME’] is preferred to time().

10. Variables should be initialized before being used. Makes the code less sloppy. Also incrementing an initialized variable is faster than incrementing an uninitialized one.

11. I recently found a code where the developer is checking if a certain constant is defined before invoking an action. His code was like This

if(MY_CONSTANT)
{
//do something
}
else
{
//do something else
}

If for some reason MY_CONSTANT is not defined, PHP will still execute the statements in the if block, because MY_CONSTANT will then be a string and if(MY_CONSTANT) will return true. The proper way to do this will then be

if(defined(MY_CONSTANT))
{
//do something
}

12. Close database connection, free resources once you are done with them. It improves execution speed.

13. To improve robustness of the application, make use of try-catch statements. Define distinct exception classes for distinct operations (e.g. DatabaseException, FileNotFoundException) and handle them properly for graceful crash of the code.

14. Avoid the ‘PHP White Screen of Death’ in production environment. Use custom fatal error handlers. Here is a good article about them.