I18N_Arabic

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

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