tyjfwa
Last Updated: February 25, 2016
·
3.488K
· rougin
Profile

PHP Performance Tips

This tip came from Google Developers Website. I will just post it here hoping that you will learn something about it. Thanks to the author (Eric Higgins) for this tip! https://developers.google.com/speed/articles/optimizing-php

Profile your code to pinpoint bottlenecks

Hoare's dictum states that Premature optimization is the root of all evil, an important thing to keep in mind when trying to make your web sites faster. Before changing your code, you'll need to determine what is causing it to be slow. You may go through this guide, and many others on optimizing PHP, when the issue might instead be database-related or network-related. By profiling your PHP code, you can try to pinpoint bottlenecks.

Upgrade your version of PHP

The team of developers who maintain the PHP engine have made a number of significant performance improvements over the years. If your web server is still running an older version, such as PHP 3 or PHP 4, you may want to investigate upgrading before you try to optimize your code.

Use caching

Making use of a caching module, such as Memcache, or a templating system which supports caching, such as Smarty, can help to improve the performance of your website by caching database results and rendered pages.

Use output buffering

PHP uses a memory buffer to store all of the data that your script tries to print. This buffer can make your pages seem slow, because your users have to wait for the buffer to fill up before it sends them any data. Fortunately, you can make some changes that will force PHP to flush the output buffers sooner, and more often, making your site feel faster to your users.

Avoid writing naive setters and getters

When writing classes in PHP, you can save time and speed up your scripts by working with object properties directly, rather than writing naive setters and getters. In the following example, the dog class uses the setName() and getName() methods for accessing the name property.

class dog {
  public $name = '';

  public function setName($name) {
    $this->name = $name;
  }

  public function getName() {
    return $this->name;
  }
}

Notice that setName() and getName() do nothing more than store and return the name property, respectively.

$rover = new dog();
$rover->setName('rover');
echo $rover->getName();

Setting and calling the name property directly can run up to 100% faster, as well as cutting down on development time.

$rover = new dog();
$rover->name = 'rover';
echo $rover->name;

Don't copy variables for no reason

Sometimes PHP novices attempt to make their code "cleaner" by copying predefined variables to variables with shorter names before working with them. What this actually results in is doubled memory consumption (when the variable is altered), and therefore, slow scripts. In the following example, if a user had inserted 512KB worth of characters into a textarea field. This implementation would result in nearly 1MB of memory being used.

$description = strip_tags($_POST['description']);
echo $description;

There's no reason to copy the variable above. You can simply do this operation inline and avoid the extra memory consumption:

echo strip_tags($_POST['description']);

Avoid doing SQL queries within a loop

A common mistake is placing a SQL query inside of a loop. This results in multiple round trips to the database, and significantly slower scripts. In the example below, you can change the loop to build a single SQL query and insert all of your users at once.

foreach ($userList as $user) {
  $query = 'INSERT INTO users (first_name,last_name) VALUES("' . $user['first_name'] . '", "' . $user['last_name'] . '")';
  mysql_query($query);
  }

Produces:

INSERT INTO users (first_name,last_name) VALUES("John", "Doe")

Instead of using a loop, you can combine the data into a single database query.

$userData = array();
foreach ($userList as $user) {
    $userData[] = '("' . $user['first_name'] . '", "' . $user['last_name'] . '")';
 }
$query = 'INSERT INTO users (first_name,last_name) VALUES' . implode(',', $userData);
mysql_query($query);

Produces:

INSERT INTO users (first_name,last_name) VALUES("John", "Doe"),("Jane", "Doe")...
Say Thanks
Respond

9 Responses
Add your response

13327
Ffebdf905fae3278a260ed03c9d165c7

Regarding the section "Don't copy variables for no reason", this isn't totally true. PHP by default only copies the variable if you attempt to edit it. So in your example I agree you shouldn't copy it, however adding shorter or more descriptive names could be helpful and won't take up much memory.

$description = $_POST['description'];
echo strip_tags($description);

In this example, you don't duplicate the memory since it's never altered due to PHP's "copy on write".

https://www.research.ibm.com/trl/people/mich/pub/200901_popl2009phpsem.pdf

over 1 year ago ·
13328
237975e7c6472ed44fa29dc795064ff1

Great tip, thanks for sharing.

over 1 year ago ·
13334

Some of these are not true and some showcase a very sloppy and out-of-date code. For instance flushing the output makes no difference if your web server is buffering it, actually it will just slow down the script. As another commenter already pointed out copying php variables doesn't affect memory as long as their value is not changed. Also the example given is wrong since strip_tags() needs to store the result in a temporary variable, which means it will allocate the double memory either way in that line of code. And it's not such a big deal anyway, unless you are writing spaghetti code variables will get garbage collected soon enough. While the idea is OK, mysql example shows outdated and very dangerous way to use SQL, it's an open invitation for SQL injections. Also when writing multi-insert queries like this you can run into problems if the total query length is too big, so you should be careful about it.

over 1 year ago ·
13375
F8c4fdde8545731ac4a77b52e4896595

Some core principles for 2013/2014 to performant PHP applications:

  1. Upgrade to PHP 5.5 with Zend OpCache or APC using PHP-PFM + Nginx
  2. Stay up to date with your framework + dependencies (using Composer)
  3. Optimize your session store to use signed cookies or database with caching
  4. Cache your database and web service access with Memcache, DBA or Redis
  5. Do blocking work in the background with queues and tasks using Resque or Gearman
  6. Use HTTP caching and a reverse proxy cache like Varnish
  7. Profile code with Xdebug + Webgrind and monitor production performance
over 1 year ago ·
13388
40cd1350403e5f6511745afed34d69ae

Avoid writing naive setters and getters : Exposing a consistent API for your users should be crucial and you can't have a consistent API just by making the properties public.

Most of the things posted are micro optimizations or contain outdated information, which is not always a bad thing, as you can include them in the "good to know" basket rather than mandatory.

over 1 year ago ·
13395
Ba916cb1c1327b700cf2f753684c2b4f

I really hope that this article is 10 years old. Otherwise it would be a very very weird article.

over 1 year ago ·
13407
0e9a63021036a78e1250083de4346144

In response to "Avoid writing naive setters and getters":
http://thecodelesscode.com/case/3

over 1 year ago ·
13436
Big pimpin

What I have learned from various blog posts, benchmarks, and personal experiences over the years:

  • General: if ( isset( $str[ 9 ] ) ) { } is faster than if ( strlen( $str ) == 10 ) { }
  • General: if and while are faster than switch and foreach respectively
  • General: [ 'banana', 'orange' ] is identical to array( 'banana', 'orange' )
  • General: In theory, 'Hello World!' is slightly faster than "Hello World!"
  • Architecture: The simplest way is often the best way
  • Loops: $keyValue = &$array[] is a great way to add to the end of an array without checking how long it is
  • Server: Apache & Nginx have nearly identical preformance; use the one you are more comfortable with
  • SQL: Use PDO or MySQLi; Avoid MySQL functions
  • SQL: Use LIMIT in queries whenever possible
  • Cache: APC is typically slightly faster than Memcached, but the difference is negligible for applications with less than ~50 concurrent users
  • Cache: Better client-side caching will save you more than server-side optimization ever could
  • Misc: Lasagna code is projectName\section\subsection\className::myFunc()
  • Misc: realpath() in all your includes/requires can make debugging a little bit easier.
  • Misc: Version Control & TDD are always worth any extra time
  • Misc: Sublime Text, Filezilla, Git, Composer, & .editorconfig FTW!
over 1 year ago ·
13527
F8c4fdde8545731ac4a77b52e4896595
over 1 year ago ·