Nginx Memcached module And PHP

I’ve seen lots of tutorials on internet explaining how set nginx to use memcached module. But, i’ve rarely seen them explaining, even the easiest one on how to populate memcached with data generated by php. When i’m getting in touch with memcached for the first time, i thought default configuration like this will be working out of the box. without touching php script. 😀

server {

	listen 80;
	server_name  example.com www.example.com;

	# ...

	location ~ \.php$ {
		set $memcached_key "kutu:$request_uri";
		memcached_pass 127.0.0.1:11211;

		default_type       text/html;
		error_page 404 405 502 = @cache_miss;
	}

	location @cache_miss {
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME /path/to/yoursite/htdocs$fastcgi_script_name;
		include /etc/nginx/fastcgi_params;
	}

	# ...
}

Well, i was totally confused :D. so, to prevent other people misinterpret on how nginx memcached module works, i wrote simple examples, and simple explainations on how to configure nginx and populate data generated from php.

First on nginx configuration

	location ~ \.php$ {
		set $memcached_key "kutu:$request_uri";
		memcached_pass 127.0.0.1:11211;

		default_type       text/html;
		error_page 404 405 502 = @cache_miss;
	}

set $memcached_key “kutu:$request_uri”; will tell nginx to use memcahed key “kutu:$request_uri” Example: “kutu:/mc.php”

memcached_pass 127.0.0.1:11211; tell nginx to pass “kutu:$request_uri” to memcached backend.

if key is found in memcached backend send the value to client, if not error_page 404 405 502 let’s fallback to @cache_miss and process request as usual.

	location @cache_miss {
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME /path/to/yoursite/htdocs$fastcgi_script_name;
		include /etc/nginx/fastcgi_params;
	}

Well, this was well known configuration to make nginx talked to php-cgi engine. no need to explain much further.   Remember, default configuration surely will be run properly, even without memcached server running on your system. :D. because that’s how the configuration tells nginx what to to do. jump to fallback (@cache_miss) if there’s error_page 404 405 502 responses.

Php sections

Setup simple database on mysql server

CREATE DATABASE memcache;
USE memcache;
CREATE TABLE memc
(
personID int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(personID),
FirstName varchar(15),
LastName varchar(15),
Age int
);

INSERT INTO memc (FirstName, LastName, Age) VALUES('Memory', 'Cache', '200');

Create db.php , this template is use for connecting to mysql db

<?php
$dbhost = '127.0.0.1';
$dbuser = 'user';
$dbpass = 'pass';

$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');

$dbname = 'memcache';
mysql_select_db($dbname);
?>

Create mc.php

<?php
$memcache = new Memcache;
$memcache->connect('127.0.0.1', 11211) or die ("Could not connect");

include('./db.php');

$uriString = $_SERVER['REQUEST_URI'];

$key = "kutu:" . $uriString;
$get_result = array();
$get_result = $memcache->get($key);

if (empty($get_result)) {
        // Run the query and get the data from the database then cache it
        $query="SELECT * FROM memc where FirstName='Memory';";
        $result = mysql_query($query);

        $row = mysql_fetch_array($result);
        echo "uri_request:" . $uriString . "\n";
        echo "<pre>\n";
        echo "FirstName: " . $row[1] . "\n";
        echo "LastName: " . $row[2] . "\n";
        echo "Age: " . $row[3] . "\n";
        echo "</pre>\n";
        echo "Retrieved the Page directly\n";

        $htmlrow =
                "uri_request:" . $uriString . "\n" .
                "<pre>\n" .
                "FirstName: " . $row[1] . "\n" .
                "LastName: " . $row[2] . "\n" .
                "Age: " . $row[3] . "\n" .
                "</pre>\n" .
                "Retrieved the Page from memcache now";

        $memcache->set($key, $htmlrow, MEMCACHE_COMPRESSED, 120); // Store the result of the query for 120 seconds

        mysql_free_result($result);
}

?>

$htmlrow is variables that we use to hold mysql query results and other text. we will use it as value in

$memcache->set($key, $htmlrow, MEMCACHE_COMPRESSED, 120);

Firstime we load the page http://www.example.com/mc.php

nginx memcached php 1
nginx memcached php 1

Reload page, nginx will serve it from memcached backend

nginx memcached php 2
nginx memcached php 2

that’s it

9 Comments

  1. wenjianhn

    Just a little fix.

    Insert “root /path/to/yoursite/htdocs;” into “server { … }”.

    Is “CREATE DATABASE memcache”, not “CREATE DATABSE memcache;”.

  2. wenjianhn

    Very usefull tutorial for newbies like me.
    Sorry, I fogot to say thank you.

  3. PHPConnect

    I have try this but on browser showing me garbage characters any idea why this happening?

    • have you populate data to memcached properly?when browser showing garbage that mean nginx have problem parsing mime type either nginx receiving garbage from memcached.

  4. hdegenaro

    Hi,

    When I run the script db.php, the page is blank. Another doubt is regarding the observation of the first post. He mentions the path “root/path/ to/yoursite/htdocs;” …. This path is the location of the web server? In my case that would be the nginx “/usr/share/nginx/www”? Is this the way?

    • db.php is inclusion for mc.php
      see this line in mc.php

      ...
      include('./db.php');
      ...
      

      that’s default nginx’s path, you can specified custom path like this, and put scripts there

              location / {
                  root   /path/to/doc;
                  index  index.php index.html index.htm;
              }
      
  5. Zipper

    Thanks for nice article! After 20th Google’s page I understood how to make it work! 😀

Leave a Reply

Your email address will not be published. Required fields are marked *