Oct 26 / Richard Knop

Clear command line, variables and command history in MATLAB

Here are three useful MATLAB commands.

To clear the command line:

clc

To clear all variables:

clear all

To clear the command history:

com.mathworks.mlservices.MLCommandHistoryServices.removeAll

Just putting this information down for my own reference so I won’t have to search for it later.

Oct 23 / Richard Knop

Free Windows Server 2008 R2 Standard Edition

If you are a high school or college student you can download Windows Server 2008 R2 Standard Edition for free from the Microsoft DreamSpark website. You can also download Visual Studio, Expression Studio and other useful applications for free.

The only thing you need is a valid Hotmail e-mail account and an ISIC card number. It’s very easy :)

Oct 22 / Richard Knop

WAMPSERVER 2.0: adding virtual hosts

I often need to test several Zend Framework projects on my local machine (I’m running Windows Vista and WAMPSERVER 2.0). To do that, I just create a virtual host for every project. There are just two files you have to modify:

  • C:\wamp\bin\apache\Apache2.2.11\conf\httpd.conf
  • C:\Windows\System32\drivers\etc\hosts

Paths to those files may differ on your PC, depends on the installation.

For instance, you might want to save your Zend Framework project to “C:\wamp\www\myproject” and access it with “http://myproject”. Add this at the end of the httpd.conf file:

NameVirtualHost *:80
<VirtualHost *:80>
    ServerName myproject
    DocumentRoot "C:\wamp\www\myproject"
</VirtualHost>

Now open the hosts file and write on the last line:

127.0.0.1    myproject    # my cool ZF project

Restart all services and it should work.

Oct 19 / Richard Knop

Changing MAC address in Windows Vista

As promised, here’s how to change your MAC address in Windows Vista (this method will hopefully also work in Windows 7).

Go to Start -> Control Panel -> View network status and tasks -> Manage network connections (in the left sidebar).

Choose the connection for which you want to change the MAC address, right click on it and select “Properties”.

Click on the “Configure” button and go to “Advanced” tab. In the “Property” box look for “Network address”. Now you should see a window like this:

Changing MAC address in Windows Vista

Instead of “000000000000″ fill in your desired MAC address and press “OK” button. Open the command prompt and check that the MAC address got changed:

ipconfig /all
Oct 17 / Richard Knop

How to change your MAC address

From time to time you will need to change the MAC address of your computer. My Internet provider, for instance, allows me to connect only my desktop PC to the Internet. To connect my laptop I had to change its MAC address to the same MAC address my desktop PC has.

First, donwload Macshift and save it to some convenient location like C:\ and extract it.

Second, you must know the name of the connection you want to change. Usually it will be the Ethernet called “Local Area Connection”.

Third, open the command line (Start -> Run -> “cmd”) and type:

cd C:\macshift

The above command moved you to the C:\macshift directory. Now type (just substitute 012345123456 with an actual MAC address):

macshift 012345123456 -i "Local Area Connection"

If you want to find out what MAC addres your PC has, type in the command line:

ipconfig /all

And look for “Physical Address”.

However, this works only in Windows XP. I will cover Windows Vista/Seven in my next post.

Oct 14 / Richard Knop

Uploading files with Zend Framework

Uploading files with Zend Framework is an easy and straightforward task. First, you need to create a form from which to upload files. For example, here is a very simple form for uploading a picture with just two fields – picture title and a file input field:

  1. class UploadPicture extends Zend_Form
  2. {
  3.     public function init()
  4.     {
  5.         $this->setMethod('post');
  6.  
  7.         $title = new Zend_Form_Element_Text('title', array(
  8.             'label' => 'Title',
  9.             'required' => false,
  10.             'filters' => array(
  11.                 'StringTrim'
  12.             ),
  13.             'validators' => array(
  14.                 array('StringLength', false, array(3, 100))
  15.             ),
  16.         ));
  17.  
  18.         $picture = new Zend_Form_Element_File('picture', array(
  19.             'label' => 'Picture',
  20.             'required' => true,
  21.             'MaxFileSize' => 2097152, // 2097152 bytes = 2 megabytes
  22.             'validators' => array(
  23.                 array('Count', false, 1),
  24.                 array('Size', false, 2097152),
  25.                 array('Extension', false, 'gif,jpg,png'),
  26.                 array('ImageSize', false, array('minwidth' => 100,
  27.                                                 'minheight' => 100,
  28.                                                 'maxwidth' => 1000,
  29.                                                 'maxheight' => 1000))
  30.             )
  31.         ));
  32.  
  33.         $picture->setValueDisabled(true);
  34.  
  35.         $submit = new Zend_Form_Element_Submit('upload_picture', array(
  36.             'label' => 'Upload the picture!'
  37.         ));
  38.  
  39.         $this->addElements(array(
  40.             $title,
  41.             $picture,
  42.             $submit
  43.         ));
  44.     }
  45. }

