You are currently browsing the archives for the Code Igniter category


Code Hinting & Autocompletion for CodeIgniter in PHPStorm

Finally, moving back and forth between models, views and controllers is just too distracting and time consuming. I had to find another way to navigate my way between codes. I tweeted asking about alternative IDEs in Mac OS X to achieve this. Turns out there is a way!

I got a tip from @LuisFAlonso (THANK YOU!) to check out instructions from a blog here. I followed the instructions and restarted PHPStorm afterwards. Sadly, it didn’t work :(

I did a Google search and was happy to read a blog post here. But it didn’t work (again). The instructions was to copy paste lines of comments directly to the system/core/Controller.php and system/core/Model.php. The thing is, my system folder is outside the public folder. So I copy pasted the Controller part to application/core/MY_Controller.php. It WORKED!

Now I’m happy with a new IDE and Code hinting + Autocompletion!

Hacking CodeIgniter for Persistent Timestamped Cache with Memcache

I’ve got myself a long title for a blog post this time. This post is exactly what the title says. Been twisting my head figuring out how to bypass CodeIgniter’s internal to hack CodeIgniter’s ability to do a persistent timestamped cache of generated HTML contents using Memcached. I couldn’t find any other way to speed up cached HTML content serving within the framework, so after a long talk with @chazzuka, I made the choice to skip framework.

The main purpose is actually what all websites want, to spit out content as fast as possible and maintaining a high satisfactory levels of perceived speed for users. CodeIgniter wasn’t built for that. To make matter more complicated, CodeIgniter has its own session handling mechanism, this made fundamental changes to caching for logged in users a risky business. Comparing the benefits and losses of the change, 0.00001242 second execution time outbid even the fastest execution time on our servers.

Please share the codes :)

Error when loading gists from http://gist.github.com/.

HandlerSocket Client Library for CodeIgniter

These past weeks, I’ve been amazed by the amazing performance offered by HandlerSocket right out of the box. You’d amaze yourself after reading a blog post by Yoshinori Matsunobu about the topic, he managed to get 750 thousands queries per second!

Well I wanted to try it on my own and see how it goes. Here’s a CodeIgniter library intended just for that!

Error when loading gists from http://gist.github.com/.

CodeIgniter Session With Memcache + Anti Bots!

Last night was a thrilling change of routine. Urbanesia was crippled because of the unprecedented growth of our MongoDB databases. I must admit that MongoDB is like Memcache with steroids, well it overdosed. MongoDB doesn’t have any mechanism to limit its memory usages, the only limit we can define is the size of its individual files. Therefore, something must be done!

The second flaw was with CodeIgniter by design. By default, CodeIgniter uses its own Session handling mechanism either by using cookie and or database. The database types supported were limited to drivers available for CodeIgniter. Well we hacked it to use MongoDB a few months ago.

The boomerang was that CodeIgniter again by default does not filter bots for its session mechanism. Urbanesia is very attractive to bots and therefore all of our sessions were mostly bots, this equals junk data. The garbage collector for sessions was also very primitive. We had to do something about this.

We wanted a fast and simple yet elegant solution to tackle the problems above. MySQL is out of the question of course, Insert/Update activities will surely lock tables and we can’t afford it. So we turned to Memcache. The most important built in feature with Memcache was its ability to limit memory usage and therefore giving us a garbage collector for stale sessions without extra codes at all!

There are no known Memcache session handling available with CodeIgniter as to my knowledge, so I went ahead and did a whole redo of our MY_Session library to accomodate Memcache as our Session storage engine. The first thing to do was to filter bots that frequently visit Urbanesia and deny them sessions, instead a cookie will do them just fine.

function __detectVisit() {
       $this->CI->load->library('user_agent');
       $agent = strtolower($this->CI->input->user_agent());

       $bot_strings = array(
           "google", "bot", "yahoo", "spider", "archiver", "curl",
           "python", "nambu", "twitt", "perl", "sphere", "PEAR",
           "java", "wordpress", "radian", "crawl", "yandex", "eventbox",
           "monitor", "mechanize", "facebookexternal", "bingbot"
       );

       foreach($bot_strings as $bot) {
               if(strpos($agent, $bot) !== false) {
                       return "bot";
               }
       }

       return "normal";
}

