CodeIgniter + XAMPP (0.7.1) + OS X Setup Guide

Having a decent development environment is important for any developer, and getting CodeIgniter and XAMPP setup on OS X (or any platform) is a snap! Sure, OS X ships with Apache, but I really like the stand-alone style of XAMPP. Plus, since XAMPP is cross platform, I can easily move my environment between platforms and minimize the need to re-configure anything.

First a little background though. The XAMPP project is a wonderful bundle created by the Apache Friends. It includes Apache, MySQL, PHP and Perl. For PHP, it includes both PHP4 and PHP5, and also ships with PHPMyAdmin for administering the MySQL server. Basically, it lives in a single directory and doesn't need to be "installed". For Windows users this is a huge plus (refer to XAMPPLite).

The CodeIgniter (CI) project is intended to be a very lightweight, highly extendable MVC frakework for PHP4 and PHP5. Sure, there are other frameworks out there such as CakePHP, but I prefer CI due to it's incredible documentation and because I feel it is more lightweight.

Go ahead and download CodeIgniter and XAMPP for OS X if you do not already have them. I prefer to checkout CodeIgniter from the SVN; you can read instructions on doing that here. Once you have both of the packages, start by installing XAMPP. For OS X users, I opted for XAMPP MacOS X (tar) 0.7.1. To get this going, run the following command:

$ sudo tar xfvz xampp-macosx-0.7.1.tar.gz -C /

This will extract the tarball into /Applications/xampp/. Following the CI SVN article on Derek Allard's site, I checked out CI #844 into /Users/ldavison/sandbox/ci_844/ using svnX. As you can see, I have put my CI source into a directory that is non-public to my XAMPP installation. In fact, this is one of the most parts of the setup in my opinion; making sure CI is outside the web servers DocumentRoot. Of course, a lot of the CI source has this in the top of the files:

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

However, I still feel it's better if the files aren't in a public directory to begin with avoiding any direct access to the source.
The next thing is to copy the index.php file into the DocumentRoot, in fact it's the only file in the CI code that needs to be publicly accessible.

$ sudo cp /Users/ldavison/sandbox/ci_844/index.php /Applications/xampp/htdocs/. $ sudo vim /Applications/xampp/htdocs/index.php

In the index.php file, edit the path to the system folder, in this case:

$system_folder = "system";

becomes:

$system_folder = "/Users/ldavison/sandbox/ci_844/system";

In order to get XAMPP to use mod_rewrite and read the configuration from a .htaccess file, the /Applicatons/xampp/etc/httpd.conf file needs to be updated. Look for the section:

<Directory "/Applications/xampp/xamppfiles/htdocs">

In here there will be a line that reads:

AllowOverride AuthConfig

Change that to read:

AllowOverride AuthConfig FileInfo

Restart the servers in XAMPP, by running:

$ sudo /Applications/xampp/xamppfiles/mampp restart

Alternatively, you could find out the PID of the apache process owned by root and kill -HUP it. That will force Apache to reload it's config:

$ ps aux | grep httpd
nobody   51504   0.0  0.1   103016   1220   ??  S

     3:38AM   0:00.00 /Applications/xampp/xamppfiles/bin/httpd -k start -DSSL -DPHP5
nobody   51503   0.0  0.1   103016   1220   ??  S

     3:38AM   0:00.00 /Applications/xampp/xamppfiles/bin/httpd -k start -DSSL -DPHP5
nobody   51502   0.0  0.1   103016   1220   ??  S

     3:38AM   0:00.00 /Applications/xampp/xamppfiles/bin/httpd -k start -DSSL -DPHP5
nobody   51501   0.0  0.1   100384   1252   ??  S

     3:38AM   0:00.00 /Applications/xampp/xamppfiles/bin/httpd -k start -DSSL -DPHP5
root     51454   0.0  0.4   103016   7596   ??  Ss

    3:38AM   0:00.24 /Applications/xampp/xamppfiles/bin/httpd -k start -DSSL -DPHP5
nobody   51506   0.0  0.1   103016   1220   ??  S

     3:38AM   0:00.00 /Applications/xampp/xamppfiles/bin/httpd -k start -DSSL -DPHP5
nobody   51505   0.0  0.1   103016   1220   ??  S

     3:38AM   0:00.00 /Applications/xampp/xamppfiles/bin/httpd -k start -DSSL -DPHP5

 

$ sudo kill -HUP 51454

That should kill all the child processes (owned by nobody) and re-spawn them with the updated httpd.conf file. If the web server is not running, double check that the configuration added was correct. You can look at the error_log to see why Apache failed to start with the updated configuration by running:

$ tail /Applications/xampp/logs/error_log

Once the httpd.conf file has been updated properly and Apache successfully reloaded, add the below to /Applications/xampp/htdocs/.htaccess. That will tell Apache what the rewrite rules are for mod_rewrite in the htdocs directory, which will remove index.php from your URI. For instance, http://localhost/index.php/controller/action will become http://localhost/controller/action.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

<IfModule !mod_rewrite.c>

    # If we don't have mod_rewrite installed, all 404's
    # can be sent to index.php, and everything works as normal.
    # Submitted by: ElliotHaughin

    ErrorDocument 404 /index.php
</IfModule> 

 

