I18N_Arabic
[ class tree: I18N_Arabic ] [ index: I18N_Arabic ] [ all elements ]

Source for file Soundex.php

Documentation is available at Soundex.php

  1. <?php
  2. /**
  3.  * ----------------------------------------------------------------------
  4.  *
  5.  * Copyright (c) 2006-2013 Khaled Al-Sham'aa.
  6.  *
  7.  * http://www.ar-php.org
  8.  *
  9.  * PHP Version 5
  10.  *
  11.  * ----------------------------------------------------------------------
  12.  *
  13.  * LICENSE
  14.  *
  15.  * This program is open source product; you can redistribute it and/or
  16.  * modify it under the terms of the GNU Lesser General Public License (LGPL)
  17.  * as published by the Free Software Foundation; either version 3
  18.  * of the License, or (at your option) any later version.
  19.  *
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU Lesser General Public License for more details.
  24.  *
  25.  * You should have received a copy of the GNU Lesser General Public License
  26.  * along with this program.  If not, see <http://www.gnu.org/licenses/lgpl.txt>.
  27.  *
  28.  * ----------------------------------------------------------------------
  29.  *
  30.  * Class Name: Arabic Soundex
  31.  *
  32.  * Filename:   Soundex.php
  33.  *
  34.  * Original    Author(s): Khaled Al-Sham'aa <khaled@ar-php.org>
  35.  *
  36.  * Purpose:    Arabic soundex algorithm takes Arabic word as an input
  37.  *             and produces a character string which identifies a set words
  38.  *             that are (roughly) phonetically alike.
  39.  *              
  40.  * ----------------------------------------------------------------------
  41.  *  
  42.  * Arabic Soundex
  43.  *
  44.  * PHP class for Arabic soundex algorithm takes Arabic word as an input and
  45.  * produces a character string which identifies a set words of those are
  46.  * (roughly) phonetically alike.
  47.  * 
  48.  * Terms that are often misspelled can be a problem for database designers. Names,
  49.  * for example, are variable length, can have strange spellings, and they are not
  50.  * unique. Words can be misspelled or have multiple spellings, especially across
  51.  * different cultures or national sources.
  52.  * 
  53.  * To solve this problem, we need phonetic algorithms which can find similar
  54.  * sounding terms and names. Just such a family of algorithms exists and is called
  55.  * SoundExes, after the first patented version.
  56.  * 
  57.  * A Soundex search algorithm takes a word, such as a person's name, as input and
  58.  * produces a character string which identifies a set of words that are (roughly)
  59.  * phonetically alike. It is very handy for searching large databases when the user
  60.  * has incomplete data.
  61.  * 
  62.  * The original Soundex algorithm was patented by Margaret O'Dell and Robert
  63.  * C. Russell in 1918. The method is based on the six phonetic classifications of
  64.  * human speech sounds (bilabial, labiodental, dental, alveolar, velar, and
  65.  * glottal), which in turn are based on where you put your lips and tongue to make
  66.  * the sounds.
  67.  * 
  68.  * Soundex function that is available in PHP, but it has been limited to English and
  69.  * other Latin-based languages. This function described in PHP manual as the
  70.  * following: Soundex keys have the property that words pronounced similarly produce
  71.  * the same soundex key, and can thus be used to simplify searches in databases
  72.  * where you know the pronunciation but not the spelling. This soundex function
  73.  * returns string of 4 characters long, starting with a letter.
  74.  * 
  75.  * We develop this class as an Arabic counterpart to English Soundex, it handle an
  76.  * Arabic input string formatted in UTF-8 character set to return Soundex key
  77.  * equivalent to normal soundex function in PHP even for English and other
  78.  * Latin-based languages because the original algorithm focus on phonetically
  79.  * characters alike not the meaning of the word itself.
  80.  * 
  81.  * Example:
  82.  * <code>
  83.  *   include('./I18N/Arabic.php');
  84.  *   $obj = new I18N_Arabic('Soundex');
  85.  *     
  86.  *   $soundex = $obj->soundex($name);
  87.  * </code>
  88.  *    
  89.  * @category  I18N
  90.  * @package   I18N_Arabic
  91.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  92.  * @copyright 2006-2013 Khaled Al-Sham'aa
  93.  *    
  94.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  95.  * @link      http://www.ar-php.org
  96.  */
  97.  
  98. // New in PHP V5.3: Namespaces
  99. // namespace I18N\Arabic;
  100. // 
  101. // $obj = new I18N\Arabic\Soundex();
  102. // 
  103. // use I18N\Arabic;
  104. // $obj = new Arabic\Soundex();
  105. //
  106. // use I18N\Arabic\Soundex as Soundex;
  107. // $obj = new Soundex();
  108.  
  109. /**
  110.  * This PHP class implement Arabic soundex algorithm
  111.  *  
  112.  * @category  I18N
  113.  * @package   I18N_Arabic
  114.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  115.  * @copyright 2006-2013 Khaled Al-Sham'aa
  116.  *    
  117.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  118.  * @link      http://www.ar-php.org
  119.  */ 
  120. {
  121.     private $_asoundexCode    array();
  122.     private $_aphonixCode     array();
  123.     private $_transliteration array();
  124.     private $_map             array();
  125.     
  126.     private $_len  4;
  127.     private $_lang 'en';
  128.     private $_code 'soundex';
  129.  
  130.     /**
  131.      * Loads initialize values
  132.      *
  133.      * @ignore
  134.      */         
  135.     public function __construct()
  136.     {
  137.         $xml simplexml_load_file(dirname(__FILE__).'/data/ArSoundex.xml');
  138.         
  139.         foreach ($xml->asoundexCode->item as $item{
  140.             $index $item['id'];
  141.             $value = (string) $item;
  142.             $this->_asoundexCode["$value"$index;
  143.         
  144.  
  145.         foreach ($xml->aphonixCode->item as $item{
  146.             $index $item['id'];
  147.             $value = (string) $item;
  148.             $this->_aphonixCode["$value"$index;
  149.         
  150.         
  151.         foreach ($xml->transliteration->item as $item{
  152.             $index $item['id'];
  153.             $this->_transliteration["$index"= (string)$item;
  154.         
  155.  
  156.         $this->_map $this->_asoundexCode;
  157.     }
  158.     
  159.     /**
  160.      * Set the length of soundex key (default value is 4)
  161.      *      
  162.      * @param integer $integer Soundex key length
  163.      *      
  164.      * @return object $this to build a fluent interface
  165.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  166.      */
  167.     public function setLen($integer)
  168.     {
  169.         $this->_len = (int)$integer;
  170.         
  171.         return $this;
  172.     }
  173.     
  174.     /**
  175.      * Set the language of the soundex key (default value is "en")
  176.      *      
  177.      * @param string $str Soundex key language [ar|en]
  178.      *      
  179.      * @return object $this to build a fluent interface
  180.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  181.      */
  182.     public function setLang($str)
  183.     {
  184.         $str strtolower($str);
  185.         
  186.         if ($str == 'ar' || $str == 'en'{
  187.             $this->_lang $str;
  188.         }
  189.         
  190.         return $this;
  191.     }
  192.     
  193.     /**
  194.      * Set the mapping code of the soundex key (default value is "soundex")
  195.      *      
  196.      * @param string $str Soundex key mapping code [soundex|phonix]
  197.      *      
  198.      * @return object $this to build a fluent interface
  199.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  200.      */
  201.     public function setCode($str)
  202.     {
  203.         $str strtolower($str);
  204.         
  205.         if ($str == 'soundex' || $str == 'phonix'{
  206.             $this->_code $str;
  207.             if ($str == 'phonix'{
  208.                 $this->_map $this->_aphonixCode;
  209.             else {
  210.                 $this->_map $this->_asoundexCode;
  211.             }
  212.         }
  213.         
  214.         return $this;
  215.     }
  216.     
  217.     /**
  218.      * Get the soundex key length used now
  219.      *      
  220.      * @return integer return current setting for soundex key length
  221.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  222.      */
  223.     public function getLen()
  224.     {
  225.         return $this->_len;
  226.     }
  227.     
  228.     /**
  229.      * Get the soundex key language used now
  230.      *      
  231.      * @return string return current setting for soundex key language
  232.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  233.      */
  234.     public function getLang()
  235.     {
  236.         return $this->_lang;
  237.     }
  238.     
  239.     /**
  240.      * Get the soundex key calculation method used now
  241.      *      
  242.      * @return string return current setting for soundex key calculation method
  243.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  244.      */
  245.     public function getCode()
  246.     {
  247.         return $this->_code;
  248.     }
  249.     
  250.     /**
  251.      * Methode to get soundex/phonix numric code for given word
  252.      *      
  253.      * @param string $word The word that we want to encode it
  254.      *      
  255.      * @return string The calculated soundex/phonix numeric code
  256.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  257.      */
  258.     protected function mapCode($word)
  259.     {
  260.         $encodedWord '';
  261.         
  262.         $max   mb_strlen($word'UTF-8');
  263.         
  264.         for ($i=0$i $max$i++{
  265.             $char mb_substr($word$i1'UTF-8');
  266.             if (isset($this->_map["$char"])) {
  267.                 $encodedWord .= $this->_map["$char"];
  268.             else {
  269.                 $encodedWord .= '0';
  270.             }
  271.         }
  272.         
  273.         return $encodedWord;
  274.     }
  275.     
  276.     /**
  277.      * Remove any characters replicates
  278.      *      
  279.      * @param string $word Arabic word you want to check if it is feminine
  280.      *      
  281.      * @return string Same word without any duplicate chracters
  282.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  283.      */
  284.     protected function trimRep($word)
  285.     {
  286.         $lastChar  null;
  287.         $cleanWord null;
  288.         $max       mb_strlen($word'UTF-8');
  289.         
  290.         for ($i 0$i $max$i++{
  291.             $char mb_substr($word$i1'UTF-8');
  292.             if ($char != $lastChar{
  293.                 $cleanWord .= $char;
  294.             }
  295.             $lastChar $char;
  296.         }
  297.         
  298.         return $cleanWord;
  299.     }
  300.     
  301.     /**
  302.      * Arabic soundex algorithm takes Arabic word as an input and produces a
  303.      * character string which identifies a set words that are (roughly)
  304.      * phonetically alike.
  305.      *      
  306.      * @param string $word Arabic word you want to calculate its soundex
  307.      *                    
  308.      * @return string Soundex value for a given Arabic word
  309.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  310.      */
  311.     public function soundex($word)
  312.     {
  313.         $soundex mb_substr($word01'UTF-8');
  314.         $rest    mb_substr($word1mb_strlen($word'UTF-8')'UTF-8');
  315.         
  316.         if ($this->_lang == 'en'{
  317.             $soundex $this->_transliteration[$soundex];
  318.         }
  319.         
  320.         $encodedRest      $this->mapCode($rest);
  321.         $cleanEncodedRest $this->trimRep($encodedRest);
  322.         
  323.         $soundex .= $cleanEncodedRest;
  324.         
  325.         $soundex str_replace('0'''$soundex);
  326.         
  327.         $totalLen mb_strlen($soundex'UTF-8');
  328.         if ($totalLen $this->_len{
  329.             $soundex mb_substr($soundex0$this->_len'UTF-8');
  330.         else {
  331.             $soundex .= str_repeat('0'$this->_len $totalLen);
  332.         }
  333.         
  334.         return $soundex;
  335.     }
  336. }

Documentation generated on Mon, 14 Jan 2013 17:49:06 +0100 by phpDocumentor 1.4.0