Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@0
|
3 * Zend Framework (http://framework.zend.com/)
|
Chris@0
|
4 *
|
Chris@0
|
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
|
Chris@0
|
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
Chris@0
|
7 * @license http://framework.zend.com/license/new-bsd New BSD License
|
Chris@0
|
8 */
|
Chris@0
|
9
|
Chris@0
|
10 namespace Zend\Stdlib;
|
Chris@0
|
11
|
Chris@0
|
12 use Zend\Stdlib\StringWrapper\StringWrapperInterface;
|
Chris@0
|
13
|
Chris@0
|
14 /**
|
Chris@0
|
15 * Utility class for handling strings of different character encodings
|
Chris@0
|
16 * using available PHP extensions.
|
Chris@0
|
17 *
|
Chris@0
|
18 * Declared abstract, as we have no need for instantiation.
|
Chris@0
|
19 */
|
Chris@0
|
20 abstract class StringUtils
|
Chris@0
|
21 {
|
Chris@0
|
22 /**
|
Chris@0
|
23 * Ordered list of registered string wrapper instances
|
Chris@0
|
24 *
|
Chris@0
|
25 * @var StringWrapperInterface[]
|
Chris@0
|
26 */
|
Chris@0
|
27 protected static $wrapperRegistry = null;
|
Chris@0
|
28
|
Chris@0
|
29 /**
|
Chris@0
|
30 * A list of known single-byte character encodings (upper-case)
|
Chris@0
|
31 *
|
Chris@0
|
32 * @var string[]
|
Chris@0
|
33 */
|
Chris@0
|
34 protected static $singleByteEncodings = [
|
Chris@0
|
35 'ASCII', '7BIT', '8BIT',
|
Chris@0
|
36 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5',
|
Chris@0
|
37 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10',
|
Chris@0
|
38 'ISO-8859-11', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
|
Chris@0
|
39 'CP-1251', 'CP-1252',
|
Chris@0
|
40 // TODO
|
Chris@0
|
41 ];
|
Chris@0
|
42
|
Chris@0
|
43 /**
|
Chris@0
|
44 * Is PCRE compiled with Unicode support?
|
Chris@0
|
45 *
|
Chris@0
|
46 * @var bool
|
Chris@0
|
47 **/
|
Chris@0
|
48 protected static $hasPcreUnicodeSupport = null;
|
Chris@0
|
49
|
Chris@0
|
50 /**
|
Chris@0
|
51 * Get registered wrapper classes
|
Chris@0
|
52 *
|
Chris@0
|
53 * @return string[]
|
Chris@0
|
54 */
|
Chris@0
|
55 public static function getRegisteredWrappers()
|
Chris@0
|
56 {
|
Chris@0
|
57 if (static::$wrapperRegistry === null) {
|
Chris@0
|
58 static::$wrapperRegistry = [];
|
Chris@0
|
59
|
Chris@0
|
60 if (extension_loaded('intl')) {
|
Chris@0
|
61 static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\Intl';
|
Chris@0
|
62 }
|
Chris@0
|
63
|
Chris@0
|
64 if (extension_loaded('mbstring')) {
|
Chris@0
|
65 static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\MbString';
|
Chris@0
|
66 }
|
Chris@0
|
67
|
Chris@0
|
68 if (extension_loaded('iconv')) {
|
Chris@0
|
69 static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\Iconv';
|
Chris@0
|
70 }
|
Chris@0
|
71
|
Chris@0
|
72 static::$wrapperRegistry[] = 'Zend\Stdlib\StringWrapper\Native';
|
Chris@0
|
73 }
|
Chris@0
|
74
|
Chris@0
|
75 return static::$wrapperRegistry;
|
Chris@0
|
76 }
|
Chris@0
|
77
|
Chris@0
|
78 /**
|
Chris@0
|
79 * Register a string wrapper class
|
Chris@0
|
80 *
|
Chris@0
|
81 * @param string $wrapper
|
Chris@0
|
82 * @return void
|
Chris@0
|
83 */
|
Chris@0
|
84 public static function registerWrapper($wrapper)
|
Chris@0
|
85 {
|
Chris@0
|
86 $wrapper = (string) $wrapper;
|
Chris@12
|
87 if (! in_array($wrapper, static::$wrapperRegistry, true)) {
|
Chris@0
|
88 static::$wrapperRegistry[] = $wrapper;
|
Chris@0
|
89 }
|
Chris@0
|
90 }
|
Chris@0
|
91
|
Chris@0
|
92 /**
|
Chris@0
|
93 * Unregister a string wrapper class
|
Chris@0
|
94 *
|
Chris@0
|
95 * @param string $wrapper
|
Chris@0
|
96 * @return void
|
Chris@0
|
97 */
|
Chris@0
|
98 public static function unregisterWrapper($wrapper)
|
Chris@0
|
99 {
|
Chris@0
|
100 $index = array_search((string) $wrapper, static::$wrapperRegistry, true);
|
Chris@0
|
101 if ($index !== false) {
|
Chris@0
|
102 unset(static::$wrapperRegistry[$index]);
|
Chris@0
|
103 }
|
Chris@0
|
104 }
|
Chris@0
|
105
|
Chris@0
|
106 /**
|
Chris@0
|
107 * Reset all registered wrappers so the default wrappers will be used
|
Chris@0
|
108 *
|
Chris@0
|
109 * @return void
|
Chris@0
|
110 */
|
Chris@0
|
111 public static function resetRegisteredWrappers()
|
Chris@0
|
112 {
|
Chris@0
|
113 static::$wrapperRegistry = null;
|
Chris@0
|
114 }
|
Chris@0
|
115
|
Chris@0
|
116 /**
|
Chris@0
|
117 * Get the first string wrapper supporting the given character encoding
|
Chris@0
|
118 * and supports to convert into the given convert encoding.
|
Chris@0
|
119 *
|
Chris@0
|
120 * @param string $encoding Character encoding to support
|
Chris@0
|
121 * @param string|null $convertEncoding OPTIONAL character encoding to convert in
|
Chris@0
|
122 * @return StringWrapperInterface
|
Chris@0
|
123 * @throws Exception\RuntimeException If no wrapper supports given character encodings
|
Chris@0
|
124 */
|
Chris@0
|
125 public static function getWrapper($encoding = 'UTF-8', $convertEncoding = null)
|
Chris@0
|
126 {
|
Chris@0
|
127 foreach (static::getRegisteredWrappers() as $wrapperClass) {
|
Chris@0
|
128 if ($wrapperClass::isSupported($encoding, $convertEncoding)) {
|
Chris@0
|
129 $wrapper = new $wrapperClass($encoding, $convertEncoding);
|
Chris@0
|
130 $wrapper->setEncoding($encoding, $convertEncoding);
|
Chris@0
|
131 return $wrapper;
|
Chris@0
|
132 }
|
Chris@0
|
133 }
|
Chris@0
|
134
|
Chris@0
|
135 throw new Exception\RuntimeException(
|
Chris@0
|
136 'No wrapper found supporting "' . $encoding . '"'
|
Chris@0
|
137 . (($convertEncoding !== null) ? ' and "' . $convertEncoding . '"' : '')
|
Chris@0
|
138 );
|
Chris@0
|
139 }
|
Chris@0
|
140
|
Chris@0
|
141 /**
|
Chris@0
|
142 * Get a list of all known single-byte character encodings
|
Chris@0
|
143 *
|
Chris@0
|
144 * @return string[]
|
Chris@0
|
145 */
|
Chris@0
|
146 public static function getSingleByteEncodings()
|
Chris@0
|
147 {
|
Chris@0
|
148 return static::$singleByteEncodings;
|
Chris@0
|
149 }
|
Chris@0
|
150
|
Chris@0
|
151 /**
|
Chris@0
|
152 * Check if a given encoding is a known single-byte character encoding
|
Chris@0
|
153 *
|
Chris@0
|
154 * @param string $encoding
|
Chris@0
|
155 * @return bool
|
Chris@0
|
156 */
|
Chris@0
|
157 public static function isSingleByteEncoding($encoding)
|
Chris@0
|
158 {
|
Chris@0
|
159 return in_array(strtoupper($encoding), static::$singleByteEncodings);
|
Chris@0
|
160 }
|
Chris@0
|
161
|
Chris@0
|
162 /**
|
Chris@0
|
163 * Check if a given string is valid UTF-8 encoded
|
Chris@0
|
164 *
|
Chris@0
|
165 * @param string $str
|
Chris@0
|
166 * @return bool
|
Chris@0
|
167 */
|
Chris@0
|
168 public static function isValidUtf8($str)
|
Chris@0
|
169 {
|
Chris@0
|
170 return is_string($str) && ($str === '' || preg_match('/^./su', $str) == 1);
|
Chris@0
|
171 }
|
Chris@0
|
172
|
Chris@0
|
173 /**
|
Chris@0
|
174 * Is PCRE compiled with Unicode support?
|
Chris@0
|
175 *
|
Chris@0
|
176 * @return bool
|
Chris@0
|
177 */
|
Chris@0
|
178 public static function hasPcreUnicodeSupport()
|
Chris@0
|
179 {
|
Chris@0
|
180 if (static::$hasPcreUnicodeSupport === null) {
|
Chris@0
|
181 ErrorHandler::start();
|
Chris@0
|
182 static::$hasPcreUnicodeSupport = defined('PREG_BAD_UTF8_OFFSET_ERROR') && preg_match('/\pL/u', 'a') == 1;
|
Chris@0
|
183 ErrorHandler::stop();
|
Chris@0
|
184 }
|
Chris@0
|
185 return static::$hasPcreUnicodeSupport;
|
Chris@0
|
186 }
|
Chris@0
|
187 }
|