Alternatively, you can add the above to the <Directory "/Applications/xampp/xamppfiles/htdocs"> section, but for development (why we're using XAMPP to begin with) I prefer using .htaccess so I don't have to restart Apache to alter certain configurations. You might want to re-think this in a production environment, of course checking with your system administrators is always best.

At this point, everything should be working properly and you should have a fresh new development environment setup! So, get after it, write some code! Free free to hit me up with any questions or comments.

Google Web Toolkit - Build AJAX apps in the Java language

Yesterday Google released a Beta of the Google Web Toolkit. Basically, it is a toolkit written in Java that allows developers to create AJAX applications; a Java to JavaScript compiler. After reading through some of the documentation and looking through the sample apps I decided to give it a shot. The documentation was good and in roughly an hour I had a page that could fetch information from flickr.com using an RPC call.

Sadly though, I'm disappointed there is no OS X version yet, but I understand it's due to the embedded web-browser. So, technically I could use this on OS X, but having the embedded browser is really nice. It allows you to treat your Java source more like any scripting language. You change the Java source, save it and simply refresh the browser window in the embedded browser. Once it's reached the point where you like it, compile it and test it in an external browser.

I'm pretty stoked about this release. I have looked at other rapid AJAX development toolkits like RubyOnRails or Mockingbird, but I like the idea behind this one better. Hopefully I'll have more time to play with this, I've already got a widget I'd like to create in mind!

Google Web Toolkit - Build AJAX apps in the Java language

Nifty BASH Function

At work, I end up spending a lot of time on servers, constantly working out of multiple directories. The directories are always the same, and sometimes cd - works for what I'm doing. However, if I am working out of three or more directories that is no longer the case, which is typical.

Today, one of my fellow nerds at the nerdery passed along two BASH functions that will make my life WAY easier. He didn't write them, and I'm not sure who did. But, just add them to your ~/.bash_profile or ~/.bashrc file and your ready to go after you re-login:

mk() { eval ${1:-MKPWD}=\"`pwd`\"; }
rt() { eval cd \"\$${1:-MKPWD}\";pwd; }

When your in a directory that you want to "bookmark", just type mk like so:

~/sandbox/$ mk sandbox

Then later:

/var/www/logs/$ rt $sandbox

Since it is exported as an ENV var, you can also copy things to it, for instance:

/var/www/logs/$ tail -n 20 error_log > $sandbox/last_20.log

Another IE Bug

This afternoon, I have been working to find out why in Internext Explorer (IE) I can't set the innerHTML value of a SPAN element without IE throwing a "Unknown Runtime Error". Of course, the SAME code works flawlessly in Mozilla/Firefox (Gecko really). First thing I did was consult the MSDN pages for innerHTML, and guess what it says? In a nutshell, it states it should work.

This made me think. Maybe I'm not passing the correct HTML or something stupid like that. So, I started removing elements until I had Testing. That worked. But, I am trying to use

    and
  • . What I found out through trial and error is that you can set SOME elements using innerHTML in IE, but not all of them. So far, the ones that fail are

    ,

      ,
    • , I haven't tested many others. I was able to use CSS and SPAN's to hack around this problem. Just extremely annoying that one has to do that in the first place.

       

      What I wanna know is when the fuck Microsoft will wake up and smell the fucking coffee? How about a browser that actually works fellas? - FUCK!

Binary Flags

I was talking to my friend Toby earlier today, bitching to him about binary flags. I was stuck on an issue with them and was havng a hell of a time getting it sorted out, since I wasn't sure what the flags needed to be.

Anyways, I was having a hard time explaining to him how it works as he is not a developer, but a network guru. So, I put it in his world, since I could demonstrate to him the same process using IP addresses and subnet masks. Another example is the umask in *nix operatin systems. After trying to explain it, I thought I'd put together some sample code showing how this works in the networking world.

Here is a C example showing how one would get the "valid" subnet mask for an IP address:

Toggle C Source for subnet_lookup.c:

The important part of this starts with:

  msb = *(unsigned char *) &adr_inet.sin_addr.s_addr;    if ((msb & 0x80) == 0x00) {       class = 'A';       netmask = "255.0.0.0";   } 

This returns the IP you specified on the command line in the correct format. We then combine that with a hex value to see if it is equal to another hex value. Since IP addresses and subnet masks are 32bit binary, when &'d together, it's like doing binary addition. And how does that work you might ask? Here is an example:

  1 + 1 = 10 (which is 0, you would carry the 1)   0 + 1 = 1   0 + 0 = 0   1 + 0 + 0 = 1   1 + 1 + 0 = 10 (again this is 0, you would carry the 1)   1 + 1 + 1 = 1 (this would be 11, you would carry the 1 here too) 

Okay, confused yet? Good! No, seriously though, it's pretty easy since you can only use 1's or 0's. Here is a more complete example of how binary values would be added together:

01101 + 10111 = 100100  This is why:    0 1 1 0 1 +  1 0 1 1 1 ------------- 1 0 0 1 0 0 

Not so bad huh? Starting from the right, we take 1 + 1, which REALLY is 10. So, it becomes 0, and you "carry" the 1. With me still? great! So, now we take 1 + 0 + 1, which again is 10. This too becomes 0 and you "carry" the 1 again. This time, we take 1 + 1 + 1, which is 11. If you've been following along, you would make it 1, then "carry" the 1.

Anyways, I've rambled way more then I intended to. If you haven't gotten it figured out by now, you either A) have no hope at all, B) consult the Oracle.