Domain TLD Parser

Posted by Jad on September 17, 2007

Parsing URLs in PHP isn’t perfect. Don’t get me wrong here, it does the job when it comes to breaking the URL in logical parts, but, it doesn’t have any options to parse the host into domain name, TLD and sub-domain(s). Most probably because new TLDs are coming out from time to time and they want to avoid having to update that same function with every new TLD release.

To over-come this limitation and because I needed some way of extracting the domain, sub-domain and TLD out of each given URL, I came up with the following class: Domain TLD Parser

It parses hosts with all kinds of different TLDs, even the country-specific ones like ‘.co.za’, ‘.ne.jp’ or ‘.ltd.uk’. Here is an example:

<?php
$url = $_SERVER['HTTP_REFERER'];
include('/path/to/domain_tld_parser.class.php');
$domain = new DomainTldParser;
echo '<pre>';
print_r($domain->parse($url));
echo '</pre>';
?>

SELECT DISTINCT in CakePHP

Posted by Jad on August 31, 2007

Even though CakePHP’s model already includes many of the database query functions, I found that the SELECT DISTINCT was missing. Ok, I know that you can always do it using either Model->query('SELECT DISTINCT `c1`, `c2`) or Model->findAll(null, 'DISTINCT `c1`, `c2`') but that would be like saying use Model->query() instead of Model->findAll().

The cool thing in CakePHP is that you can add your own functions to use in your app on top of the ones that come bundled in the core. For the Model, you just create an ‘app_model.php’ file that you place in our app’s main folder. The empty file should look like this:

/**
 * Custom AppModel that adds functionality to the core Model
 */
class AppModel extends Model
{
   //empty
}

Now inside your new AppModel class, add the following function:

   /**
    * Returns a resultset array with DISTINCT fields from database matching given conditions.
    *
    * @param   mixed    $conditions SQL conditions as a string or as an array('field' =>'value',...)
    * @param   mixed    $fields Either a single string of a field name, or an array of field names
    * @return  array    Array of records
    */
   function findDistinct($conditions = null, $fields = null)
   {
      $db =& ConnectionManager::getDataSource($this->useDbConfig);

      $str = 'DISTINCT ';
      if (!is_array($fields))
      {
         $str .= '`' . $fields . '`';
      }
      else
      {
         foreach ($fields as $field)
         {
            $str .= '`' . $field . '`, ';
         }
         $str = substr($str, 0, -2);
      }

      $queryData = array(
                     'conditions'   => $conditions,
                     'fields'       => $str,
                     );
      $data = $db->read($this, $queryData, false);

      return $data;
   }

You can now use Model->findDistinct('c1') or Model->findDistinct(array('c1', 'c2', 'c3')) to retrieve DISTINCT columns values.

Hoping you find it useful.