Consistency.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. <?php
  2. /**
  3. * Hoa
  4. *
  5. *
  6. * @license
  7. *
  8. * New BSD License
  9. *
  10. * Copyright © 2007-2017, Hoa community. All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. * * Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * * Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * * Neither the name of the Hoa nor the names of its contributors may be
  20. * used to endorse or promote products derived from this software without
  21. * specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. namespace Hoa\Consistency
  36. {
  37. /**
  38. * Class Hoa\Consistency\Consistency.
  39. *
  40. * This class is a collection of tools to ensure foreward and backward
  41. * compatibility.
  42. *
  43. * @copyright Copyright © 2007-2017 Hoa community
  44. * @license New BSD License
  45. */
  46. class Consistency
  47. {
  48. /**
  49. * Check if an entity exists (class, interface, trait…).
  50. *
  51. * @param string $entityName Entity name.
  52. * @param bool $autoloader Run autoloader if necessary.
  53. * @return bool
  54. */
  55. public static function entityExists($entityName, $autoloader = false)
  56. {
  57. return
  58. class_exists($entityName, $autoloader) ||
  59. interface_exists($entityName, false) ||
  60. trait_exists($entityName, false);
  61. }
  62. /**
  63. * Get the shortest name for an entity.
  64. *
  65. * @param string $entityName Entity name.
  66. * @return string
  67. */
  68. public static function getEntityShortestName($entityName)
  69. {
  70. $parts = explode('\\', $entityName);
  71. $count = count($parts);
  72. if (1 >= $count) {
  73. return $entityName;
  74. }
  75. if ($parts[$count - 2] === $parts[$count - 1]) {
  76. return implode('\\', array_slice($parts, 0, -1));
  77. }
  78. return $entityName;
  79. }
  80. /**
  81. * Declare a flex entity (for nested library).
  82. *
  83. * @param string $entityName Entity name.
  84. * @return bool
  85. */
  86. public static function flexEntity($entityName)
  87. {
  88. return class_alias(
  89. $entityName,
  90. static::getEntityShortestName($entityName),
  91. false
  92. );
  93. }
  94. /**
  95. * Whether a word is reserved or not.
  96. *
  97. * @param string $word Word.
  98. * @return bool
  99. */
  100. public static function isKeyword($word)
  101. {
  102. static $_list = [
  103. // PHP keywords.
  104. '__halt_compiler',
  105. 'abstract',
  106. 'and',
  107. 'array',
  108. 'as',
  109. 'bool',
  110. 'break',
  111. 'callable',
  112. 'case',
  113. 'catch',
  114. 'class',
  115. 'clone',
  116. 'const',
  117. 'continue',
  118. 'declare',
  119. 'default',
  120. 'die',
  121. 'do',
  122. 'echo',
  123. 'else',
  124. 'elseif',
  125. 'empty',
  126. 'enddeclare',
  127. 'endfor',
  128. 'endforeach',
  129. 'endif',
  130. 'endswitch',
  131. 'endwhile',
  132. 'eval',
  133. 'exit',
  134. 'extends',
  135. 'false',
  136. 'final',
  137. 'float',
  138. 'for',
  139. 'foreach',
  140. 'function',
  141. 'global',
  142. 'goto',
  143. 'if',
  144. 'implements',
  145. 'include',
  146. 'include_once',
  147. 'instanceof',
  148. 'insteadof',
  149. 'int',
  150. 'interface',
  151. 'isset',
  152. 'list',
  153. 'mixed',
  154. 'namespace',
  155. 'new',
  156. 'null',
  157. 'numeric',
  158. 'object',
  159. 'or',
  160. 'print',
  161. 'private',
  162. 'protected',
  163. 'public',
  164. 'require',
  165. 'require_once',
  166. 'resource',
  167. 'return',
  168. 'static',
  169. 'string',
  170. 'switch',
  171. 'throw',
  172. 'trait',
  173. 'true',
  174. 'try',
  175. 'unset',
  176. 'use',
  177. 'var',
  178. 'void',
  179. 'while',
  180. 'xor',
  181. 'yield',
  182. // Compile-time constants.
  183. '__class__',
  184. '__dir__',
  185. '__file__',
  186. '__function__',
  187. '__line__',
  188. '__method__',
  189. '__namespace__',
  190. '__trait__'
  191. ];
  192. return in_array(strtolower($word), $_list);
  193. }
  194. /**
  195. * Whether an ID is a valid PHP identifier.
  196. *
  197. * @param string $id ID.
  198. * @return bool
  199. */
  200. public static function isIdentifier($id)
  201. {
  202. return 0 !== preg_match(
  203. '#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x80-\xff]*$#',
  204. $id
  205. );
  206. }
  207. /**
  208. * Register a register shutdown function.
  209. * It may be analogous to a super static destructor.
  210. *
  211. * @param callable $callable Callable.
  212. * @return bool
  213. */
  214. public static function registerShutdownFunction($callable)
  215. {
  216. return register_shutdown_function($callable);
  217. }
  218. /**
  219. * Get PHP executable.
  220. *
  221. * @return string
  222. */
  223. public static function getPHPBinary()
  224. {
  225. if (defined('PHP_BINARY')) {
  226. return PHP_BINARY;
  227. }
  228. if (isset($_SERVER['_'])) {
  229. return $_SERVER['_'];
  230. }
  231. foreach (['', '.exe'] as $extension) {
  232. if (file_exists($_ = PHP_BINDIR . DS . 'php' . $extension)) {
  233. return realpath($_);
  234. }
  235. }
  236. return null;
  237. }
  238. /**
  239. * Generate an Universal Unique Identifier (UUID).
  240. *
  241. * @return string
  242. */
  243. public static function uuid()
  244. {
  245. return sprintf(
  246. '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
  247. mt_rand(0, 0xffff),
  248. mt_rand(0, 0xffff),
  249. mt_rand(0, 0xffff),
  250. mt_rand(0, 0x0fff) | 0x4000,
  251. mt_rand(0, 0x3fff) | 0x8000,
  252. mt_rand(0, 0xffff),
  253. mt_rand(0, 0xffff),
  254. mt_rand(0, 0xffff)
  255. );
  256. }
  257. }
  258. }
  259. namespace
  260. {
  261. if (70000 > PHP_VERSION_ID && false === interface_exists('Throwable', false)) {
  262. /**
  263. * Implement a fake Throwable class, introduced in PHP7.0.
  264. */
  265. interface Throwable
  266. {
  267. public function getMessage();
  268. public function getCode();
  269. public function getFile();
  270. public function getLine();
  271. public function getTrace();
  272. public function getPrevious();
  273. public function getTraceAsString();
  274. public function __toString();
  275. }
  276. }
  277. /**
  278. * Define TLSv* constants, introduced in PHP 5.5.
  279. */
  280. if (50600 > PHP_VERSION_ID) {
  281. $define = function ($constantName, $constantValue, $case = false) {
  282. if (!defined($constantName)) {
  283. return define($constantName, $constantValue, $case);
  284. }
  285. return false;
  286. };
  287. $define('STREAM_CRYPTO_METHOD_TLSv1_0_SERVER', 8);
  288. $define('STREAM_CRYPTO_METHOD_TLSv1_1_SERVER', 16);
  289. $define('STREAM_CRYPTO_METHOD_TLSv1_2_SERVER', 32);
  290. $define('STREAM_CRYPTO_METHOD_ANY_SERVER', 62);
  291. $define('STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT', 9);
  292. $define('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT', 17);
  293. $define('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT', 33);
  294. $define('STREAM_CRYPTO_METHOD_ANY_CLIENT', 63);
  295. }
  296. if (!function_exists('curry')) {
  297. /**
  298. * Curry.
  299. * Example:
  300. * $c = curry('str_replace', …, …, 'foobar');
  301. * var_dump($c('foo', 'baz')); // bazbar
  302. * $c = curry('str_replace', 'foo', 'baz', …);
  303. * var_dump($c('foobarbaz')); // bazbarbaz
  304. * Nested curries also work:
  305. * $c1 = curry('str_replace', …, …, 'foobar');
  306. * $c2 = curry($c1, 'foo', …);
  307. * var_dump($c2('baz')); // bazbar
  308. * Obviously, as the first argument is a callable, we can combine this with
  309. * \Hoa\Consistency\Xcallable ;-).
  310. * The “…” character is the HORIZONTAL ELLIPSIS Unicode character (Unicode:
  311. * 2026, UTF-8: E2 80 A6).
  312. *
  313. * @param mixed $callable Callable (two parts).
  314. * @param ... ... Arguments.
  315. * @return \Closure
  316. */
  317. function curry($callable)
  318. {
  319. $arguments = func_get_args();
  320. array_shift($arguments);
  321. $ii = array_keys($arguments, …, true);
  322. return function () use ($callable, $arguments, $ii) {
  323. return call_user_func_array(
  324. $callable,
  325. array_replace($arguments, array_combine($ii, func_get_args()))
  326. );
  327. };
  328. }
  329. }
  330. /**
  331. * Flex entity.
  332. */
  333. Hoa\Consistency\Consistency::flexEntity('Hoa\Consistency\Consistency');
  334. }