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

Source for file I18N_UnicodeString.php

Documentation is available at I18N_UnicodeString.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. /**
  4. * Provides a method of storing and manipulating multibyte strings in PHP.
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * LICENSE: Copyright 2004 John Downey. All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * o Redistributions of source code must retain the above copyright notice, this
  14. *   list of conditions and the following disclaimer.
  15. * o Redistributions in binary form must reproduce the above copyright notice,
  16. *   this list of conditions and the following disclaimer in the documentation
  17. *   and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT "AS IS" AND ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22. * EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  26. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  27. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  28. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. * The views and conclusions contained in the software and documentation are
  31. * those of the authors and should not be interpreted as representing official
  32. * policies, either expressed or implied, of The PEAR Group.
  33. *
  34. @category  Internationalization
  35. @package   I18N_UnicodeString
  36. @author    John Downey <jdowney@gmail.com>
  37. @copyright 2004-2006 John Downey
  38. @license   http://www.freebsd.org/copyright/freebsd-license.html 2 Clause BSD License
  39. @version   CVS: $Id$
  40. @filesource
  41. */
  42.  
  43. /**
  44. * Class provides a way to use and manipulate multibyte strings in PHP
  45. *
  46. @package I18N_UnicodeString
  47. @author  John Downey <jdowney@gmail.com>
  48. @access  public
  49. @version Release: @package_version@
  50. */
  51. {
  52.     /**
  53.     * The internal representation of the string as an array of numbers.
  54.     * @access private
  55.     * @var    array $_unicode 
  56.     */
  57.     var $_unicode = array();
  58.     
  59.     /**
  60.     * Converts an entire array of strings to Unicode capable strings.
  61.     *
  62.     * Useful for converting a GET/POST of all its Unicode values into a
  63.     * workable and easily changed format. Takes an optional second
  64.     * parameter similer to that of {@link setString()}.
  65.     *
  66.     * @access public
  67.     * @static
  68.     * @param  array $array An array of PHP variables.
  69.     * @param  string $encoding The encoding the string values are in.
  70.     * @return array The array with all of its string values converted to
  71.     *                I18N_Unicode objects.
  72.     * @see    setString()
  73.     */
  74.     function convertArray($array$encoding 'HTML'{
  75.         foreach($array as $key => $value{
  76.             if (is_string($value)) {
  77.                 $array[$key= new I18N_Unicode($value$encoding);
  78.             }
  79.         }
  80.         
  81.         return $array;
  82.     }
  83.     
  84.     /**
  85.     * The constructor of the class string which can receive a new string in a
  86.     * number of formats.
  87.     *
  88.     * @access public
  89.     * @param  mixed $value A variable containing the Unicode string in one of
  90.     *                       various encodings.
  91.     * @param  string $encoding The encoding that the string is in.
  92.     * @see    setString()
  93.     */
  94.     function I18N_UnicodeString($value ''$encoding 'UTF-8'{
  95.         $this->setString($value$encoding);
  96.     }
  97.     
  98.     /**
  99.     * Set the string to a value passed in one of many encodings.
  100.     *
  101.     * You may pass the encoding as an optional second parameter which defaults
  102.     * to UTF-8 encoding. Possible encodings are:
  103.     * 
  104.     * o <i>ASCII</i> - when you pass a normal 7 bit ASCII string
  105.     * o <i>UTF-8</i> - when you pass a UTF-8 encoded string
  106.     * o <i>HTML</i> - when you pass a string encoded with HTML entities, such
  107.     *   as the kind received from a GET/POST
  108.     * o <i>Unicode</i> or <i>UCS-4</i> - when passing an array of integer values representing
  109.     *   each character
  110.     *
  111.     * @access public
  112.     * @param  mixed $value A variable containing the Unicode string in one of
  113.     *                       various encodings.
  114.     * @param  string $encoding The encoding that the string is in.
  115.     * @return mixed Returns true on success or PEAR_Error otherwise.
  116.     */
  117.     function setString($value$encoding 'UTF-8'{
  118.            switch(strtoupper($encoding)) {
  119.             case 'ASCII':
  120.             case 'UTF8':
  121.             case 'UTF-8':
  122.                 $this->_unicode = self::utf8ToUnicode($value);
  123.                 break;
  124.  
  125.             case 'HTML':
  126.                 $this->_unicode $this->_stringFromHtml($value);
  127.                 break;
  128.  
  129.             case 'UTF32':
  130.             case 'UTF-32':
  131.             case 'UCS4':
  132.             case 'UCS-4':
  133.             case 'UNICODE':
  134.                 $this->_unicode $value;
  135.                 break;
  136.  
  137.             default:
  138.                 return self::raiseError('Unrecognized encoding');
  139.         }
  140.         
  141.         if (strtolower(get_class($this->_unicode)) == 'pear_error'{
  142.             return $this->_unicode;
  143.         }
  144.         
  145.         return true;
  146.     }
  147.     
  148.     /**
  149.     * Converts a string encoded with HTML entities into our internal
  150.     * representation of an array of integers.
  151.     *
  152.     * @access private
  153.     * @param  string $string A string containing Unicode values encoded as HTML
  154.     *                         entities.
  155.     * @return array The array of Unicode values.
  156.     */
  157.     function _stringFromHtml($string ''{
  158.         $parts   explode('&#'$string);
  159.         $unicode = array();
  160.         foreach($parts as $part{
  161.             $text strstr($part';');
  162.             
  163.             if (!empty($text)) {
  164.                 $value substr($part0strpos($part';'));
  165.  
  166.                 /* Suggested by Jonathan Yavner to allow HTML to also be in
  167.                    the form of &#xNNNN where NNNN is the hexidecimal of a
  168.                    Unicode character */
  169.                 if (ord($value[0]== 120{
  170.                     $unicode[intval(substr($value1)16);
  171.                 else {
  172.                     $unicode[intval($value);
  173.                 }
  174.  
  175.                 $text substr($text1);
  176.  
  177.                 for($i = 0$max strlen($text)$i $max$i++{
  178.                     $unicode[ord($text[$i]);
  179.                 }
  180.             else {
  181.                 for($i = 0$max strlen($part)$i $max$i++{
  182.                     $unicode[ord($part[$i]);
  183.                 }
  184.             }
  185.         }
  186.  
  187.         return $unicode;
  188.     }
  189.     
  190.     /**
  191.     * Converts a UTF-8 string into our representation of an array of integers.
  192.     *
  193.     * Method was made static by suggestion of Lukas Feiler (#7429)
  194.     *
  195.     * @static
  196.     * @access public
  197.     * @param  string $string A string containing Unicode values encoded in UTF-8
  198.     * @return array The array of Unicode values.
  199.     */
  200.     function utf8ToUnicode($string ''{
  201.         $unicode = array();
  202.         $values  = array();
  203.         $search  = 1;
  204.         
  205.         for($count = 0$length strlen($string)$count $length$count++{
  206.             $value ord($string[$count]);
  207.  
  208.             if ($value < 128{
  209.                 // if the value is an ASCII char then just go ahead and add it on
  210.                 $unicode[$value;
  211.             else {
  212.                 // if not then we need to know how many more bytes make up this character
  213.                 if (count($values== 0{
  214.                     if ($value >> 5 == 6{
  215.                         $values[($value - 192<< 6;
  216.                         $search   = 2;
  217.                     elseif ($value >> 4 == 14{
  218.                         $values[($value - 224<< 12;
  219.                         $search   = 3;
  220.                     elseif ($value >> 3 == 30{
  221.                         $values[($value - 240<< 18;
  222.                         $search   = 4;
  223.                     elseif ($value >> 2 == 62{
  224.                         $values[($value - 248<< 24;
  225.                         $search   = 5;
  226.                     elseif ($value >> 1 == 126{
  227.                         $values[($value - 252<< 30;
  228.                         $search   = 6;
  229.                     else {
  230.                         return self::raiseError('Malformed UTF-8 string');
  231.                     }
  232.                 else {
  233.                     if ($value >> 6 == 2{
  234.                         $values[$value - 128;
  235.                     else {
  236.                         return self::raiseError('Malformed UTF-8 string');
  237.                     }
  238.  
  239.                     if (count($values== $search{
  240.                         // if we have all of our bytes then go ahead an encode it in unicode
  241.                         $value $values[0];
  242.                         for($i = 1; $i $search$i++{
  243.                             $value += ($values[$i<< ((($search $i- 1* 6));
  244.                         }
  245.                         
  246.                         $unicode[$value;
  247.  
  248.                         $values = array();
  249.                         $search = 1;
  250.                     }
  251.                 }
  252.             }
  253.         }
  254.         
  255.         return $unicode;
  256.     }
  257.  
  258.     /**
  259.      * Transforms a single unicode character represented by an integer to a UTF-8 string.
  260.      *
  261.      * Suggested by Lukas Feiler (#7429)
  262.      *
  263.      * @static
  264.      * @access public
  265.      * @param  integer $int A unicode character as an integer
  266.      * @return string The unicode character converted to a UTF-8 string.
  267.      */
  268.     function unicodeCharToUtf8($char{
  269.         $string '';
  270.         if ($char < 128{
  271.             // its an ASCII char no encoding needed
  272.             $string .= chr($char);
  273.         elseif ($char < 1 << 11{
  274.             // its a 2 byte UTF-8 char
  275.             $string .= chr(192 + ($char >> 6));
  276.             $string .= chr(128 + ($char 63));
  277.         elseif ($char < 1 << 16{
  278.             // its a 3 byte UTF-8 char
  279.             $string .= chr(224 + ($char >> 12));
  280.             $string .= chr(128 + (($char >> 663));
  281.             $string .= chr(128 + ($char 63));
  282.         elseif ($char < 1 << 21{
  283.             // its a 4 byte UTF-8 char
  284.             $string .= chr(240 + ($char >> 18));
  285.             $string .= chr(128 + (($char >> 1263));
  286.             $string .= chr(128 + (($char >>  663));
  287.             $string .= chr(128 + ($char 63));
  288.         elseif ($char < 1 << 26{
  289.             // its a 5 byte UTF-8 char
  290.             $string .= chr(248 + ($char >> 24));
  291.             $string .= chr(128 + (($char >> 1863));
  292.             $string .= chr(128 + (($char >> 1263));
  293.             $string .= chr(128 + (($char >> 663));
  294.             $string .= chr(128 + ($char 63));
  295.         else {
  296.             // its a 6 byte UTF-8 char
  297.             $string .= chr(252 + ($char >> 30));
  298.             $string .= chr(128 + (($char >> 2463));
  299.             $string .= chr(128 + (($char >> 1863));
  300.             $string .= chr(128 + (($char >> 1263));
  301.             $string .= chr(128 + (($char >> 663));
  302.             $string .= chr(128 + ($char 63));
  303.         }
  304.  
  305.         return $string;
  306.     }
  307.     
  308.     /**
  309.     * Retrieves the string and returns it as a UTF-8 encoded string.
  310.     *
  311.     * @access public
  312.     * @return string A string with the Unicode values encoded in UTF-8.
  313.     */
  314.     function toUtf8String({
  315.         $string '';
  316.  
  317.         foreach($this->_unicode as $char{
  318.             $string .= $this->unicodeCharToUtf8($char);
  319.         }
  320.  
  321.         return $string;
  322.     }
  323.     
  324.     /**
  325.     * Retrieves the string and returns it as a string encoded with HTML
  326.     * entities.
  327.     *
  328.     * @access public
  329.     * @return string A string with the Unicode values encoded as HTML entities.
  330.     */
  331.     function toHtmlEntitiesString({
  332.         $string '';
  333.  
  334.         foreach($this->_unicode as $char{
  335.             if ($char > 127{
  336.                 $string .= '&#' $char ';';
  337.             else {
  338.                 $string .= chr($char);
  339.             }
  340.         }
  341.  
  342.         return $string;
  343.     }
  344.     
  345.     /**
  346.     * Retrieve the length of the string in characters.
  347.     *
  348.     * @access public
  349.     * @return integer The length of the string.
  350.     */
  351.     function length({
  352.         return count($this->_unicode);
  353.     }
  354.     
  355.     /**
  356.     * Works exactly like PHP's substr function only it works on Unicode
  357.     * strings.
  358.     *
  359.     * @access public
  360.     * @param  integer $begin The beginning of the substring.
  361.     * @param  integer $length The length to read. Defaults to the rest of the
  362.     *                          string.
  363.     * @return I18N_UnicodeString A new I18N_UnicodeString class containing the
  364.     *                             substring or a PEAR_Error if an error is
  365.     *                             thrown.
  366.     */
  367.     function subString($begin$length = null{
  368.         $unicode = array();
  369.         
  370.         if (is_null($length)) {
  371.             $length $this->length($begin;
  372.         }
  373.         
  374.         if (($begin $length$this->length()) {
  375.             return self::raiseError('Cannot read past end of string.');        
  376.         }
  377.         
  378.         if ($begin $this->length()) {
  379.             return self::raiseError('Beginning extends past end of string.');
  380.         }
  381.         
  382.         for($i $begin$max_length ($begin $length)$i $max_length$i++{
  383.             array_push($unicode$this->_unicode[$i]);
  384.         }
  385.  
  386.         return new I18N_UnicodeString($unicode'Unicode');
  387.     }
  388.     
  389.     /**
  390.     * Works like PHP's substr_replace function.
  391.     *
  392.     * @access public
  393.     * @param  I18N_UnicodeString $find The string to replaced
  394.     * @param  I18N_UnicodeString $replace The string to replace $find with
  395.     * @param  integer $start The position in the string to start replacing at
  396.     * @param  integer $length The length from the starting to position to stop
  397.     *                          replacing at
  398.     * @return I18N_UnicodeString The current string with all $find replaced by
  399.     *                             $replace
  400.     * @see    stringReplace()
  401.     */
  402.     function subStringReplace(&$find&$replace$start$length = null{
  403.         if (is_null($length)) {
  404.             $length $this->length($start;
  405.         }
  406.         
  407.         $begin  $this->subString(0$start);
  408.         $string $this->subString($start$length);
  409.         $string $string->stringReplace($find$replace);
  410.         $after  $this->subString($start $length);
  411.         
  412.         return new I18N_UnicodeString(array_merge($begin->_unicode$string->_unicode$after->_unicode)'Unicode');
  413.     }
  414.     
  415.     /**
  416.     * Works like PHP's str_replace function.
  417.     *
  418.     * @access public
  419.     * @param  I18N_UnicodeString $find The string to replaced
  420.     * @param  I18N_UnicodeString $replace The string to replace $find with
  421.     * @return I18N_UnicodeString The current string with all $find replaced by
  422.     *                             $replace
  423.     * @see    subStringReplace()
  424.     */
  425.     function stringReplace(&$find&$replace{
  426.         $return = new I18N_UnicodeString($this->_unicode'Unicode');
  427.         
  428.         while($return->strStr($find!== false{
  429.             $after $return->strStr($find);
  430.             $begin $return->subString(0$return->length($after->length());
  431.             $after $after->subString($find->length());
  432.             
  433.             $return = new I18N_UnicodeString(array_merge($begin->_unicode$replace->_unicode$after->_unicode)'Unicode');
  434.         }
  435.         
  436.         return $return;
  437.     }
  438.     
  439.     /**
  440.     * Works like PHP's strstr function by returning the string from $find on.
  441.     *
  442.     * @access public
  443.     * @param  I18N_UnicodeString $find The string to found
  444.     * @return I18N_UnicodeString The current string from $find on to the end
  445.     */
  446.     function strStr(&$find{
  447.         $found = false;
  448.         $after $find->_unicode;
  449.         
  450.         for($i = 0$length $this->length()$i $length$i++{
  451.             if ($found{
  452.                 $after[$this->_unicode[$i];
  453.             else {
  454.                 if ($this->_unicode[$i== $find->_unicode[0]{
  455.                     if ($i $find->length($length{
  456.                         break;
  457.                     }
  458.                     
  459.                     for($c = 1$max $find->length()$c $max$c++{
  460.                         $found = true;
  461.  
  462.                         if ($this->_unicode[++$i!= $find->_unicode[$c]{
  463.                             $found = false;
  464.                             break;
  465.                         }
  466.                     }
  467.                 }
  468.             }
  469.         }
  470.         
  471.         if ($found{
  472.             return new I18N_UnicodeString($after'Unicode');
  473.         else {
  474.             return false;
  475.         }
  476.     }
  477.  
  478.     /**
  479.     * Returns the position of a character much like PHP's strpos function.
  480.     *
  481.     * @access public
  482.     * @param  mixed $char A Unicode char represented as either an integer or a
  483.     *                      UTF-8 char.
  484.     * @return integer The location of the character in the string.
  485.     */
  486.     function indexOf($char{
  487.         if (!is_int($char)) {
  488.             if (strlen($char> 1{
  489.                 $char array_shift($this->utf8ToUnicode($char));
  490.             else {
  491.                 $char ord($char);
  492.             }
  493.         }
  494.         
  495.         for($i = 0$length $this->length()$i $length$i++{
  496.             if ($this->_unicode[$i== $char{
  497.                 return $i;
  498.             }
  499.         }
  500.         
  501.         return -1;
  502.     }
  503.     
  504.     /**
  505.     * Returns the last position of a character much like PHP's strrpos function.
  506.     *
  507.     * @access public
  508.     * @param  mixed $char A Unicode char represented as either an integer or a
  509.     *                      UTF-8 char.
  510.     * @return integer The last location of the character in the string.
  511.     */
  512.     function lastIndexOf($char{
  513.         if (!is_int($char)) {
  514.             if (strlen($char> 1{
  515.                 $char array_shift($this->utf8ToUnicode($char));
  516.             else {
  517.                 $char ord($char);
  518.             }
  519.         }
  520.         
  521.         for($i $this->length(- 1; $i >= 0; $i--{
  522.             if ($this->_unicode[$i== $char{
  523.                 return $i;
  524.             }
  525.         }
  526.         
  527.         return -1;    
  528.     }
  529.     
  530.     /**
  531.     * Determines if two Unicode strings are equal
  532.     *
  533.     * @access public
  534.     * @param  I18N_UnicodeString $unicode The string to compare to.
  535.     * @return boolean True if they are equal, false otherwise.
  536.     */
  537.     function equals(&$unicode{
  538.         if ($this->length(!= $unicode->length()) {
  539.             // if they arn't even the same length no need to even check
  540.             return false;
  541.         }
  542.         
  543.         return ($this->_unicode == $unicode->_unicode);
  544.     }
  545.     
  546.     /**
  547.     * Appends a given Unicode string to the end of the current one.
  548.     *
  549.     * @access public
  550.     * @param  I18N_UnicodeString $unicode The string to append.
  551.     * @return I18N_UnicodeString The new string created from the appension.
  552.     */
  553.     function append(&$unicode{
  554.         return new I18N_UnicodeString(array_merge($this->_unicode$unicode->_unicode)'Unicode');
  555.     }
  556.     
  557.     /**
  558.     * Used to raise a PEAR_Error.
  559.     *
  560.     * Hopefully this method is never called, but when it is it will include the
  561.     * PEAR class and return a new PEAR_Error.
  562.     *
  563.     * @static
  564.     * @access public
  565.     * @param string $message The error message to raise.
  566.     * @return PEAR_Error A PEAR error message.
  567.     */
  568.     function raiseError($message{
  569.         include_once('PEAR.php');
  570.     
  571.         return PEAR::raiseError($message);
  572.     }
  573. }
  574. ?>

Documentation generated on Mon, 11 Mar 2019 14:39:29 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.