Introducing a simple, yet deceivingly useful, micro benchmarking / timer class called Bench.

I’ve found myself on more than a few occasion using this familiar block of code in order to quickly narrow down a bottleneck or test a specific section of code.

$start = microtime(true);
// [Some Code To Test]
$time = (microtime(true) - $start);
echo $time . ' Seconds';

This is a crude but effective way of finding out how long it takes to get from line A to line B. On the down-side, this technique is annoying to implement, only measures time between two points, and makes code look very cluttered – so I started developing Bench.

Features

Bench offers more than just clean looking code or timing between two lines. Its goal is to be more powerful and reusable than simple Microtime Arithmetic while trying avoid stepping on anyone’s toes (cough cough Xdebug, see below).

Start and Stop

Bench can perform the same operation as the example above but in a much cleaner manner.

Bench::start();
// [Some Code To Test]
echo Bench::stop() . ' Seconds.';

### Marks

“Marks” are simply points in code that one would like tracked by Bench. They are easy to use, quick to implement, and very useful when tracking multiple parts of a script/request.

Bench::start();
// [Application Bootstrap]
Bench::mark('bootstrap');
// [Database Connection Opened]
Bench::mark('database');
// [Data Processing + Manipulation]
Bench::mark('processing');
// [HTML Creation]
Bench::mark('html');

Each call to mark() creates a Mark Array that contains the id, microtime of when it occurred, seconds since start, and seconds since the previously called mark.

print_r( Bench::getMarkById( 'database' ) );
/*
Array (
  [id] => database
  [microtime] => 1287969552.88
  [since_start] => 1.10582304001
  [since_last_mark] => 0.171210050583
)
*/

When calling Bench::mark(...) it returns ['since_last_mark'] as it tends to be the most sought after piece of information when working with marks. The first call to Bench::mark(...) will return ['since_start'] as – at that point in time – there are no marks in Bench to compare the call with.

Statistics

I’ve also built in a simple statistics method [ Bench::getStats() ] that returns an array with information about the request up until the point it was called.

print_r(Bench::getStats());
/*
Array (
  // The average time between marks (in seconds)
  [mark_average] => 0.346896330516
  // The longest mark
  [mark_longest] => Array (
    [id] => database
    [microtime] => 1288045989.62
    [since_start] => 1.02174592018
    [since_last_mark] => 0.831446886063
  )
  // The shortest mark
  [mark_shortest] => Array (
    [id] => processing
    [microtime] => 1288045989.64
    [since_start] => 1.04068899155
    [since_last_mark] => 0.0189430713654
  )
  // Start microtime
  [start] => 1288045988.6
  // Stop microtime (if called)
  [stop] =>
  // Time elapsed (in seconds)
  [elapsed] => 1.0407409668
)
*/

You may have noticed that ['stop'] is NULL but ['elapsed'] is still populated. That’s because I did not call Bench::stop() in the above example (as it is not required). Bench is meant to be snappy and intuitive; Thus, ['elapsed'] contains the time elapsed between the Bench::start() and Bench::getStats() calls.

I’ve documented many more examples, tips, and tricks over at the Bench Wiki.

Umm… What About Xdebug?!

This is probably one of the first things you thought of when you started reading this post.

Let me first say that I absolutely love Xdebug and have used it on many projects. It’s a huge life saver when you need to profile your entire application or find out what is truly going on within your code. However, when one is just looking to quickly find how long it took to get from line A to B to C then Xdebug can be bit overkill and slower than outputting/logging the result(s) from Bench.

The availability of Xdebug can also become an issue if the app sits on a server where one has limited to no access at all. Having the ability to quickly upload class.Bench.php and start debugging issues only occurring on the server helps to offset this occasional lack of environmental control – making Bench a viable light-weight alternative.

Summary

I developed Bench to be a happy middle ground between doing microtime arithmetic and loading up an Xdebug grind file. Whether Bench accomplishes this goal is – for the most part – a matter of personal taste.

Further simplification of Bench can be achieved by writing an autoload function for your development environment which eliminates the need to include the class.Bench.php file. Check out the spl_autoload() documentation </a> for a better understanding of autoloading within PHP as the topic is beyond the scope of this post.

License

This class and its code is released under the New-BSD License.

Requirements

  • PHP >= 5.0

Download

The source code is available to anyone at http://github.com/veloper/Bench.

I’ve developed a new class for WinCache that wraps around the wincache_ucache* functions. The goal of this project is to improve and add to the functionality of WinCache’s User Cache feature.

Basic Usage

Below is a quick code example of how this class simplifies the way in which a developer can take advantage of the user cache.

/**
 * Get Cache Object
 */