Besides few filters and validators, there is one important line:

  1. $picture->setValueDisabled(true);

From ZF 1.8, files are automatically received when you call $form->getValues() method. I like to receive files manually because sometimes I will want to add some new filter or validator based on values from the submitted form. So, the $element->setValueDisabled(true) disables the automatic transfer of files.

Second thing you need to do is to handle the form submission in the controller. Here is how to do that:

  1. public function uploadPictureAction()
  2. {
  3.     $request = $this->getRequest();
  4.  
  5.     $form = $this->_getForm('UploadPicture',
  6.                             $this->_helper->url('upload-picture'));
  7.  
  8.     // if POST data has been submitted
  9.     if ($request->isPost()) {
  10.         // if the UploadPicture form has been submitted and the submitted data is valid
  11.         if (isset($_POST['upload_picture']) && $form->isValid($_POST)) {
  12.  
  13.             $data = $form->getValues();
  14.  
  15.             // get the picture extension
  16.             $ext = end(explode('.', $form->picture->getFileName()));
  17.  
  18.             // you will probably want to save the picture in the database
  19.             $dbTrans = false;
  20.  
  21.             try {
  22.  
  23.                 $db = $this->_getDb();
  24.                 $dbTrans = $db->beginTransaction();
  25.  
  26.                 // query the database here
  27.  
  28.                 $db->commit();
  29.  
  30.                 // where do you want to save the image?
  31.                 $path = 'images/my-image.' . $ext;
  32.  
  33.                 // add filter for renaming the uploaded picture
  34.                 $form->picture->addFilter('Rename',
  35.                                           array('target' => $path,
  36.                                                 'overwrite' => true));
  37.  
  38.                 // upload the picture
  39.                 $form->picture->receive();                
  40.  
  41.                 $form->reset();
  42.  
  43.             } catch (Exception $e) {
  44.                 if (true === $dbTrans) {
  45.                     $db->rollBack();
  46.                 }
  47.                 // pass possible exceptions to the view
  48.                 $this->view->error = $e->getMessage();
  49.             }
  50.  
  51.         }
  52.     }
  53.  
  54.     // pass the form to the view
  55.     $this->view->form = $form;
  56. }

In case you are wondering what method I used to initialize the form, here it is (I think I’ve already posted it in one of my older entries):

  1. private function _getForm($form, $action = null)
  2. {
  3.     include APPLICATION_PATH . '/modules/' . $this->_request->getModuleName()
  4.     . '/forms/' . $form . '.php';
  5.     $form = new $form();
  6.     if (null !== $action) {
  7.         $form->setAction($action);
  8.     }
  9.     return $form;
  10. }

So, that’s it. It wasn’t too difficult, was it?

For some more details, study the Zend_Form_Element_File documentation.

Oct 6 / Richard Knop

PHP & Google Checkout

I’ve been working on several projects lately that have involved Google Checkout integration on various levels. Besides a basic HTML integration you can get going in few seconds (just by copy and pasting the sample code from the documentation) you can also entirely integrate the checkout process with your websites through the Google Checkout API.

There are also sample classes for different languages (PHP, .NET, JSP etc) that allow you to receive responses from Google Checkout about a stage the checkout process is currently in (an order goes through many stages until it becomes processed and your customer’s credit card gets actually charged such as “REVIEWING”, “CHARGEABLE”, “CHARGING”, “CHARGED”) so you can update your local database accordingly.

