I use Vagrant boxes for almost all of my development work. I recently came across this simple yet incredibly time-saving Vagrant tip. I use NFS to share files between my host computer and Vagrant box. While Vagrant makes this quite trivial to do Vagrant does require elevated permissions to mount the NFS share which means I need to enter my password everytime a Vagrant box starts up. This isn’t a huge deal as I only restart my Vagrant boxes a few times a week but I frequently will start up a box then go do something else while it boots and when I return later I see my box sitting at the password prompt. By adding a few lines to my /etc/sudoers file I just type vagrant up and I’m done.

1. Open up terminal. (CMD+SPACE, type in terminal)

2. Type in:
sudo visudo

3. Enter your password.

4. Add these lines to the bottom of the file.
Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
Cmnd_Alias VAGRANT_NFSD = /sbin/nfsd restart
Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /usr/bin/sed -E -e /*/ d -ibak /etc/exports
%admin ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD, VAGRANT_EXPORTS_REMOVE

In case you aren’t familiar with vim, press i to insert text, when done, press ESC, then : followed by wq then press enter.

Your done! Wait 5 minutes (because you just typed in your password like 30 seconds ago). Then type vagrant up from your project root and don’t enter your password.

Share

This past weekend I was trying to use the Zend Framework Twitter library. While the documentation made it look simple, it was missing a lot of steps and information. With the help of a lot of googling I came up with this:

[ad name=”Google Adsense 468×60″]

 
        $userToken = 'user_token';
        $userSecret = 'user_secret';
        
        $appConsumerKey = 'your_app_consumer_key';
        $appConsumerSecret = 'your_app_consumer_secret';
        
        // generate an Oauth token to pass to Zend_Service_Twitter
        $token = new Zend_Oauth_Token_Access();
        $token->setToken($userToken)
              ->setTokenSecret($userSecret);

        $options = array(
            'username'       => 'twitter_username',
            'accessToken'    => $token,
            'consumerKey'    => $appConsumerKey,
            'consumerSecret' => $appConsumerSecret
        );

        $twitter = new Zend_Service_Twitter($options);
        
        // verify user's credentials with Twitter
        var_export($twitter->account->verifyCredentials());
        
Share

I have installed the PHP extension Xdebug on multiple platforms and for some reason I keep forgetting how I manage to do it every time.

Below are the steps I followed to get Xdebug working with Zend Server CE 5.04 with PHP 5.3 on Windows 7 Ultimate 64-bit.

[ad name=”Google Adsense-1-box”]

  1. Download the correct Xdebug extension from here.
    Note: Although I am running a 64-bit OS, Zend Server CE 5.04 is 32-bit and requires 32-bit extensions so I downloaded the 32-bit version of Xdebug php_xdebug-2.1.0-5.3-vc9-nts.dll
  2. Copy the DLL to C:\Program Files (x86)\Zend\ZendServer\lib\phpext\
  3. Add the following lines ABOVE [Zend] in your php.ini file which is located at C:\Program Files (x86)\Zend\ZendServer\etc\php.ini
    [xdebug]
    zend_extension="C:\Program Files (x86)\Zend\ZendServer\lib\phpext\php_xdebug-2.1.0-5.3-vc9-nts.dll"
    
  4. Restart Apache
  5. Log in to the Zend Server GUI at http://localhost:10081/ZendServer and check the PHP Info page for Xdebug
  6. If you have an Xdebug section then it works. Now you’ll want to probably add some more configuration to the [xdebug] section of the php.ini file. See xdebug.org for more info.
Share

The Zend Framework Quick Start tutorial comes with a great example of the type of error handling Zend Framework can do. Any exception that is thrown almost anywhere in your application is caught and handled by the Error Controller. This allows for very customized development and/or user error messages. But what about generic PHP errors? What about PHP notices? It’s really annoying to see a white screen with a single PHP error after you’ve spent so long trying to get your pretty Error Controller handled errors looking so nice.

PHP has a nifty function called set_error_handler which allows you to, well, set the error handler. You provide it a callback function and it calls your function when something bad happens. While it obviously can’t catch all PHP errors, it does a pretty good job of catching most of the little annoying ones.

Below is a way to set your ErrorController as the PHP error handler.

[ad name=”Google Adsense 468×60″]

Add the following method to your Bootstrap.php class.

public function __construct($application) {
    parent::__construct($application);
    MyApp_Error_Handler::set();
}

Add this code to a file called library/MyApp/Error/Handler.php

class MyApp_Error_Handler {
    public static function handle($errno, $errstr, $errfile, $errline) 
    {
        if (!error_reporting()) return;
        throw new Exception($errstr . " in $errfile:$errline". $errno);
    }
        
    public static function set()
    {
        set_error_handler(array(__CLASS__, 'handle'));
    }
}
    

Share

I know I haven’t blogged since August but I have a good excuse. My team and I have been working really hard towards the public beta release of our new online wish list app Wishing Wagon. Basically, Wishing Wagon allows you to create lists of items you would like to receive for a special occasion like Christmas, birthday, wedding, etc. The advantage of Wishing Wagon over other store-based wish lists is that we aren’t store-based. You can add any item you want from any online or physical store.

Since my blog is primarily about technical topics and I’m not sure if promoting my web app can be classified as a miscellaneous rant, I’ll talk a bit about the architecture of Wishing Wagon.

[ad name=”Google Adsense 468×60″]

The site was built using PHP and of course my favourite PHP framework, Zend Framework. For the database, instead of MySQL, this time we decided to use Couch DB. I must say that using documents instead of using relational databases feels so much more natural. Documents fit much better with models and I don’t have to worry about Many-to-Many relationships anymore. Couch DB took a bit of time to get used to, but I am now hooked and will try to use Couch whenever eventual consistency is an option.

During the development of Wishing Wagon, I’ve also come to appreciate the built-in Amazon API support in Zend Framework. Retrieving products and searching for items is a breeze. I was a little surprised at how easy it was.

The site is hosted on Rackspace Cloud and is load balanced using HAproxy. We use Rackspace Cloud files as our CDN and we use the Compass Rackspace Cloud Files Zend Framework Library to upload files to the CDN.

I’ll try to blog a bit more about our development experience in the next few weeks.

Don’t forget Christmas is only 45 days away! Why not create a Wishing Wagon and add some items? Oh, and did I mention it’s free?

Share