blob: 544211baab2cc7393461af90eb84a8f52ffdd7be [file] [log] [blame]
Jake Farrellb03a59c2011-11-29 16:45:51 +00001<?php
2
Roger Thomas6fb59232014-11-04 10:09:23 +00003interface TStringFunc
4{
Jake Farrellb03a59c2011-11-29 16:45:51 +00005 public function substr($str, $start, $length = null);
6 public function strlen($str);
7}
8
9class TStringFunc_Core
10implements TStringFunc {
Roger Thomas6fb59232014-11-04 10:09:23 +000011 public function substr($str, $start, $length = null)
12 {
Jake Farrellb03a59c2011-11-29 16:45:51 +000013 // specifying a null $length would return an empty string
Roger Thomas6fb59232014-11-04 10:09:23 +000014 if ($length === null) {
Pavel Kvach82383642024-01-14 15:53:17 +020015 return substr((string) $str, $start);
Jake Farrellb03a59c2011-11-29 16:45:51 +000016 }
Roger Thomas6fb59232014-11-04 10:09:23 +000017
Pavel Kvach82383642024-01-14 15:53:17 +020018 return substr((string) $str, $start, $length);
Jake Farrellb03a59c2011-11-29 16:45:51 +000019 }
20
Roger Thomas6fb59232014-11-04 10:09:23 +000021 public function strlen($str)
22 {
Pavel Kvach82383642024-01-14 15:53:17 +020023 return strlen((string) $str);
Jake Farrellb03a59c2011-11-29 16:45:51 +000024 }
25}
26
27class TStringFunc_Mbstring
28implements TStringFunc {
Roger Thomas6fb59232014-11-04 10:09:23 +000029 public function substr($str, $start, $length = null)
30 {
Jake Farrellb03a59c2011-11-29 16:45:51 +000031 /**
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 Thomas6fb59232014-11-04 10:09:23 +000038 if ($length === null) {
Jake Farrellb03a59c2011-11-29 16:45:51 +000039 $length = $this->strlen($str) - $start;
40 }
41
Pavel Kvach82383642024-01-14 15:53:17 +020042 return mb_substr((string) $str, $start, $length, '8bit');
Jake Farrellb03a59c2011-11-29 16:45:51 +000043 }
44
Roger Thomas6fb59232014-11-04 10:09:23 +000045 public function strlen($str)
46 {
Pavel Kvach82383642024-01-14 15:53:17 +020047 return mb_strlen((string) $str, '8bit');
Jake Farrellb03a59c2011-11-29 16:45:51 +000048 }
49}
50
Roger Thomas6fb59232014-11-04 10:09:23 +000051class TStringFuncFactory
52{
Jake Farrellb03a59c2011-11-29 16:45:51 +000053 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 Thomas6fb59232014-11-04 10:09:23 +000061 public static function create()
62 {
63 if (!self::$_instance) {
Jake Farrellb03a59c2011-11-29 16:45:51 +000064 self::_setInstance();
65 }
66
67 return self::$_instance;
68 }
69
Roger Thomas6fb59232014-11-04 10:09:23 +000070 private static function _setInstance()
71 {
Jake Farrellb03a59c2011-11-29 16:45:51 +000072 /**
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 Thomas6fb59232014-11-04 10:09:23 +000078 if (ini_get('mbstring.func_overload') & 2) {
Jake Farrellb03a59c2011-11-29 16:45:51 +000079 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}