There are few small errors in the sample class from Google though so I have decided to post the working version and explain briefly how to use it. Here’s a snippet from one of my projects (it’s actually a Zend Framework controller action):

  1. public function responseHandlerAction()
  2. {
  3.     // point to the correct directory
  4.     chdir(APPLICATION_PATH . '/../library/Google/Checkout');
  5.     // include all the required files
  6.     include('googlecart.php');
  7.     include('googleitem.php');
  8.     include('googleshipping.php');
  9.     include('googletax.php');
  10.     include('googleresponse.php');
  11.     include('googlerequest.php');
  12.  
  13.     $merchant_id = 'your merchant id here…';
  14.     $merchant_key = 'your merchant key here…';
  15.     $server_type = 'sandbox'; // change this to anything other than 'sandbox' to go live
  16.     $currency = 'GBP'; // USD for dollar
  17.  
  18.     $Gresponse = new GoogleResponse($merchant_id, $merchant_key);
  19.  
  20.     $Grequest = new GoogleRequest($merchant_id, $merchant_key, $server_type, $currency);
  21.  
  22.     // retrieve the XML sent in the HTTP POST request to the ResponseHandler
  23.     $xml_response = isset($HTTP_RAW_POST_DATA) ?
  24.     $HTTP_RAW_POST_DATA:file_get_contents("php://input");
  25.     if (get_magic_quotes_gpc()) {
  26.         $xml_response = stripslashes($xml_response);
  27.     }
  28.     list($root, $data) = $Gresponse->GetParsedXML($xml_response);
  29.     $Gresponse->SetMerchantAuthentication($merchant_id, $merchant_key);
  30.  
  31.     $status = $Gresponse->HttpAuthentication();
  32.     if (!$status) {
  33.         die('authentication failed');
  34.     }
  35.  
  36.     switch ($root) {
  37.         case 'new-order-notification':
  38.  
  39.             /*
  40.              * $google_id = $data[$root]['google-order-number']['VALUE'];
  41.              * $items = $this->get_arr_result($data[$root]['shopping-cart']['items']['item']);
  42.              * foreach ($items as $item) {
  43.              *     $id = $item['merchant-item-id']['VALUE'];
  44.              *     // do something here…
  45.              * }
  46.              */
  47.  
  48.             $Gresponse->SendAck();
  49.  
  50.             break;
  51.         case 'order-state-change-notification':
  52.  
  53.             $new_financial_state = $data[$root]['new-financial-order-state']['VALUE'];
  54.             $new_fulfillment_order = $data[$root]['new-fulfillment-order-state']['VALUE'];
  55.  
  56.             switch ($new_financial_state) {
  57.                 case 'REVIEWING':
  58.  
  59.                     // do something here…
  60.  
  61.                     break;
  62.                 case 'CHARGEABLE':
  63.  
  64.                     $Grequest->SendProcessOrder($data[$root]['google-order-number']['VALUE']);
  65.                     $Grequest->SendChargeOrder($data[$root]['google-order-number']['VALUE'], '');
  66.  
  67.                     break;
  68.                 case 'CHARGING':
  69.  
  70.                     // do something here…
  71.  
  72.                     break;
  73.                 case 'CHARGED':
  74.  
  75.                     /*
  76.                      * $google_id = $data[$root]['google-order-number']['VALUE'];
  77.                      * do something here…
  78.                      */
  79.  
  80.                     break;
  81.                 case 'PAYMENT_DECLINED':
  82.  
  83.                     // do something here…
  84.  
  85.                     break;
  86.                 case 'CANCELLED':
  87.  
  88.                     // do something here…
  89.  
  90.                     break;
  91.                 case 'CANCELLED_BY_GOOGLE':
  92.  
  93.                     $message = 'Sorry, your order is cancelled by Google'
  94.                     $Grequest->SendBuyerMessage($data[$root]['google-order-number']['VALUE'], $message, true);
  95.  
  96.                     break;
  97.                 default:
  98.  
  99.                     break;
  100.             }
  101.  
  102.             switch ($new_fulfillment_order) {
  103.                 case 'NEW':
  104.  
  105.                     // do something here…
  106.  
  107.                     break;
  108.                 case 'PROCESSING':
  109.  
  110.                     // do something here…
  111.  
  112.                     break;
  113.                 case 'DELIVERED':
  114.  
  115.                     // do something here…
  116.  
  117.                     break;
  118.                 case 'WILL_NOT_DELIVER':
  119.  
  120.                     // do something here…
  121.  
  122.                     break;
  123.                 default:
  124.  
  125.                     // do something here…
  126.  
  127.                     break;
  128.             }
  129.  
  130.             $Gresponse->SendAck();
  131.             break;
  132.         case 'charge-amount-notification':
  133.  
  134.             // do something here…
  135.  
  136.             $Gresponse->SendAck();
  137.  
  138.             break;
  139.         case 'chargeback-amount-notification':
  140.  
  141.             // do something here…
  142.  
  143.             $Gresponse->SendAck();
  144.  
  145.             break;
  146.         case 'refund-amount-notification':
  147.  
  148.             // do something here…
  149.  
  150.             $Gresponse->SendAck();
  151.  
  152.             break;
  153.         case 'risk-information-notification':
  154.  
  155.             // do something here…
  156.  
  157.             $Gresponse->SendAck();
  158.  
  159.             break;
  160.         default:
  161.  
  162.             // do something here…
  163.  
  164.             $Gresponse->SendBadRequestStatus('Invalid or not supported Message');
  165.  
  166.             break;
  167.     }
  168. }
  169.  
  170. private function get_arr_result($child_node) {
  171.     $result = array();
  172.     if (isset($child_node)) {
  173.         if ($this->is_associative_array($child_node)) {
  174.             $result[] = $child_node;
  175.         } else {
  176.             foreach ($child_node as $curr_node){
  177.                 $result[] = $curr_node;
  178.             }
  179.         }
  180.     }
  181.     return $result;
  182. }
  183.  
  184. private function is_associative_array($var) {
  185.     return is_array ($var) && !is_numeric (implode('', array_keys($var)));
  186. }

95% of the code above is taken from the responsehandler.php on this page. I have only made little modifications to make it all work because the original code contained few errors.

Now, how to make it all work? First, go here and download the latest sample code. Unzip the archive and copy all files except responsehandler.php and cartdemo.php to some location in your project (I just created a directory called ‘Google’ and put all files there in my library folder).