Yes it’s quite primitive but it works and it satisfied our needs to filter the most frequent bots. The next step was to build namespaces adjusted with some of CodeIgniter’s built in Session handling mechanisms.

function __build_namespace($sess_id, $ip_addr = 0, $user_agent = '') {
	$this->namespace .= $sess_id;
	if($this->sess_match_ip == TRUE && $ip_addr > 0)
		$this->namespace .= '#'.ip2long($ip_addr);
	if($this->sess_match_useragent == TRUE && $user_agent != '')
		$this->namespace .= '#'.md5($user_agent);
}

The 3 parameters accepted are all components within a standard CodeIgniter Session. Since CodeIgniter gave us options like sess_match_ip and sess_match_useragent, it’s important to adjust the namespace as a filter of its own actually. One of the most difficult part was to decide whether to use JSON or serialized array to store custom user data. I decided to use JSON in the end. Here’s a code snippet of setting a session value to Memcache.

$this->CI->memsess->set($this->namespace, json_encode($this->userdata), $this->sess_expiration);

FYI, I used another library called memsess, short of Memcache Sessions lol to let me shard Memcache arrays. I wanted an exclusive Memcache instance solely be used to store sessions. The main reason was to keep session data as tidy as possible meaning that there are no other data that will push the sessions data away unless we tell them to. This makes the Memcache instance far more predictable. Most of the codings were derived from CI_Session and modified to use Memcache as storage. I will not go into the full details of the library, instead I’m gonna give the code for the sess_read() method. I’m pretty sure it’s enough for you to experiment on your own.

function sess_read() {
	// Kick out bots!
	if($this->is_bot) {
		$this->sess_destroy();
		return FALSE;
	}

	$session = $this->CI->input->cookie($this->sess_cookie_name);

	if($session === FALSE) {
		return FALSE;
	}

	if ($this->sess_encrypt_cookie == TRUE) {
		$session = $this->CI->encrypt->decode($session);
	} else {
		$hash	 = substr($session, strlen($session)-32);
		$session = substr($session, 0, strlen($session)-32);

		if ($hash !==  md5($session.$this->encryption_key)) {
			$this->sess_destroy();
			return FALSE;
		}
	}

	$session = $this->_unserialize($session);

	if (
		!is_array($session)
		OR ! isset($session['session_id'])
		OR ! isset($session['ip_address'])
		OR ! isset($session['user_agent'])
		OR ! isset($session['last_activity'])
	) {
		$this->sess_destroy();
		return FALSE;
	}

	if (($session['last_activity'] + $this->sess_expiration) < $this->now) {
		$this->sess_destroy();
		return FALSE;
	}

	if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address()) {
		$this->sess_destroy();
		return FALSE;
	}

	if (
		$this->sess_match_useragent == TRUE
		AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50))
		) {
		$this->sess_destroy();
		return FALSE;
	}

	// Build namespace!
	$this->__reset_namespace();
	$this->__build_namespace($session['session_id'], $session['ip_address'], $session['user_agent']);

	$query = $this->CI->memsess->get($this->namespace);
	if(empty($query)) {
		$this->sess_destroy();
		return FALSE;
	}

	$row = json_decode($query);
	if(isset($row->user_data) AND $row->user_data != '') {
		$custom_data = $this->_unserialize($row->user_data);
		if(is_array($custom_data)) {
			foreach($custom_data as $key => $val) {
				$session[$key] = $val;
			}
		}
	}

	$this->userdata = $session;
	unset($session);

	return TRUE;
}

There you go, a glimpse into Session management in CodeIgniter with Memcache. This is a product of experiment because of needs. I’m sure it can be done in smarter ways, the sky is the limit ;)


photo of Batista Batista R Harahap [email protected]
Jl. Bango II/29C, Pondok Labu
Cilandak , DKI Jakarta , 12450 Indonesia
62817847023

This hCard created with the hCard creator.