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-2016 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-2016 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. /**
  99.  * This PHP class implement Arabic soundex algorithm
  100.  *  
  101.  * @category  I18N
  102.  * @package   I18N_Arabic
  103.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  104.  * @copyright 2006-2016 Khaled Al-Sham'aa
  105.  *    
  106.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  107.  * @link      http://www.ar-php.org
  108.  */ 
  109. {
  110.     private $_asoundexCode    array();
  111.     private $_aphonixCode     array();
  112.     private $_transliteration array();
  113.     private $_map             array();
  114.     
  115.     private $_len  4;
  116.     private $_lang 'en';
  117.     private $_code 'soundex';
  118.  
  119.     /**
  120.      * Loads initialize values
  121.      *
  122.      * @ignore
  123.      */         
  124.     public function __construct()
  125.     {
  126.         $xml simplexml_load_file(dirname(__FILE__).'/data/ArSoundex.xml');
  127.         
  128.         foreach ($xml->asoundexCode->item as $item{
  129.             $index $item['id'];
  130.             $value = (string) $item;
  131.             $this->_asoundexCode["$value"$index;
  132.         
  133.  
  134.         foreach ($xml->aphonixCode->item as $item{
  135.             $index $item['id'];
  136.             $value = (string) $item;
  137.             $this->_aphonixCode["$value"$index;
  138.         
  139.         
  140.         foreach ($xml->transliteration->item as $item{
  141.             $index $item['id'];
  142.             $this->_transliteration["$index"= (string)$item;
  143.         
  144.  
  145.         $this->_map $this->_asoundexCode;
  146.     }
  147.     
  148.     /**
  149.      * Set the length of soundex key (default value is 4)
  150.      *      
  151.      * @param integer $integer Soundex key length
  152.      *      
  153.      * @return object $this to build a fluent interface
  154.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  155.      */
  156.     public function setLen($integer)
  157.     {
  158.         $this->_len = (int)$integer;
  159.         
  160.         return $this;
  161.     }
  162.     
  163.     /**
  164.      * Set the language of the soundex key (default value is "en")
  165.      *      
  166.      * @param string $str Soundex key language [ar|en]
  167.      *      
  168.      * @return object $this to build a fluent interface
  169.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  170.      */
  171.     public function setLang($str)
  172.     {
  173.         $str strtolower($str);
  174.         
  175.         if ($str == 'ar' || $str == 'en'{
  176.             $this->_lang $str;
  177.         }
  178.         
  179.         return $this;
  180.     }
  181.     
  182.     /**
  183.      * Set the mapping code of the soundex key (default value is "soundex")
  184.      *      
  185.      * @param string $str Soundex key mapping code [soundex|phonix]
  186.      *      
  187.      * @return object $this to build a fluent interface
  188.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  189.      */
  190.     public function setCode($str)
  191.     {
  192.         $str strtolower($str);
  193.         
  194.         if ($str == 'soundex' || $str == 'phonix'{
  195.             $this->_code $str;
  196.             if ($str == 'phonix'{
  197.                 $this->_map $this->_aphonixCode;
  198.             else {
  199.                 $this->_map $this->_asoundexCode;
  200.             }
  201.         }
  202.         
  203.         return $this;
  204.     }
  205.     
  206.     /**
  207.      * Get the soundex key length used now
  208.      *      
  209.      * @return integer return current setting for soundex key length
  210.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  211.      */
  212.     public function getLen()
  213.     {
  214.         return $this->_len;
  215.     }
  216.     
  217.     /**
  218.      * Get the soundex key language used now
  219.      *      
  220.      * @return string return current setting for soundex key language
  221.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  222.      */
  223.     public function getLang()
  224.     {
  225.         return $this->_lang;
  226.     }
  227.     
  228.     /**
  229.      * Get the soundex key calculation method used now
  230.      *      
  231.      * @return string return current setting for soundex key calculation method
  232.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  233.      */
  234.     public function getCode()
  235.     {
  236.         return $this->_code;
  237.     }
  238.     
  239.     /**
  240.      * Methode to get soundex/phonix numric code for given word
  241.      *      
  242.      * @param string $word The word that we want to encode it
  243.      *      
  244.      * @return string The calculated soundex/phonix numeric code
  245.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  246.      */
  247.     protected function mapCode($word)
  248.     {
  249.         $encodedWord '';
  250.         
  251.         $max   mb_strlen($word'UTF-8');
  252.         
  253.         for ($i=0$i $max$i++{
  254.             $char mb_substr($word$i1'UTF-8');
  255.             if (isset($this->_map["$char"])) {
  256.                 $encodedWord .= $this->_map["$char"];
  257.             else {
  258.                 $encodedWord .= '0';
  259.             }
  260.         }
  261.         
  262.         return $encodedWord;
  263.     }
  264.     
  265.     /**
  266.      * Remove any characters replicates
  267.      *      
  268.      * @param string $word Arabic word you want to check if it is feminine
  269.      *      
  270.      * @return string Same word without any duplicate chracters
  271.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  272.      */
  273.     protected function trimRep($word)
  274.     {
  275.         $lastChar  null;
  276.         $cleanWord null;
  277.         $max       mb_strlen($word'UTF-8');
  278.         
  279.         for ($i 0$i $max$i++{
  280.             $char mb_substr($word$i1'UTF-8');
  281.             if ($char != $lastChar{
  282.                 $cleanWord .= $char;
  283.             }
  284.             $lastChar $char;
  285.         }
  286.         
  287.         return $cleanWord;
  288.     }
  289.     
  290.     /**
  291.      * Arabic soundex algorithm takes Arabic word as an input and produces a
  292.      * character string which identifies a set words that are (roughly)
  293.      * phonetically alike.
  294.      *      
  295.      * @param string $word Arabic word you want to calculate its soundex
  296.      *                    
  297.      * @return string Soundex value for a given Arabic word
  298.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  299.      */
  300.     public function soundex($word)
  301.     {
  302.         $soundex mb_substr($word01'UTF-8');
  303.         $rest    mb_substr($word1mb_strlen($word'UTF-8')'UTF-8');
  304.         
  305.         if ($this->_lang == 'en'{
  306.             $soundex $this->_transliteration[$soundex];
  307.         }
  308.         
  309.         $encodedRest      $this->mapCode($rest);
  310.         $cleanEncodedRest $this->trimRep($encodedRest);
  311.         
  312.         $soundex .= $cleanEncodedRest;
  313.         
  314.         $soundex str_replace('0'''$soundex);
  315.         
  316.         $totalLen mb_strlen($soundex'UTF-8');
  317.         if ($totalLen $this->_len{
  318.             $soundex mb_substr($soundex0$this->_len'UTF-8');
  319.         else {
  320.             $soundex .= str_repeat('0'$this->_len $totalLen);
  321.         }
  322.         
  323.         return $soundex;
  324.     }
  325. }

Documentation generated on Fri, 01 Jan 2016 10:26:24 +0200 by phpDocumentor 1.4.0