$cacheObj = DDWinUCache::getInstance();
/**
 * Cache Data
 */
$cacheObj->set('foo', 'bar');
$cacheObj->set('bar', 'candy');
$cacheObj->set('hello_world', 'we did it!');
$cacheObj->set('apple_red_core', 'simple tagging');
/**
 * Delete Cache Entries
 */
$cacheObj->delete('*or*'); // array('apple_red_core', 'hello_world');
/**
 * Get Cached Data
 */
$cacheObj->get('foo'); // "bar"

New Features

Within this class I’ve greatly improved the functionality of the delete method. I’ve also made getting information about the user cache simpler by creating accessor methods for all user cache related data. And to top it all off I’ve implemented ArrayAccess to push the simplicity over the edge.

Improved Delete

Arguably the biggest feature of this class is the ability to delete cache entries via three methods.

/**
 * Traditional
 */
$cacheObj->delete('this_is_a_test_entry');
/**
 * Wild Cards '*' and '?'
 */
$cacheObj->delete('this*');
$cacheObj->delete('this?is?a?test?entry');
/**
 * Regular Expression (PCRE)
 */
$cacheObj->delete('/^this.*?entry$/i');

### Accessor Methods
I’ve mapped all the data available via the arrays returned by wincache_ucahce_info() and wincache_ucahce_meminfo() into accessor methods. I’ve also added two more derived methods that can be used to help control the user cache – getMemoryUsed() and getMemoryUsedPercent().

ArrayAccess

The code below accomplishes the same tasks as in the *Basic Usage example above…

/**
 * Get Cache Object
 */
$cacheObj = DDWinUCache::getInstance();
/**
 * Cache Data
 */
$cacheObj['foo'] = 'bar';
$cacheObj['bar'] = 'candy';
$cacheObj['hello_world'] = 'we did it!';
$cacheObj['apple_red_core'] = 'simple tagging';
/**
 * Delete Cache Entries
 */
unset($cacheObj['*or*']); // array('apple_red_core', 'hello_world');
/**
 * Get Cached Data
 */
$cacheObj['foo'] // "bar"

Garbage Collection Issue

WinCache’s User Cache has a maximum memory limit of 85 Mb. With this cap one must be careful as WinCache has no built-in garbage collection outside of the TTL settings on each cache entry. This lack of garbage collection becomes an issue when one tries to set a cache variable while the user cache’s memory usage is maxed out – as the operation will fail.

This situation can be avoided by using getMemoryUsedPercent() in conjunction with clear() or delete(...).

Summary

My objective was to build a mapper class that extended the functionality of the WinCache User Cache. Specifically, I focused on making entry deletion more versatile and increasing the simplicity by which one interacted with the cache. To those ends I believe this is a great solution.

If you have any feature requests or bug reports please let me know and I’ll add/fix them asap.

License

This class and its code is released under the New-BSD License.

Download

The source code is available to anyone at http://github.com/veloper/DDWinUCache.

While working for a previous employer I was tasked with developing a new company “intranet” site. Changes rolled out at an aggressive rate and the process of deploying updates via FTP quickly turned into a tedious task.

After a while I decided to spend some personal time thinking of ways to make whole process a bit smoother. A few of days passed as I tossed around various ideas in my head, then it hit me…

Why not just checkout a working copy of the project onto the production server itself?

Subversion Deployment Work Flow

So simple! All I’d have to do is use the production server’s subversion client to add, update, and remove any changes – deployment becomes as simple as: $ svn up.

Setting Up The Environment

As is the case with most ideas there ended up being a few issues that needed to be worked out before moving forward.

Subversion’s .svn/ Directories

A working copy of a subversion repository is riddled with hidden .svn directories. This is a security risk as, by default, these directories and their contents are publicly accessible. To fix this issue we need to deny access by adding the following lines of code to either the Apache Global Config file, the site’s <VirtualHost> block, or the .htaccess file in the site’s root directory.

<Directory ~ "\.svn">
    Order allow,deny
    Deny from all
</Directory>

See Apache Tips & Tricks: Deny access to some folders for more information.

Development vs. Production Configuration Files

More than likely the development and production config files will contain very different settings. That’s an issue because if we run the command $ svn up on the production server the development config file will overwrite the production server’s config file – not a good thing.

Note: If your config file is Environment Aware feel free to skip this subsection.

First we need create a new directory named something along the lines of /defaults. Once created we copy over default versions of our config files and then add & commit the directory to the repository. This ensures that skeleton versions of our config files will be available when checking-out a working copy from the repository.