Second, you need to create a shopping cart or at least a checkout button that will take your customers to the Google Checkout page where they can pay for the product with their credit/debit cards. Here is just an example from one of my latest projects (a short excerpt of the checkout action):

  1. // point to the correct directory
  2. chdir(APPLICATION_PATH . '/../library/Google/Checkout');
  3. // include all the required files
  4. include('googlecart.php');
  5. include('googleitem.php');
  6. include('googleshipping.php');
  7. include('googletax.php');
  8.  
  9. $merchant_id = 'xxxxxxxxxxxxxxxx';
  10. $merchant_key = 'xxxxxxxxxxxxxxxxxxxxxx';
  11. $server_type = 'sandbox';
  12. $currency = 'GBP';
  13. $cart = new GoogleCart($merchant_id, $merchant_key, $server_type,
  14.                        $currency);
  15.  
  16. $item = new GoogleItem("Digital Item",
  17.                        "Description",
  18.                        1, // quantity
  19.                        $price); // unit price
  20. $item->SetMerchantItemId($id);
  21. $item->SetEmailDigitalDelivery('true');
  22. $cart->AddItem($item);
  23.  
  24. // <edit-cart-url>
  25. $cart->SetEditCartUrl('http://mydomain.com/controller/action');
  26.  
  27. // "Return to xyz" link
  28. $cart->SetContinueShoppingUrl('http://mydomain.com/controller/action');
  29.  
  30. // request buyer's phone number
  31. $cart->SetRequestBuyerPhone(false);
  32.  
  33. $this->view->checkoutButton = $cart->CheckoutButtonCode('large',
  34.                                                         true,
  35.                                                         'en_US',
  36.                                                         false);

Third, you need to configure your Google Checkout account to send callbacks to the response-handler action. Remember that when you are testing the integration in the sandbox, you can just use ordinary http:// URIs but when you go live, Google Checkout requires you to use https:// at least on the response-handler action URI.

The actual PHP integration depends on the website you want to integrate Google Checkout with so I’m not going to show you how to do that. I can give you some very basic guidelines though:

  1. I usually have a special table where I store all Google Checkout transactions. On the page with Google Checkout button I create a new row in the table and use the primary key to set a merchant item id ($item->SetMerchantItemId($id)). This helps me determine the transaction id in the response-handler action.
  2. In the “new-order-notification” callback I get the google order number and edit the transaction in the table based on the merchant item id I set earlier.
  3. In the “CHARGED” callback I mark the transaction in the table as finished based on its google order number (usually the table has a boolean field with default value 0 called “finished”, so I set it to 1).
Oct 5 / Richard Knop

SQLSTATE[42000]: Syntax error or access violation: 1064

If you are using PDO adapter to work with databases in Zend Framework you might come across an exception similar to this:

Message: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 2

It took me some time to track down the cause of this error message. I was building a complex query with Zend_Db_Select which included several joins and subqueries so I thought I had made a mistake in syntax somewhere but the problem was I was passing an undefined variable to where() method. So the problematic line was:

$select->where($where);

And $where was not defined. Hope this helps somebody.

Addendum (Oct 6, 2009 @ 14:13)

The same problem can occur also when there is any error in your WHERE clause, for instance:

WHERE id =

The above (there’s a missing integer after “id =”) would throw the same exception.

Sep 29 / Richard Knop

JQuery autosave on click event

What does this simple jQuery snippet do? When you click on the link with class “autosave”, the form with id “autosave” is submitted via POST request to the same page. After that it redirects to the actual target of the link (href attribute).

  1. $(document).ready(function() {
  2.     $('a.autosave').click(function() {
  3.         // get relative address of the current window/tab
  4.         var url = window.location.pathname;
  5.         // collect the data from the form with id "autosave-form"
  6.         $postData = $('form#autosave').serialize();
  7.         // submit the form
  8.         $.post(url, $postData, function(data) {
  9.             // after the ajax request is successful, redirect to the link target
  10.             window.location.href = $('#autosave').attr('href');
  11.         });
  12.         // prevent default behavior
  13.         return false;
  14.     });
  15. });

This can be useful in numerous situations. For example, on the page where user can edit his/her profile, you want to have a link saying something like “view my profile”. But you don’t want less experienced users to click on the link and lose all changes they have made to their profile (which happens quite a lot).

Sep 29 / Richard Knop

PHP array of United Kingdom counties

