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