Now that we have our default config files stored safely away in the /defaults directory we remove the site’s config file(s) from revision control and commit the change to the repository. Notice the use of the --keep-local flag to prevent the file from being deleting.

$ svn remove --keep-local wp-config.php
$ svn commit -m "Removing wp-config.php from revision control."

Finally we take advantage of Subversion’s property list to ignore the file(s) we just removed from revision control. Ignoring a file or directory will prevent it from being included in commands such as $ svn status and $ svn add. It will also prevent other subversion clients (such as those found in Eclipse or NetBeans IDEs from automatically adding the files during a commit.

In the example below we…

  • Change the PWD to the directory containing our config file.
  • Create a hidden file named .svn_files_to_ignore and populate it with a file name pattern we want ignored by subversion.
  • Add the .svn_files_to_ignore file to revision control.
  • Instruct subversion to ignore all files in the current directory that match the pattern(s) contained in the .svn_files_to_ignore file.
  • Commit the local changes to the repository.
$ cd /path/to/config_file/directory
$ echo "wp-config.php" > .svn_files_to_ignore
$ svn add .svn_files_to_ignore
$ svn propset svn:ignore -F .svn_files_to_ignore .
$ svn commit -m "Added svn:ignore property and related .svn_files_to_ignore file."

If your project has more than one file that needs to be ignored you can add the file patterns (one per line) to the .svn_files_to_ignore file – see The propset Documentation for more information.

The Final Product

At this point we’ve taken care of the major environment issues and have checked-out a working copy of the repository into the DOCUMENT_ROOT path for the site.

Development

  • Add/Update/Delete files while working in the site’s development environment.
  • Commit the changes you’ve made to the project’s subversion repository.

Deployment

  • SSH into the production server.
  • Change your PWD to the site’s DOCUMENT_ROOT directory.
  • Run $ svn update
  • That’s it! You’ve now deployed all changes you’ve made locally to the production server without even opening up an FTP client.

Rollback

Below is a quick rollback scenario where we’ve …

  • checked, and noted, the current revision number of the production server’s working copy,
  • proceeded to updated the production server’s working copy to the latest revision,
  • but we realized there was an unknown error occurring after the update,
  • so we decided to rollback the working copy to the last stable revision.
$ cd /path/to/site/document_root
$ svn info
> ...
> Revision: 17
> ...
$ svn up
> At revision 19.

Oops! An unknown error is occurring on the site!

$ svn up -r 17
> ...
> Updated to revision 17.

Summary

It’s important to keep in mind that this technique is more of an alternative/geeky way of deploying commits you’ve made in your subversion repository to the production server.

I’d also like to note that if you do not have a fast connection from your production server to your subversion server running $ svn update could take some time depending on the combined size of the files that need to be transferred.

The examples shown in this post do not reflect “proper” subversion repository structuring. Rather, I attempted to relay a proof on concept that can be applied or adapted to almost any repository structure.

If you have any thoughts or ideas on this process please let me know!

In this article I’ll explain what register_globals is; how to protect against exploits that take advantage of it; and why it should be turned off (if possible).

What is Register Globals?

register_globals is a setting/feature within PHP that was intended to ease development by making variables passed to the script (via a form, cookie, or session) automatically available as predefined variables within the global scope.

In the example below you can see how register_globals takes a variable from the page’s query string and creates the global variable $apple to represent it.

Page: index.php?apple=red

echo $apple; // 'red'

How Register Globals Can Be Exploited

At first glance one might say “That’s a great feature! Now I don’t have to go to the trouble of defining $apple and assigning it a value!

In my time as a web developer I’ve come across a few great pieces of advice.

  • Never trust the user.
  • Don’t assume.
  • If it can happen, it will happen.

Below is a excerpt from a Shopping Cart script; watch what happens when we assume

Page: cart.php?promo_code=12save

if($promo_code == '12save') {
  $discount= 0.10;
}

if(isset($discount)) {
  $price -= $price * $discount;
}

This might look secure to a new or even intermediate PHP developer…

I mean, come on… the only way to get the discount is by knowing the correct promo code, right?!

Wrong Let’s add another variable to the page’s query string and see what happens…

Page: cart.php?promo_code=doesNotMatter&discount=0.80

if($promo_code == '12save') {
  $discount= 0.10;
}

/**
 * Even though the promo code was incorrect this
 * IF statement will still evaluate TRUE and discount
 * the price.
 */
if(isset($discount)) {
  $price -= $price * $discount;
}

The reason this exploit works is because register_globals has defined $promo_code and $discount based on the page’s query string before any of the script’s code was executed.

So how can one combat this? Easy, don’t assume what the value of $discount will be, explicitly set it to 0 by default.

Page: cart.php?promo_code=12save

$discount = 0;
if($promo_code == '12save') {
  $discount = 0.10;
}

if(isset($discount) && ($discount > 0)) {
  $price -= $price * $discount;
}

Be aware that register_globals will allow keys => values to be inserted into existing array variables – this is often missed by developers of all skill levels. Array keys used later in a script must be defined with a default value to avoid exploitable code.

Below is an example of an attacker successfully forcing a “debug” mode, thus allowing him/her to see PHP errors.

Page: index.php?config[debug]=1

if(isset($config['debug']) && ($config['debug'] == true)) {
  error_reporting(E_ALL);
}

Why Register Globals Should Be Turned Off

Having register_globals enabled is like playing with fire. It’s a crutch used by new or intermediate PHP developers that don’t know any better – or in some cases are just too lazy to use proper coding practices.

Since PHP 4.2.0 register_globals has been disabled by default; and in PHP 5.3 it’s now considered deprecated. However, many shard hosting companies keep it enabled on their servers as they host older sites that were developed during a time of heavy register_globals reliance.

If you are starting a new project on a server where you have access to the php.ini file I would suggest you turn off register_globals.

If you don’t have access to the php.ini file; you’re on a shard server; or you have other sites on your server that break when you turn register_globals off you can try adding the following line of code to the root directory’s .htaccess file…

File: .htaccess

php_flag register_globals off

Summary

It’s important to realize that register_globals, by itself, is not a security flaw within PHP. If a developer is following proper coding practices there is no need to worry about register_globals being on or off.

Remember to always define your variables and array keys before you use them!

Notice: A major release has been issued since this post – Version 2.0

Changing the domain name or URL of a WordPress site can be a very frustrating and time consuming task.

I usually have three development environments that I’m constantly switching between and all of them have completely different domain names.

Server URL
Local http://localhost:8888/myProject
Preview http://myProject.mysite.com
Production http://www.myProject.com

WordPress Domain Changer Screenshot

Fed up with all the steps needed to change the domain I decided it would be worth my time to build a script that could streamline the entire migration process. The first revision of this script was dirty and insecure (to say the least) but it significantly reduced the amount of time spent moving sites between servers and changing their domains.

In a later version I added functionality that allowed the script to read the wp-config.php file and extract DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, and $table_prefix. In addition to this I added five corresponding form fields and auto-populated them with the data parsed from the WordPress config file. This further reduced the amount of time spent setting up and running the domain change script.

When I started working on this latest revision I decided to go in another direction by developing the script into more of a standalone web application. I added simple authentication; better error checking; a console area displaying Errors, Notices, and Actions; and a “session” timeout feature all wrapped in a new user interface.

I’ve also added a mandatory 5 second wait (sleep) during authentication in order to combat the threat of a brute-force attack. However, even with this countermeasure in place it’s very important this script gets removed from the server as soon as the migration process has been completed.

How to Use / Instructions

  1. Backup your WordPress database.
  2. Seriously, Back Up Your Database!
  3. Situation One: You have a new server where you intend to upload your existing WordPress site files.
    1. Export the current WordPress database data into a SQL dump file.
    2. Create a MySQL database on the new server.
    3. Import the WordPress database dump file into the newly created database.
    4. Open up the wp-config.php file and set the DB_HOST, DB_USER, DB_PASSWORD, and DB_NAME constants to the correct values for the new server.
    5. Upload the WordPress directory contents to the domain directory on the new server.
  4. Situation Two: The WordPress files and database locations have not changed — just the domain name.
    • Coninue on to Step 5…
  5. Open up wpdc/config.php file in a text editor and replace the default password with a VERY secure password of your choice.
  6. Upload the entire wpdc/ directory to the root directory of your WordPress site.
    • Note: The root directory is where the wp-config.php is located.
  7. In a web browser go to: http://www.your-new-domain.com/wpdc
  8. Type in the password that you set in step 6 at the authentication prompt.
  9. You will now be presented with the domain changer form.
    1. The script will try and auto-detect all of the settings, but it’s up to you to confirm they are all correct.
  10. Take one last look at the settings to verify that they are correct… then click the “Change Domain!”” button.
  11. Go to your site’s home page at the new domain — all should be working!
  12. Once the domain has been changed remove this wpdc/ directory from the server!

License

This class and its code is released under the New-BSD License.

Requirements

  • PHP >= 5.0, with the MySQLi Extension enabled.
  • WordPress >= 2.8.0
    • Untested on previous versions

Download

The source code is available to anyone at http://github.com/veloper/WordPress-Domain-Changer.

If you’ve found an issue, improvement, or bug with this script please contact me or leave a comment.