Search:

Search all manuals
Search this manual
Manual
Getting Started with Membase and PHP
Additional Resources
Community Wiki
Community Forums
Couchbase SDKs
Parent Section
Getting Started with Membase and PHP
Chapter Sections
Chapters

4. Accessing PHP from Membase

Counting the number of times a web page has been accessed, and recording the last access date of the web page, are two common tasks in web development. To demonstrate how to use Membase, we'll implement those features in PHP using the Membase library.

The data storage model of Membase is similar to that of the Array data type in PHP. You can store a value accessed by a key of some sort, then retrieve the value by the key. In this article we'll be storing and retrieving integer and string data (see Listing 1).

Listing 1: PHP/Memcached page counter and last accessed code

<?php
#Create the Memcached object
$mc_obj = new Memcached();
$mc_obj->addServer('localhost', 11211);

#determine the name of the script currently running
    $script_name=$_SERVER["SCRIPT_NAME"];

#if the script name doesn't exist as a Membase key then add
    $script_access_count=$mc_obj->get($script_name);
if($mc_obj->getResultCode() == Memcached::RES_NOTFOUND){
#the add will fail if it has already been added
       $mc_obj->add($script_name,0);
    }

#increment the integer associated with the script name
    $access_count = $mc_obj->increment($script_name);


#print the current access count
    echo "this page ($script_name) accessed $access_count times<br>";

  #retrieve the last access date/time of the script.
 #the key name is is the script name prefixed with DATE::
$last_access_date=$mc_obj->get("DATE::" . $script_name);

#handle the case where this is the first access to the script
#and that key doesn't yet exist
    if($last_access_date ==FALSE){
     $last_access_date = "never";
    }
    echo "this page last accessed: " . $last_access_date;

#save the current access date/time in a script
    $mc_obj->set("DATE::" . $script_name,date("F j, Y, g:i:s a "));
?>

The above listing can be saved into a PHP file in a directory served by your web server.

Here we've saved it as test.php.

When you load test.php page you'll see something like this on the first load:

this page (/test.php) accessed 1 times
this page last accessed: never

And like this on subsequent loads, with the access count incrementing and the date/time increasing:

this page (/test.php) accessed 2 times
this page last accessed: June 1, 2011, 10:06:04 am

Reload the script a few times in rapid succession and you'll see a spike in traffic in the Membase Web UI. So, what exactly is our script doing to achieve this?

The first line of the script creates a Memcached object ($mc_obj), and then adds a Membase server hostname and port to the server pool that we'll be accessing. In this case we're only adding the one server running on our localhost, but any hostname with a Membase server may be specified. The port number, 11211 is the "default" bucket where keys are stored, though you can assign different buckets to different ports via the Moxi server bundled with Membase, which manages connection pools, timeouts and cluster topology changes for you.

$mc_obj = new Memcached();
$mc_obj->addServer('localhost', 11211);

We then get the "SCRIPT_NAME" value from the $_SERVER Array, which tells us in which script this PHP code is currently running.

$script_name=$_SERVER["SCRIPT_NAME"];

Now we connect to Membase to retrieve the integer access count associated with this script using the script name (determined above) as the key.

$script_access_count=$mc_obj->get($script_name);

If there is no such key in Membase (because the page has not previously been accessed), the request returns a Boolean FALSE value, and the result code of the call to the get method is the Memcached constant RES_NOTFOUND (resource not found). In this case we use the add method to set the value to zero. If, between the failed get and add method calls, the key has already been added by another process, the add will fail and we will not overwrite the added value. This sort of attention to concurrency issues is overkill for the current application, as a missed counting of a single script access is unlikely to be critical; however, it illustrates how to write memcached code to avoid unintentionally overwriting keys:

if($mc_obj->getResultCode() == Memcached::RES_NOTFOUND){
       $mc_obj->add($script_name,0);
}

The key associated with the script name count is then incremented by one for the current script access, and that incremented value is returned and printed out. The increment method is atomic, consisting of both an increment and retrieval of the resultant value. If the Membase server receives two such requests, they will be queued for action in the order they were received and return the correct count to each requesting process.

$access_count = $mc_obj->increment($script_name);
echo "this page ($script_name) accessed $access_count times<br>";

To retrieve and update the last access date of the script we're doing something similar to what we did for the script access count, however, instead of adding and incrementing an integer, we're adding and updating a string.

As a key for the date any given script was accessed, we've prepended the string "DATE::" to the beginning of the script name; thus the key for the last access date of our test.php script is "DATE::test.php". We first try to get the date of last access and assign it to the $last_access_date variable. If this fails (the get method returns a Boolean FALSE value and the subsequent getResultCode call returns RES_NOTFOUND) that means it hasn't yet been set, so the script has not previously been accessed. In that case we'll set $last_access_date to "never". We then print out the value of $last_access_date.

$last_access_date=$mc_obj->get("DATE::" . $script_name);
 if($mc_obj->getResultCode() == Memcached::RES_NOTFOUND){
    $last_access_date = "never";
}
echo "this page last accessed: " . $last_access_date;

We now set the access date for this access of the script for retrieval on the next access.

$mc_obj->set("DATE::" . $script_name,date("F j, Y, g:i:s a "));

And that's the end of the script. There is no method in the memcached library to close the connection to the server, however it will automatically be closed at the end of script execution.