I think some of you might find this useful. I couldn’t find array of UK counties anywhere on the Web so I had to manually write them all down. Here’s the array:

  1. $ukCounties = array(
  2.     'Bedfordshire' => 'Bedfordshire',
  3.     'Berkshire' => 'Berkshire',
  4.     'Buckinghamshire' => 'Buckinghamshire',
  5.     'Cambridgeshire' => 'Cambridgeshire',
  6.     'Cheshire' => 'Cheshire',
  7.     'Cornwall' => 'Cornwall',
  8.     'Cumberland' => 'Cumberland',
  9.     'Derbyshire' => 'Derbyshire',
  10.     'Devon' => 'Devon',
  11.     'Dorset' => 'Dorset',
  12.     'Durham' => 'Durham',
  13.     'East Yorkshire' => 'East Yorkshire',
  14.     'Essex' => 'Essex',
  15.     'Gloucestershire' => 'Gloucestershire',
  16.     'Hampshire' => 'Hampshire',
  17.     'Herefordshire' => 'Herefordshire',
  18.     'Hertfordshire' => 'Hertfordshire',
  19.     'Huntingdonshire' => 'Huntingdonshire',
  20.     'Kent' => 'Kent',
  21.     'Lancashire' => 'Lancashire',
  22.     'Leicestershire' => 'Leicestershire',
  23.     'Lincolnshire' => 'Lincolnshire',
  24.     'Middlesex' => 'Middlesex',
  25.     'Norfolk' => 'Norfolk',
  26.     'North Yorkshire' => 'North Yorkshire',
  27.     'Northamptonshire' => 'Northamptonshire',
  28.     'Northumberland' => 'Northumberland',
  29.     'Nottinghamshire' => 'Nottinghamshire',
  30.     'Oxfordshire' => 'Oxfordshire',
  31.     'Rutland' => 'Rutland',
  32.     'Shropshire' => 'Shropshire',
  33.     'Somerset' => 'Somerset',
  34.     'Staffordshire' => 'Staffordshire',
  35.     'Suffolk' => 'Suffolk',
  36.     'Surrey' => 'Surrey',
  37.     'Sussex' => 'Sussex',
  38.     'Warwickshire' => 'Warwickshire',
  39.     'West Yorkshire' => 'West Yorkshire',
  40.     'Westmorland' => 'Westmorland',
  41.     'Wiltshire' => 'Wiltshire',
  42.     'Worcestershire' => 'Worcestershire',
  43.     'Aberdeenshire' => 'Aberdeenshire',
  44.     'Angus/Forfarshire' => 'Angus/Forfarshire',
  45.     'Argyllshire' => 'Argyllshire',
  46.     'Ayrshire' => 'Ayrshire',
  47.     'Banffshire' => 'Banffshire',
  48.     'Berwickshire' => 'Berwickshire',
  49.     'Buteshire' => 'Buteshire',
  50.     'Cromartyshire' => 'Cromartyshire',
  51.     'Caithness' => 'Caithness',
  52.     'Clackmannanshire' => 'Clackmannanshire',
  53.     'Dumfriesshire' => 'Dumfriesshire',
  54.     'Dunbartonshire/Dumbartonshire' => 'Dunbartonshire/Dumbartonshire',
  55.     'East Lothian/Haddingtonshire' => 'East Lothian/Haddingtonshire',
  56.     'Fife' => 'Fife',
  57.     'Inverness-shire' => 'Inverness-shire',
  58.     'Kincardineshire' => 'Kincardineshire',
  59.     'Kinross-shire' => 'Kinross-shire',
  60.     'Kirkcudbrightshire' => 'Kirkcudbrightshire',
  61.     'Lanarkshire' => 'Lanarkshire',
  62.     'Midlothian/Edinburghshire' => 'Midlothian/Edinburghshire',
  63.     'Morayshire' => 'Morayshire',
  64.     'Nairnshire' => 'Nairnshire',
  65.     'Orkney' => 'Orkney',
  66.     'Peeblesshire' => 'Peeblesshire',
  67.     'Perthshire' => 'Perthshire',
  68.     'Renfrewshire' => 'Renfrewshire',
  69.     'Ross-shire' => 'Ross-shire',
  70.     'Roxburghshire' => 'Roxburghshire',
  71.     'Selkirkshire' => 'Selkirkshire',
  72.     'Shetland' => 'Shetland',
  73.     'Stirlingshire' => 'Stirlingshire',
  74.     'Sutherland' => 'Sutherland',
  75.     'West Lothian/Linlithgowshire' => 'West Lothian/Linlithgowshire',
  76.     'Wigtownshire' => 'Wigtownshire',
  77.     'Anglesey/Sir Fon' => 'Anglesey/Sir Fon',
  78.     'Brecknockshire/Sir Frycheiniog' => 'Brecknockshire/Sir Frycheiniog',
  79.     'Caernarfonshire/Sir Gaernarfon' => 'Caernarfonshire/Sir Gaernarfon',
  80.     'Carmarthenshire/Sir Gaerfyrddin' => 'Carmarthenshire/Sir Gaerfyrddin',
  81.     'Cardiganshire/Ceredigion' => 'Cardiganshire/Ceredigion',
  82.     'Denbighshire/Sir Ddinbych' => 'Denbighshire/Sir Ddinbych',
  83.     'Flintshire/Sir Fflint' => 'Flintshire/Sir Fflint',
  84.     'Glamorgan/Morgannwg' => 'Glamorgan/Morgannwg',
  85.     'Merioneth/Meirionnydd' => 'Merioneth/Meirionnydd',
  86.     'Monmouthshire/Sir Fynwy' => 'Monmouthshire/Sir Fynwy',
  87.     'Montgomeryshire/Sir Drefaldwyn' => 'Montgomeryshire/Sir Drefaldwyn',
  88.     'Pembrokeshire/Sir Benfro' => 'Pembrokeshire/Sir Benfro',
  89.     'Radnorshire/Sir Faesyfed' => 'Radnorshire/Sir Faesyfed',
  90.     'County Antrim' => 'County Antrim',
  91.     'County Armagh' => 'County Armagh',
  92.     'County Down' => 'County Down',
  93.     'County Fermanagh' => 'County Fermanagh',
  94.     'County Tyrone' => 'County Tyrone',
  95.     'County Londonderry/Derry' => 'County Londonderry/Derry',
  96. );

