StringUtils.php 5.4 KB

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