1<?php 2 3interface TStringFunc 4{ 5 public function substr($str, $start, $length = null); 6 public function strlen($str); 7} 8 9class TStringFunc_Core 10implements TStringFunc { 11 public function substr($str, $start, $length = null) 12 { 13 // specifying a null $length would return an empty string 14 if ($length === null) { 15 return substr($str, $start); 16 } 17 18 return substr($str, $start, $length); 19 } 20 21 public function strlen($str) 22 { 23 return strlen($str); 24 } 25} 26 27class TStringFunc_Mbstring 28implements TStringFunc { 29 public function substr($str, $start, $length = null) 30 { 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 */ 38 if ($length === null) { 39 $length = $this->strlen($str) - $start; 40 } 41 42 return mb_substr($str, $start, $length, '8bit'); 43 } 44 45 public function strlen($str) 46 { 47 return mb_strlen($str, '8bit'); 48 } 49} 50 51class TStringFuncFactory 52{ 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 */ 61 public static function create() 62 { 63 if (!self::$_instance) { 64 self::_setInstance(); 65 } 66 67 return self::$_instance; 68 } 69 70 private static function _setInstance() 71 { 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 */ 78 if (ini_get('mbstring.func_overload') & 2) { 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} 91