Here is also an array of all world countries even though this is easily found all around the Web (just in case :D ):

  1. $countries = array(
  2.     'United Kingdom' => 'United Kingdom',
  3.     'United States' => 'United States',
  4.     'Afghanistan' => 'Afghanistan',
  5.     'Albania' => 'Albania',
  6.     'Algeria' => 'Algeria',
  7.     'American Samoa' => 'American Samoa',
  8.     'Andorra' => 'Andorra',
  9.     'Angola' => 'Angola',
  10.     'Anguilla' => 'Anguilla',
  11.     'Antarctica' => 'Antarctica',
  12.     'Antigua And Barbuda' => 'Antigua And Barbuda',
  13.     'Argentina' => 'Argentina',
  14.     'Armenia' => 'Armenia',
  15.     'Aruba' => 'Aruba',
  16.     'Australia' => 'Australia',
  17.     'Austria' => 'Austria',
  18.     'Azerbaijan' => 'Azerbaijan',
  19.     'Bahamas' => 'Bahamas',
  20.     'Bahrain' => 'Bahrain',
  21.     'Bangladesh' => 'Bangladesh',
  22.     'Barbados' => 'Barbados',
  23.     'Belarus' => 'Belarus',
  24.     'Belgium' => 'Belgium',
  25.     'Belize' => 'Belize',
  26.     'Benin' => 'Benin',
  27.     'Bermuda' => 'Bermuda',
  28.     'Bhutan' => 'Bhutan',
  29.     'Bolivia' => 'Bolivia',
  30.     'Bosnia And Herzegowina' => 'Bosnia And Herzegowina',
  31.     'Botswana' => 'Botswana',
  32.     'Bouvet Island' => 'Bouvet Island',
  33.     'Brazil' => 'Brazil',
  34.     'British Indian Ocean Territory' => 'British Indian Ocean Territory',
  35.     'Brunei Darussalam' => 'Brunei Darussalam',
  36.     'Bulgaria' => 'Bulgaria',
  37.     'Burkina Faso' => 'Burkina Faso',
  38.     'Burundi' => 'Burundi',
  39.     'Cambodia' => 'Cambodia',
  40.     'Cameroon' => 'Cameroon',
  41.     'Canada' => 'Canada',
  42.     'Cape Verde' => 'Cape Verde',
  43.     'Cayman Islands' => 'Cayman Islands',
  44.     'Central African Republic' => 'Central African Republic',
  45.     'Chad' => 'Chad',
  46.     'Chile' => 'Chile',
  47.     'China' => 'China',
  48.     'Christmas Island' => 'Christmas Island',
  49.     'Cocos (Keeling) Islands' => 'Cocos (Keeling) Islands',
  50.     'Colombia' => 'Colombia',
  51.     'Comoros' => 'Comoros',
  52.     'Congo' => 'Congo',
  53.     'Congo, The Democratic Republic Of The' => 'Congo, The Democratic Republic Of The',
  54.     'Cook Islands' => 'Cook Islands',
  55.     'Costa Rica' => 'Costa Rica',
  56.     'Cote D\'Ivoire' => 'Cote D\'Ivoire',
  57.     'Croatia (Local Name: Hrvatska)' => 'Croatia (Local Name: Hrvatska)',
  58.     'Cuba' => 'Cuba',
  59.     'Cyprus' => 'Cyprus',
  60.     'Czech Republic' => 'Czech Republic',
  61.     'Denmark' => 'Denmark',
  62.     'Djibouti' => 'Djibouti',
  63.     'Dominica' => 'Dominica',
  64.     'Dominican Republic' => 'Dominican Republic',
  65.     'East Timor' => 'East Timor',
  66.     'Ecuador' => 'Ecuador',
  67.     'Egypt' => 'Egypt',
  68.     'El Salvador' => 'El Salvador',
  69.     'Equatorial Guinea' => 'Equatorial Guinea',
  70.     'Eritrea' => 'Eritrea',
  71.     'Estonia' => 'Estonia',
  72.     'Ethiopia' => 'Ethiopia',
  73.     'Falkland Islands (Malvinas)' => 'Falkland Islands (Malvinas)',
  74.     'Faroe Islands' => 'Faroe Islands',
  75.     'Fiji' => 'Fiji',
  76.     'Finland' => 'Finland',
  77.     'France' => 'France',
  78.     'France, Metropolitan' => 'France, Metropolitan',
  79.     'French Guiana' => 'French Guiana',
  80.     'French Polynesia' => 'French Polynesia',
  81.     'French Southern Territories' => 'French Southern Territories',
  82.     'Gabon' => 'Gabon',
  83.     'Gambia' => 'Gambia',
  84.     'Georgia' => 'Georgia',
  85.     'Germany' => 'Germany',
  86.     'Ghana' => 'Ghana',
  87.     'Gibraltar' => 'Gibraltar',
  88.     'Greece' => 'Greece',
  89.     'Greenland' => 'Greenland',
  90.     'Grenada' => 'Grenada',
  91.     'Guadeloupe' => 'Guadeloupe',
  92.     'Guam' => 'Guam',
  93.     'Guatemala' => 'Guatemala',
  94.     'Guinea' => 'Guinea',
  95.     'Guinea-Bissau' => 'Guinea-Bissau',
  96.     'Guyana' => 'Guyana',
  97.     'Haiti' => 'Haiti',
  98.     'Heard And Mc Donald Islands' => 'Heard And Mc Donald Islands',
  99.     'Holy See (Vatican City State)' => 'Holy See (Vatican City State)',
  100.     'Honduras' => 'Honduras',
  101.     'Hong Kong' => 'Hong Kong',
  102.     'Hungary' => 'Hungary',
  103.     'Iceland' => 'Iceland',
  104.     'India' => 'India',
  105.     'Indonesia' => 'Indonesia',
  106.     'Iran (Islamic Republic Of)' => 'Iran (Islamic Republic Of)',
  107.     'Iraq' => 'Iraq',
  108.     'Ireland' => 'Ireland',
  109.     'Israel' => 'Israel',
  110.     'Italy' => 'Italy',
  111.     'Jamaica' => 'Jamaica',
  112.     'Japan' => 'Japan',
  113.     'Jordan' => 'Jordan',
  114.     'Kazakhstan' => 'Kazakhstan',
  115.     'Kenya' => 'Kenya',
  116.     'Kiribati' => 'Kiribati',
  117.     'Korea, Democratic People\'s Republic Of' => 'Korea, Democratic People\'s Republic Of',
  118.     'Korea, Republic Of' => 'Korea, Republic Of',
  119.     'Kuwait' => 'Kuwait',
  120.     'Kyrgyzstan' => 'Kyrgyzstan',
  121.     'Lao People\'s Democratic Republic' => 'Lao People\'s Democratic Republic',
  122.     'Latvia' => 'Latvia',
  123.     'Lebanon' => 'Lebanon',
  124.     'Lesotho' => 'Lesotho',
  125.     'Liberia' => 'Liberia',
  126.     'Libyan Arab Jamahiriya' => 'Libyan Arab Jamahiriya',
  127.     'Liechtenstein' => 'Liechtenstein',
  128.     'Lithuania' => 'Lithuania',
  129.     'Luxembourg' => 'Luxembourg',
  130.     'Macau' => 'Macau',
  131.     'Macedonia, Former Yugoslav Republic Of' => 'Macedonia, Former Yugoslav Republic Of',
  132.     'Madagascar' => 'Madagascar',
  133.     'Malawi' => 'Malawi',
  134.     'Malaysia' => 'Malaysia',
  135.     'Maldives' => 'Maldives',
  136.     'Mali' => 'Mali',
  137.     'Malta' => 'Malta',
  138.     'Marshall Islands' => 'Marshall Islands',
  139.     'Martinique' => 'Martinique',
  140.     'Mauritania' => 'Mauritania',
  141.     'Mauritius' => 'Mauritius',
  142.     'Mayotte' => 'Mayotte',
  143.     'Mexico' => 'Mexico',
  144.     'Micronesia, Federated States Of' => 'Micronesia, Federated States Of',
  145.     'Moldova, Republic Of' => 'Moldova, Republic Of',
  146.     'Monaco' => 'Monaco',
  147.     'Mongolia' => 'Mongolia',
  148.     'Montserrat' => 'Montserrat',
  149.     'Morocco' => 'Morocco',
  150.     'Mozambique' => 'Mozambique',
  151.     'Myanmar' => 'Myanmar',
  152.     'Namibia' => 'Namibia',
  153.     'Nauru' => 'Nauru',
  154.     'Nepal' => 'Nepal',
  155.     'Netherlands' => 'Netherlands',
  156.     'Netherlands Antilles' => 'Netherlands Antilles',
  157.     'New Caledonia' => 'New Caledonia',
  158.     'New Zealand' => 'New Zealand',
  159.     'Nicaragua' => 'Nicaragua',
  160.     'Niger' => 'Niger',
  161.     'Nigeria' => 'Nigeria',
  162.     'Niue' => 'Niue',
  163.     'Norfolk Island' => 'Norfolk Island',
  164.     'Northern Mariana Islands' => 'Northern Mariana Islands',
  165.     'Norway' => 'Norway',
  166.     'Oman' => 'Oman',
  167.     'Pakistan' => 'Pakistan',
  168.     'Palau' => 'Palau',
  169.     'Panama' => 'Panama',
  170.     'Papua New Guinea' => 'Papua New Guinea',
  171.     'Paraguay' => 'Paraguay',
  172.     'Peru' => 'Peru',
  173.     'Philippines' => 'Philippines',
  174.     'Pitcairn' => 'Pitcairn',
  175.     'Poland' => 'Poland',
  176.     'Portugal' => 'Portugal',
  177.     'Puerto Rico' => 'Puerto Rico',
  178.     'Qatar' => 'Qatar',
  179.     'Reunion' => 'Reunion',
  180.     'Romania' => 'Romania',
  181.     'Russian Federation' => 'Russian Federation',
  182.     'Rwanda' => 'Rwanda',
  183.     'Saint Kitts And Nevis' => 'Saint Kitts And Nevis',
  184.     'Saint Lucia' => 'Saint Lucia',
  185.     'Saint Vincent And The Grenadines' => 'Saint Vincent And The Grenadines',
  186.     'Samoa' => 'Samoa',
  187.     'San Marino' => 'San Marino',
  188.     'Sao Tome And Principe' => 'Sao Tome And Principe',
  189.     'Saudi Arabia' => 'Saudi Arabia',
  190.     'Senegal' => 'Senegal',
  191.     'Seychelles' => 'Seychelles',
  192.     'Sierra Leone' => 'Sierra Leone',
  193.     'Singapore' => 'Singapore',
  194.     'Slovakia (Slovak Republic)' => 'Slovakia (Slovak Republic)',
  195.     'Slovenia' => 'Slovenia',
  196.     'Solomon Islands' => 'Solomon Islands',
  197.     'Somalia' => 'Somalia',
  198.     'South Africa' => 'South Africa',
  199.     'South Georgia, South Sandwich Islands' => 'South Georgia, South Sandwich Islands',
  200.     'Spain' => 'Spain',
  201.     'Sri Lanka' => 'Sri Lanka',
  202.     'St. Helena' => 'St. Helena',
  203.     'St. Pierre And Miquelon' => 'St. Pierre And Miquelon',
  204.     'Sudan' => 'Sudan',
  205.     'Suriname' => 'Suriname',
  206.     'Svalbard And Jan Mayen Islands' => 'Svalbard And Jan Mayen Islands',
  207.     'Swaziland' => 'Swaziland',
  208.     'Sweden' => 'Sweden',
  209.     'Switzerland' => 'Switzerland',
  210.     'Syrian Arab Republic' => 'Syrian Arab Republic',
  211.     'Taiwan' => 'Taiwan',
  212.     'Tajikistan' => 'Tajikistan',
  213.     'Tanzania, United Republic Of' => 'Tanzania, United Republic Of',
  214.     'Thailand' => 'Thailand',
  215.     'Togo' => 'Togo',
  216.     'Tokelau' => 'Tokelau',
  217.     'Tonga' => 'Tonga',
  218.     'Trinidad And Tobago' => 'Trinidad And Tobago',
  219.     'Tunisia' => 'Tunisia',
  220.     'Turkey' => 'Turkey',
  221.     'Turkmenistan' => 'Turkmenistan',
  222.     'Turks And Caicos Islands' => 'Turks And Caicos Islands',
  223.     'Tuvalu' => 'Tuvalu',
  224.     'Uganda' => 'Uganda',
  225.     'Ukraine' => 'Ukraine',
  226.     'United Arab Emirates' => 'United Arab Emirates',
  227.     'United States Minor Outlying Islands' => 'United States Minor Outlying Islands',
  228.     'Uruguay' => 'Uruguay',
  229.     'Uzbekistan' => 'Uzbekistan',
  230.     'Vanuatu' => 'Vanuatu',
  231.     'Venezuela' => 'Venezuela',
  232.     'Viet Nam' => 'Viet Nam',
  233.     'Virgin Islands (British)' => 'Virgin Islands (British)',
  234.     'Virgin Islands (U.S.)' => 'Virgin Islands (U.S.)',
  235.     'Wallis And Futuna Islands' => 'Wallis And Futuna Islands',
  236.     'Western Sahara' => 'Western Sahara',
  237.     'Yemen' => 'Yemen',
  238.     'Yugoslavia' => 'Yugoslavia',
  239.     'Zambia' => 'Zambia',
  240.     'Zimbabwe' => 'Zimbabwe');