Jake Farrell | b03a59c | 2011-11-29 16:45:51 +0000 | [diff] [blame] | 1 | <?php |
| 2 | |
| 3 | interface TStringFunc { |
| 4 | public function substr($str, $start, $length = null); |
| 5 | public function strlen($str); |
| 6 | } |
| 7 | |
| 8 | class TStringFunc_Core |
| 9 | implements TStringFunc { |
| 10 | public function substr($str, $start, $length = null) { |
| 11 | // specifying a null $length would return an empty string |
| 12 | if($length === null) { |
| 13 | return substr($str, $start); |
| 14 | } |
| 15 | return substr($str, $start, $length); |
| 16 | } |
| 17 | |
| 18 | public function strlen($str) { |
| 19 | return strlen($str); |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | class TStringFunc_Mbstring |
| 24 | implements TStringFunc { |
| 25 | public function substr($str, $start, $length = null) { |
| 26 | /** |
| 27 | * We need to set the charset parameter, which is the second |
| 28 | * optional parameter and the first optional parameter can't |
| 29 | * be null or false as a "magic" value because that would |
| 30 | * cause an empty string to be returned, so we need to |
| 31 | * actually calculate the proper length value. |
| 32 | */ |
| 33 | if($length === null) { |
| 34 | $length = $this->strlen($str) - $start; |
| 35 | } |
| 36 | |
| 37 | return mb_substr($str, $start, $length, '8bit'); |
| 38 | } |
| 39 | |
| 40 | public function strlen($str) { |
| 41 | return mb_strlen($str, '8bit'); |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | class TStringFuncFactory { |
| 46 | private static $_instance; |
| 47 | |
| 48 | /** |
| 49 | * Get the Singleton instance of TStringFunc implementation that is |
| 50 | * compatible with the current system's mbstring.func_overload settings. |
| 51 | * |
| 52 | * @return TStringFunc |
| 53 | */ |
| 54 | public static function create() { |
| 55 | if(!self::$_instance) { |
| 56 | self::_setInstance(); |
| 57 | } |
| 58 | |
| 59 | return self::$_instance; |
| 60 | } |
| 61 | |
| 62 | private static function _setInstance() { |
| 63 | /** |
| 64 | * Cannot use str* functions for byte counting because multibyte |
| 65 | * characters will be read a single bytes. |
| 66 | * |
| 67 | * See: http://us.php.net/manual/en/mbstring.overload.php |
| 68 | */ |
| 69 | if(ini_get('mbstring.func_overload') & 2) { |
| 70 | self::$_instance = new TStringFunc_Mbstring(); |
| 71 | } |
| 72 | /** |
| 73 | * mbstring is not installed or does not have function overloading |
| 74 | * of the str* functions enabled so use PHP core str* functions for |
| 75 | * byte counting. |
| 76 | */ |
| 77 | else { |
| 78 | self::$_instance = new TStringFunc_Core(); |
| 79 | } |
| 80 | } |
| 81 | } |