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