├── .gitignore ├── CoStart.php ├── README.md ├── composer.json ├── composer.lock ├── core ├── common.php ├── coroutines │ ├── CoSocket.php │ ├── CoroutineReturnValue.php │ ├── Scheduler.php │ ├── SystemCall.php │ └── Task.php └── socket │ ├── SocketListen.php │ ├── SocketServer.php │ └── Sockets.php ├── curl.php ├── start.php ├── test.php └── vendor ├── autoload.php └── composer ├── ClassLoader.php ├── InstalledVersions.php ├── LICENSE ├── autoload_classmap.php ├── autoload_files.php ├── autoload_namespaces.php ├── autoload_psr4.php ├── autoload_real.php ├── autoload_static.php ├── installed.json └── installed.php /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | !.gitignore 3 | .idea* 4 | *runtime 5 | composer.lock -------------------------------------------------------------------------------- /CoStart.php: -------------------------------------------------------------------------------- 1 | accept()) 18 | ); 19 | } 20 | } 21 | 22 | /** 23 | * @param CoSocket $socket 24 | * @return \Generator 25 | */ 26 | function handleClient(CoSocket $socket): Generator 27 | { 28 | $data = (yield $socket->read(8192)); 29 | $msg = "Received following request:\n\n"; 30 | $msgLength = strlen($msg); 31 | $response = <<write($response); 39 | yield $socket->close(); 40 | } 41 | $scheduler = new Scheduler; 42 | try { 43 | $scheduler->newTask(server(8000)); 44 | /** @noinspection PhpUnreachableStatementInspection */ 45 | $scheduler->run(); 46 | } catch (Exception $e) { 47 | 48 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 在PHP中使用协程实现多任务调度 2 | `这是来自鸟哥翻译的一篇php文章中的代码`本人运行环境 php7.1 3 |

php 协程 http封装

4 |

5 | https://www.laruence.com/2015/05/28/3038.html 6 |

-------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "php/php-yield-webserver", 3 | "authors": [ 4 | { 5 | "name": "nekgod", 6 | "email": "1559096467@qq.com" 7 | } 8 | ], 9 | "autoload": { 10 | "psr-4": { 11 | "core\\": "core/" 12 | }, 13 | "files": ["core/common.php"] 14 | }, 15 | "require": {} 16 | } 17 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "c2bb16a30b43905b0d6682b7ef866fee", 8 | "packages": [], 9 | "packages-dev": [], 10 | "aliases": [], 11 | "minimum-stability": "stable", 12 | "stability-flags": [], 13 | "prefer-stable": false, 14 | "prefer-lowest": false, 15 | "platform": [], 16 | "platform-dev": [], 17 | "plugin-api-version": "2.0.0" 18 | } 19 | -------------------------------------------------------------------------------- /core/common.php: -------------------------------------------------------------------------------- 1 | setSendValue($task->getTaskId()); 16 | $scheduler->schedule($task); 17 | }); 18 | } 19 | 20 | /** 21 | * 创建新任务 22 | * @param Generator $coroutine 23 | * @return SystemCall 24 | */ 25 | function newTask(Generator $coroutine): SystemCall 26 | { 27 | return new SystemCall( 28 | function (Task $task, Scheduler $scheduler) use ($coroutine) { 29 | $task->setSendValue($scheduler->newTask($coroutine)); 30 | $scheduler->schedule($task); 31 | } 32 | ); 33 | } 34 | 35 | /** 36 | * 删除任务 37 | * @param $tid 38 | * @return SystemCall 39 | */ 40 | function killTask($tid): SystemCall 41 | { 42 | return new SystemCall( 43 | function (Task $task, Scheduler $scheduler) use ($tid) { 44 | $task->setSendValue($scheduler->killTask($tid)); 45 | $scheduler->schedule($task); 46 | } 47 | ); 48 | } 49 | 50 | /** 51 | * socket 读取 52 | * @param $socket 53 | * @return SystemCall 54 | */ 55 | function waitForRead($socket): SystemCall 56 | { 57 | return new SystemCall( 58 | function (Task $task, Scheduler $scheduler) use ($socket) { 59 | $scheduler->waitForRead($socket, $task); 60 | } 61 | ); 62 | } 63 | 64 | /** 65 | * socket 写入 66 | * @param $socket 67 | * @return \core\coroutines\SystemCall 68 | */ 69 | function waitForWrite($socket): SystemCall 70 | { 71 | return new SystemCall( 72 | function (Task $task, Scheduler $scheduler) use ($socket) { 73 | $scheduler->waitForWrite($socket, $task); 74 | } 75 | ); 76 | } 77 | 78 | /** 79 | * 协程堆栈 80 | * @param Generator $gen 81 | * @return Generator|void 82 | */ 83 | function stackedCoroutine(Generator $gen) 84 | { 85 | $stack = new SplStack; 86 | for (; ;) { 87 | $value = $gen->current(); 88 | if ($value instanceof Generator) { 89 | $stack->push($gen); 90 | $gen = $value; 91 | continue; 92 | } 93 | $isReturnValue = $value instanceof CoroutineReturnValue; 94 | if (!$gen->valid() || $isReturnValue) { 95 | if ($stack->isEmpty()) { 96 | return; 97 | } 98 | $gen = $stack->pop(); 99 | $gen->send($isReturnValue ? $value->getValue() : NULL); 100 | continue; 101 | } 102 | $gen->send(yield $gen->key() => $value); 103 | } 104 | } 105 | 106 | /** 107 | * 创建协程返回函数 108 | * @param $value 109 | * @return CoroutineReturnValue 110 | */ 111 | function retval($value): CoroutineReturnValue 112 | { 113 | return new CoroutineReturnValue($value); 114 | } -------------------------------------------------------------------------------- /core/coroutines/CoSocket.php: -------------------------------------------------------------------------------- 1 | socket = $socket; 11 | } 12 | 13 | public function accept() 14 | { 15 | yield waitForRead($this->socket); 16 | yield retval(new CoSocket(stream_socket_accept($this->socket, 0))); 17 | } 18 | 19 | public function read($size) 20 | { 21 | yield waitForRead($this->socket); 22 | yield retval(fread($this->socket, $size)); 23 | } 24 | 25 | public function write($string) 26 | { 27 | yield waitForWrite($this->socket); 28 | fwrite($this->socket, $string); 29 | } 30 | 31 | public function close() 32 | { 33 | @fclose($this->socket); 34 | } 35 | } -------------------------------------------------------------------------------- /core/coroutines/CoroutineReturnValue.php: -------------------------------------------------------------------------------- 1 | value = $value; 14 | } 15 | 16 | public function getValue() 17 | { 18 | return $this->value; 19 | } 20 | } -------------------------------------------------------------------------------- /core/coroutines/Scheduler.php: -------------------------------------------------------------------------------- 1 | task 16 | protected $taskQueue; // 任务队列 17 | 18 | public function __construct() 19 | { 20 | $this->taskQueue = new SplQueue(); 21 | } 22 | 23 | /** 24 | * 运行调度器 执行任务 25 | * @return void 26 | */ 27 | public function run() 28 | { 29 | $this->newTask($this->ioPollTask()); 30 | while (!$this->taskQueue->isEmpty()) { 31 | /** @var Task $task */ 32 | $task = $this->taskQueue->dequeue(); 33 | $retrieval = $task->run(); 34 | /** 35 | * 任务中有系统调用函数执行 36 | */ 37 | if ($retrieval instanceof SystemCall) { 38 | $retrieval($task, $this); 39 | continue; 40 | } 41 | if ($task->isFinished()) { 42 | unset($this->taskMap[$task->getTaskId()]); 43 | } else { 44 | $this->schedule($task); 45 | } 46 | } 47 | } 48 | 49 | /** 50 | * 任务 追加 51 | * @param Generator $coroutine 52 | * @return int 53 | */ 54 | public function newTask(Generator $coroutine): int 55 | { 56 | $tid = ++$this->maxTaskId; 57 | $task = new Task($tid, $coroutine); 58 | $this->taskMap[$tid] = $task; 59 | $this->schedule($task); 60 | return $tid; 61 | } 62 | 63 | /** 64 | * 协程最小调度单位 yield 加入调用任务队列 65 | * @param Task $task 66 | * @return void 67 | */ 68 | public function schedule(Task $task) 69 | { 70 | $this->taskQueue->enqueue($task); 71 | } 72 | 73 | /** 74 | * 删除任务 75 | * @param $tid 76 | * @return bool 77 | */ 78 | public function killTask($tid): bool 79 | { 80 | if (!isset($this->taskMap[$tid])) { 81 | return false; 82 | } 83 | // 移除task任务映射 84 | unset($this->taskMap[$tid]); 85 | // 移除任务队列 86 | foreach ($this->taskQueue as $i => $task) { 87 | if ($task->getTaskId() === $tid) { 88 | unset($this->taskQueue[$i]); 89 | break; 90 | } 91 | } 92 | return true; 93 | } 94 | 95 | protected $waitingForRead = []; 96 | protected $waitingForWrite = []; 97 | 98 | // resourceID => [socket, tasks] 99 | 100 | public function waitForRead($socket, Task $task) 101 | { 102 | if (isset($this->waitingForRead[(int)$socket])) { 103 | $this->waitingForRead[(int)$socket][1][] = $task; 104 | } else { 105 | $this->waitingForRead[(int)$socket] = [$socket, [$task]]; 106 | } 107 | } 108 | 109 | public function waitForWrite($socket, Task $task) 110 | { 111 | if (isset($this->waitingForWrite[(int)$socket])) { 112 | $this->waitingForWrite[(int)$socket][1][] = $task; 113 | } else { 114 | $this->waitingForWrite[(int)$socket] = [$socket, [$task]]; 115 | } 116 | } 117 | 118 | protected function ioPollTask(): Generator 119 | { 120 | while (true) { 121 | if ($this->taskQueue->isEmpty()) { 122 | $this->ioPoll(null); 123 | } else { 124 | $this->ioPoll(0); 125 | } 126 | yield; 127 | } 128 | } 129 | 130 | protected function ioPoll($timeout) 131 | { 132 | $rSocks = []; 133 | foreach ($this->waitingForRead as list($socket)) { 134 | $rSocks[] = $socket; 135 | } 136 | $wSocks = []; 137 | foreach ($this->waitingForWrite as list($socket)) { 138 | $wSocks[] = $socket; 139 | } 140 | // var_dump($rSocks); 141 | // var_dump($wSocks); 142 | $eSocks = []; // dummy 143 | if (!stream_select($rSocks, $wSocks, $eSocks, $timeout)) { 144 | return; 145 | } 146 | foreach ($rSocks as $socket) { 147 | list(, $tasks) = $this->waitingForRead[(int)$socket]; 148 | unset($this->waitingForRead[(int)$socket]); 149 | foreach ($tasks as $task) { 150 | $this->schedule($task); 151 | } 152 | } 153 | foreach ($wSocks as $socket) { 154 | list(, $tasks) = $this->waitingForWrite[(int)$socket]; 155 | unset($this->waitingForWrite[(int)$socket]); 156 | foreach ($tasks as $task) { 157 | $this->schedule($task); 158 | } 159 | } 160 | } 161 | } 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /core/coroutines/SystemCall.php: -------------------------------------------------------------------------------- 1 | callback = $callback; 18 | } 19 | 20 | public function __invoke(Task $task, Scheduler $scheduler) 21 | { 22 | $callback = $this->callback; 23 | return $callback($task, $scheduler); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /core/coroutines/Task.php: -------------------------------------------------------------------------------- 1 | taskId = $taskId; 20 | $this->coroutine = StackedCoroutine($coroutine); 21 | } 22 | 23 | public function getTaskId() 24 | { 25 | return $this->taskId; 26 | } 27 | 28 | public function setSendValue($sendValue) 29 | { 30 | $this->sendValue = $sendValue; 31 | } 32 | 33 | public function run() 34 | { 35 | if ($this->beforeFirstYield) { 36 | $this->beforeFirstYield = false; 37 | return $this->coroutine->current(); 38 | } 39 | 40 | $retrieval = $this->coroutine->send($this->sendValue); 41 | $this->sendValue = null; 42 | return $retrieval; 43 | } 44 | 45 | /** 46 | * 任务是否已结束 47 | * @return bool 48 | */ 49 | public function isFinished(): bool 50 | { 51 | return !$this->coroutine->valid(); 52 | } 53 | } -------------------------------------------------------------------------------- /core/socket/SocketListen.php: -------------------------------------------------------------------------------- 1 | socket = $sock; 20 | } 21 | 22 | /** 23 | * @return Sockets 24 | */ 25 | public function popSocket() 26 | { 27 | return new Sockets(socket_accept($this->getSocket())); 28 | } 29 | 30 | public function getSocket(){ 31 | return $this->socket; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /core/socket/SocketServer.php: -------------------------------------------------------------------------------- 1 | socket = $socket; 12 | } 13 | 14 | public function getContent() 15 | { 16 | if ($this->readContent) { 17 | return $this->readContent; 18 | } 19 | $this->readContent = socket_read($this->socket, 1024 * 1024); 20 | return $this->readContent; 21 | } 22 | 23 | public function sendContent($content) 24 | { 25 | return socket_write($this->socket, $content,strlen($content)); 26 | } 27 | 28 | public function close() 29 | { 30 | socket_close($this->socket); 31 | } 32 | 33 | public function getSocket() 34 | { 35 | return $this->socket; 36 | } 37 | } -------------------------------------------------------------------------------- /curl.php: -------------------------------------------------------------------------------- 1 | newTask(test()); 15 | $scheduler->run(); -------------------------------------------------------------------------------- /start.php: -------------------------------------------------------------------------------- 1 | popSocket(); 15 | var_dump($socket); 16 | $content = $socket->getContent(); 17 | var_dump($content); 18 | $s = $socket->sendContent("HTTP/1.1 200 OK 19 | Content-Type: text/html 20 | 21 | hello world\r"); 22 | var_dump($s); 23 | $socket->close(); 24 | }while(true); 25 | 26 | socket_close($socketListen->getSocket()); -------------------------------------------------------------------------------- /test.php: -------------------------------------------------------------------------------- 1 | current(); 33 | //var_dump($res); 34 | //$Scheduler = new Scheduler(); 35 | //$Scheduler->newTask(test1()); 36 | //$Scheduler->run(); -------------------------------------------------------------------------------- /vendor/autoload.php: -------------------------------------------------------------------------------- 1 | 7 | * Jordi Boggiano 8 | * 9 | * For the full copyright and license information, please view the LICENSE 10 | * file that was distributed with this source code. 11 | */ 12 | 13 | namespace Composer\Autoload; 14 | 15 | /** 16 | * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. 17 | * 18 | * $loader = new \Composer\Autoload\ClassLoader(); 19 | * 20 | * // register classes with namespaces 21 | * $loader->add('Symfony\Component', __DIR__.'/component'); 22 | * $loader->add('Symfony', __DIR__.'/framework'); 23 | * 24 | * // activate the autoloader 25 | * $loader->register(); 26 | * 27 | * // to enable searching the include path (eg. for PEAR packages) 28 | * $loader->setUseIncludePath(true); 29 | * 30 | * In this example, if you try to use a class in the Symfony\Component 31 | * namespace or one of its children (Symfony\Component\Console for instance), 32 | * the autoloader will first look for the class under the component/ 33 | * directory, and it will then fallback to the framework/ directory if not 34 | * found before giving up. 35 | * 36 | * This class is loosely based on the Symfony UniversalClassLoader. 37 | * 38 | * @author Fabien Potencier 39 | * @author Jordi Boggiano 40 | * @see https://www.php-fig.org/psr/psr-0/ 41 | * @see https://www.php-fig.org/psr/psr-4/ 42 | */ 43 | class ClassLoader 44 | { 45 | /** @var ?string */ 46 | private $vendorDir; 47 | 48 | // PSR-4 49 | /** 50 | * @var array[] 51 | * @psalm-var array> 52 | */ 53 | private $prefixLengthsPsr4 = array(); 54 | /** 55 | * @var array[] 56 | * @psalm-var array> 57 | */ 58 | private $prefixDirsPsr4 = array(); 59 | /** 60 | * @var array[] 61 | * @psalm-var array 62 | */ 63 | private $fallbackDirsPsr4 = array(); 64 | 65 | // PSR-0 66 | /** 67 | * @var array[] 68 | * @psalm-var array> 69 | */ 70 | private $prefixesPsr0 = array(); 71 | /** 72 | * @var array[] 73 | * @psalm-var array 74 | */ 75 | private $fallbackDirsPsr0 = array(); 76 | 77 | /** @var bool */ 78 | private $useIncludePath = false; 79 | 80 | /** 81 | * @var string[] 82 | * @psalm-var array 83 | */ 84 | private $classMap = array(); 85 | 86 | /** @var bool */ 87 | private $classMapAuthoritative = false; 88 | 89 | /** 90 | * @var bool[] 91 | * @psalm-var array 92 | */ 93 | private $missingClasses = array(); 94 | 95 | /** @var ?string */ 96 | private $apcuPrefix; 97 | 98 | /** 99 | * @var self[] 100 | */ 101 | private static $registeredLoaders = array(); 102 | 103 | /** 104 | * @param ?string $vendorDir 105 | */ 106 | public function __construct($vendorDir = null) 107 | { 108 | $this->vendorDir = $vendorDir; 109 | } 110 | 111 | /** 112 | * @return string[] 113 | */ 114 | public function getPrefixes() 115 | { 116 | if (!empty($this->prefixesPsr0)) { 117 | return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); 118 | } 119 | 120 | return array(); 121 | } 122 | 123 | /** 124 | * @return array[] 125 | * @psalm-return array> 126 | */ 127 | public function getPrefixesPsr4() 128 | { 129 | return $this->prefixDirsPsr4; 130 | } 131 | 132 | /** 133 | * @return array[] 134 | * @psalm-return array 135 | */ 136 | public function getFallbackDirs() 137 | { 138 | return $this->fallbackDirsPsr0; 139 | } 140 | 141 | /** 142 | * @return array[] 143 | * @psalm-return array 144 | */ 145 | public function getFallbackDirsPsr4() 146 | { 147 | return $this->fallbackDirsPsr4; 148 | } 149 | 150 | /** 151 | * @return string[] Array of classname => path 152 | * @psalm-return array 153 | */ 154 | public function getClassMap() 155 | { 156 | return $this->classMap; 157 | } 158 | 159 | /** 160 | * @param string[] $classMap Class to filename map 161 | * @psalm-param array $classMap 162 | * 163 | * @return void 164 | */ 165 | public function addClassMap(array $classMap) 166 | { 167 | if ($this->classMap) { 168 | $this->classMap = array_merge($this->classMap, $classMap); 169 | } else { 170 | $this->classMap = $classMap; 171 | } 172 | } 173 | 174 | /** 175 | * Registers a set of PSR-0 directories for a given prefix, either 176 | * appending or prepending to the ones previously set for this prefix. 177 | * 178 | * @param string $prefix The prefix 179 | * @param string[]|string $paths The PSR-0 root directories 180 | * @param bool $prepend Whether to prepend the directories 181 | * 182 | * @return void 183 | */ 184 | public function add($prefix, $paths, $prepend = false) 185 | { 186 | if (!$prefix) { 187 | if ($prepend) { 188 | $this->fallbackDirsPsr0 = array_merge( 189 | (array) $paths, 190 | $this->fallbackDirsPsr0 191 | ); 192 | } else { 193 | $this->fallbackDirsPsr0 = array_merge( 194 | $this->fallbackDirsPsr0, 195 | (array) $paths 196 | ); 197 | } 198 | 199 | return; 200 | } 201 | 202 | $first = $prefix[0]; 203 | if (!isset($this->prefixesPsr0[$first][$prefix])) { 204 | $this->prefixesPsr0[$first][$prefix] = (array) $paths; 205 | 206 | return; 207 | } 208 | if ($prepend) { 209 | $this->prefixesPsr0[$first][$prefix] = array_merge( 210 | (array) $paths, 211 | $this->prefixesPsr0[$first][$prefix] 212 | ); 213 | } else { 214 | $this->prefixesPsr0[$first][$prefix] = array_merge( 215 | $this->prefixesPsr0[$first][$prefix], 216 | (array) $paths 217 | ); 218 | } 219 | } 220 | 221 | /** 222 | * Registers a set of PSR-4 directories for a given namespace, either 223 | * appending or prepending to the ones previously set for this namespace. 224 | * 225 | * @param string $prefix The prefix/namespace, with trailing '\\' 226 | * @param string[]|string $paths The PSR-4 base directories 227 | * @param bool $prepend Whether to prepend the directories 228 | * 229 | * @throws \InvalidArgumentException 230 | * 231 | * @return void 232 | */ 233 | public function addPsr4($prefix, $paths, $prepend = false) 234 | { 235 | if (!$prefix) { 236 | // Register directories for the root namespace. 237 | if ($prepend) { 238 | $this->fallbackDirsPsr4 = array_merge( 239 | (array) $paths, 240 | $this->fallbackDirsPsr4 241 | ); 242 | } else { 243 | $this->fallbackDirsPsr4 = array_merge( 244 | $this->fallbackDirsPsr4, 245 | (array) $paths 246 | ); 247 | } 248 | } elseif (!isset($this->prefixDirsPsr4[$prefix])) { 249 | // Register directories for a new namespace. 250 | $length = strlen($prefix); 251 | if ('\\' !== $prefix[$length - 1]) { 252 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 253 | } 254 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 255 | $this->prefixDirsPsr4[$prefix] = (array) $paths; 256 | } elseif ($prepend) { 257 | // Prepend directories for an already registered namespace. 258 | $this->prefixDirsPsr4[$prefix] = array_merge( 259 | (array) $paths, 260 | $this->prefixDirsPsr4[$prefix] 261 | ); 262 | } else { 263 | // Append directories for an already registered namespace. 264 | $this->prefixDirsPsr4[$prefix] = array_merge( 265 | $this->prefixDirsPsr4[$prefix], 266 | (array) $paths 267 | ); 268 | } 269 | } 270 | 271 | /** 272 | * Registers a set of PSR-0 directories for a given prefix, 273 | * replacing any others previously set for this prefix. 274 | * 275 | * @param string $prefix The prefix 276 | * @param string[]|string $paths The PSR-0 base directories 277 | * 278 | * @return void 279 | */ 280 | public function set($prefix, $paths) 281 | { 282 | if (!$prefix) { 283 | $this->fallbackDirsPsr0 = (array) $paths; 284 | } else { 285 | $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; 286 | } 287 | } 288 | 289 | /** 290 | * Registers a set of PSR-4 directories for a given namespace, 291 | * replacing any others previously set for this namespace. 292 | * 293 | * @param string $prefix The prefix/namespace, with trailing '\\' 294 | * @param string[]|string $paths The PSR-4 base directories 295 | * 296 | * @throws \InvalidArgumentException 297 | * 298 | * @return void 299 | */ 300 | public function setPsr4($prefix, $paths) 301 | { 302 | if (!$prefix) { 303 | $this->fallbackDirsPsr4 = (array) $paths; 304 | } else { 305 | $length = strlen($prefix); 306 | if ('\\' !== $prefix[$length - 1]) { 307 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 308 | } 309 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 310 | $this->prefixDirsPsr4[$prefix] = (array) $paths; 311 | } 312 | } 313 | 314 | /** 315 | * Turns on searching the include path for class files. 316 | * 317 | * @param bool $useIncludePath 318 | * 319 | * @return void 320 | */ 321 | public function setUseIncludePath($useIncludePath) 322 | { 323 | $this->useIncludePath = $useIncludePath; 324 | } 325 | 326 | /** 327 | * Can be used to check if the autoloader uses the include path to check 328 | * for classes. 329 | * 330 | * @return bool 331 | */ 332 | public function getUseIncludePath() 333 | { 334 | return $this->useIncludePath; 335 | } 336 | 337 | /** 338 | * Turns off searching the prefix and fallback directories for classes 339 | * that have not been registered with the class map. 340 | * 341 | * @param bool $classMapAuthoritative 342 | * 343 | * @return void 344 | */ 345 | public function setClassMapAuthoritative($classMapAuthoritative) 346 | { 347 | $this->classMapAuthoritative = $classMapAuthoritative; 348 | } 349 | 350 | /** 351 | * Should class lookup fail if not found in the current class map? 352 | * 353 | * @return bool 354 | */ 355 | public function isClassMapAuthoritative() 356 | { 357 | return $this->classMapAuthoritative; 358 | } 359 | 360 | /** 361 | * APCu prefix to use to cache found/not-found classes, if the extension is enabled. 362 | * 363 | * @param string|null $apcuPrefix 364 | * 365 | * @return void 366 | */ 367 | public function setApcuPrefix($apcuPrefix) 368 | { 369 | $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; 370 | } 371 | 372 | /** 373 | * The APCu prefix in use, or null if APCu caching is not enabled. 374 | * 375 | * @return string|null 376 | */ 377 | public function getApcuPrefix() 378 | { 379 | return $this->apcuPrefix; 380 | } 381 | 382 | /** 383 | * Registers this instance as an autoloader. 384 | * 385 | * @param bool $prepend Whether to prepend the autoloader or not 386 | * 387 | * @return void 388 | */ 389 | public function register($prepend = false) 390 | { 391 | spl_autoload_register(array($this, 'loadClass'), true, $prepend); 392 | 393 | if (null === $this->vendorDir) { 394 | return; 395 | } 396 | 397 | if ($prepend) { 398 | self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; 399 | } else { 400 | unset(self::$registeredLoaders[$this->vendorDir]); 401 | self::$registeredLoaders[$this->vendorDir] = $this; 402 | } 403 | } 404 | 405 | /** 406 | * Unregisters this instance as an autoloader. 407 | * 408 | * @return void 409 | */ 410 | public function unregister() 411 | { 412 | spl_autoload_unregister(array($this, 'loadClass')); 413 | 414 | if (null !== $this->vendorDir) { 415 | unset(self::$registeredLoaders[$this->vendorDir]); 416 | } 417 | } 418 | 419 | /** 420 | * Loads the given class or interface. 421 | * 422 | * @param string $class The name of the class 423 | * @return true|null True if loaded, null otherwise 424 | */ 425 | public function loadClass($class) 426 | { 427 | if ($file = $this->findFile($class)) { 428 | includeFile($file); 429 | 430 | return true; 431 | } 432 | 433 | return null; 434 | } 435 | 436 | /** 437 | * Finds the path to the file where the class is defined. 438 | * 439 | * @param string $class The name of the class 440 | * 441 | * @return string|false The path if found, false otherwise 442 | */ 443 | public function findFile($class) 444 | { 445 | // class map lookup 446 | if (isset($this->classMap[$class])) { 447 | return $this->classMap[$class]; 448 | } 449 | if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { 450 | return false; 451 | } 452 | if (null !== $this->apcuPrefix) { 453 | $file = apcu_fetch($this->apcuPrefix.$class, $hit); 454 | if ($hit) { 455 | return $file; 456 | } 457 | } 458 | 459 | $file = $this->findFileWithExtension($class, '.php'); 460 | 461 | // Search for Hack files if we are running on HHVM 462 | if (false === $file && defined('HHVM_VERSION')) { 463 | $file = $this->findFileWithExtension($class, '.hh'); 464 | } 465 | 466 | if (null !== $this->apcuPrefix) { 467 | apcu_add($this->apcuPrefix.$class, $file); 468 | } 469 | 470 | if (false === $file) { 471 | // Remember that this class does not exist. 472 | $this->missingClasses[$class] = true; 473 | } 474 | 475 | return $file; 476 | } 477 | 478 | /** 479 | * Returns the currently registered loaders indexed by their corresponding vendor directories. 480 | * 481 | * @return self[] 482 | */ 483 | public static function getRegisteredLoaders() 484 | { 485 | return self::$registeredLoaders; 486 | } 487 | 488 | /** 489 | * @param string $class 490 | * @param string $ext 491 | * @return string|false 492 | */ 493 | private function findFileWithExtension($class, $ext) 494 | { 495 | // PSR-4 lookup 496 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; 497 | 498 | $first = $class[0]; 499 | if (isset($this->prefixLengthsPsr4[$first])) { 500 | $subPath = $class; 501 | while (false !== $lastPos = strrpos($subPath, '\\')) { 502 | $subPath = substr($subPath, 0, $lastPos); 503 | $search = $subPath . '\\'; 504 | if (isset($this->prefixDirsPsr4[$search])) { 505 | $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); 506 | foreach ($this->prefixDirsPsr4[$search] as $dir) { 507 | if (file_exists($file = $dir . $pathEnd)) { 508 | return $file; 509 | } 510 | } 511 | } 512 | } 513 | } 514 | 515 | // PSR-4 fallback dirs 516 | foreach ($this->fallbackDirsPsr4 as $dir) { 517 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { 518 | return $file; 519 | } 520 | } 521 | 522 | // PSR-0 lookup 523 | if (false !== $pos = strrpos($class, '\\')) { 524 | // namespaced class name 525 | $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) 526 | . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); 527 | } else { 528 | // PEAR-like class name 529 | $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; 530 | } 531 | 532 | if (isset($this->prefixesPsr0[$first])) { 533 | foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { 534 | if (0 === strpos($class, $prefix)) { 535 | foreach ($dirs as $dir) { 536 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 537 | return $file; 538 | } 539 | } 540 | } 541 | } 542 | } 543 | 544 | // PSR-0 fallback dirs 545 | foreach ($this->fallbackDirsPsr0 as $dir) { 546 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 547 | return $file; 548 | } 549 | } 550 | 551 | // PSR-0 include paths. 552 | if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { 553 | return $file; 554 | } 555 | 556 | return false; 557 | } 558 | } 559 | 560 | /** 561 | * Scope isolated include. 562 | * 563 | * Prevents access to $this/self from included files. 564 | * 565 | * @param string $file 566 | * @return void 567 | * @private 568 | */ 569 | function includeFile($file) 570 | { 571 | include $file; 572 | } 573 | -------------------------------------------------------------------------------- /vendor/composer/InstalledVersions.php: -------------------------------------------------------------------------------- 1 | 7 | * Jordi Boggiano 8 | * 9 | * For the full copyright and license information, please view the LICENSE 10 | * file that was distributed with this source code. 11 | */ 12 | 13 | namespace Composer; 14 | 15 | use Composer\Autoload\ClassLoader; 16 | use Composer\Semver\VersionParser; 17 | 18 | /** 19 | * This class is copied in every Composer installed project and available to all 20 | * 21 | * See also https://getcomposer.org/doc/07-runtime.md#installed-versions 22 | * 23 | * To require its presence, you can require `composer-runtime-api ^2.0` 24 | */ 25 | class InstalledVersions 26 | { 27 | /** 28 | * @var mixed[]|null 29 | * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array}|array{}|null 30 | */ 31 | private static $installed; 32 | 33 | /** 34 | * @var bool|null 35 | */ 36 | private static $canGetVendors; 37 | 38 | /** 39 | * @var array[] 40 | * @psalm-var array}> 41 | */ 42 | private static $installedByVendor = array(); 43 | 44 | /** 45 | * Returns a list of all package names which are present, either by being installed, replaced or provided 46 | * 47 | * @return string[] 48 | * @psalm-return list 49 | */ 50 | public static function getInstalledPackages() 51 | { 52 | $packages = array(); 53 | foreach (self::getInstalled() as $installed) { 54 | $packages[] = array_keys($installed['versions']); 55 | } 56 | 57 | if (1 === \count($packages)) { 58 | return $packages[0]; 59 | } 60 | 61 | return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); 62 | } 63 | 64 | /** 65 | * Returns a list of all package names with a specific type e.g. 'library' 66 | * 67 | * @param string $type 68 | * @return string[] 69 | * @psalm-return list 70 | */ 71 | public static function getInstalledPackagesByType($type) 72 | { 73 | $packagesByType = array(); 74 | 75 | foreach (self::getInstalled() as $installed) { 76 | foreach ($installed['versions'] as $name => $package) { 77 | if (isset($package['type']) && $package['type'] === $type) { 78 | $packagesByType[] = $name; 79 | } 80 | } 81 | } 82 | 83 | return $packagesByType; 84 | } 85 | 86 | /** 87 | * Checks whether the given package is installed 88 | * 89 | * This also returns true if the package name is provided or replaced by another package 90 | * 91 | * @param string $packageName 92 | * @param bool $includeDevRequirements 93 | * @return bool 94 | */ 95 | public static function isInstalled($packageName, $includeDevRequirements = true) 96 | { 97 | foreach (self::getInstalled() as $installed) { 98 | if (isset($installed['versions'][$packageName])) { 99 | return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); 100 | } 101 | } 102 | 103 | return false; 104 | } 105 | 106 | /** 107 | * Checks whether the given package satisfies a version constraint 108 | * 109 | * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: 110 | * 111 | * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') 112 | * 113 | * @param VersionParser $parser Install composer/semver to have access to this class and functionality 114 | * @param string $packageName 115 | * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package 116 | * @return bool 117 | */ 118 | public static function satisfies(VersionParser $parser, $packageName, $constraint) 119 | { 120 | $constraint = $parser->parseConstraints($constraint); 121 | $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); 122 | 123 | return $provided->matches($constraint); 124 | } 125 | 126 | /** 127 | * Returns a version constraint representing all the range(s) which are installed for a given package 128 | * 129 | * It is easier to use this via isInstalled() with the $constraint argument if you need to check 130 | * whether a given version of a package is installed, and not just whether it exists 131 | * 132 | * @param string $packageName 133 | * @return string Version constraint usable with composer/semver 134 | */ 135 | public static function getVersionRanges($packageName) 136 | { 137 | foreach (self::getInstalled() as $installed) { 138 | if (!isset($installed['versions'][$packageName])) { 139 | continue; 140 | } 141 | 142 | $ranges = array(); 143 | if (isset($installed['versions'][$packageName]['pretty_version'])) { 144 | $ranges[] = $installed['versions'][$packageName]['pretty_version']; 145 | } 146 | if (array_key_exists('aliases', $installed['versions'][$packageName])) { 147 | $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); 148 | } 149 | if (array_key_exists('replaced', $installed['versions'][$packageName])) { 150 | $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); 151 | } 152 | if (array_key_exists('provided', $installed['versions'][$packageName])) { 153 | $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); 154 | } 155 | 156 | return implode(' || ', $ranges); 157 | } 158 | 159 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 160 | } 161 | 162 | /** 163 | * @param string $packageName 164 | * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present 165 | */ 166 | public static function getVersion($packageName) 167 | { 168 | foreach (self::getInstalled() as $installed) { 169 | if (!isset($installed['versions'][$packageName])) { 170 | continue; 171 | } 172 | 173 | if (!isset($installed['versions'][$packageName]['version'])) { 174 | return null; 175 | } 176 | 177 | return $installed['versions'][$packageName]['version']; 178 | } 179 | 180 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 181 | } 182 | 183 | /** 184 | * @param string $packageName 185 | * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present 186 | */ 187 | public static function getPrettyVersion($packageName) 188 | { 189 | foreach (self::getInstalled() as $installed) { 190 | if (!isset($installed['versions'][$packageName])) { 191 | continue; 192 | } 193 | 194 | if (!isset($installed['versions'][$packageName]['pretty_version'])) { 195 | return null; 196 | } 197 | 198 | return $installed['versions'][$packageName]['pretty_version']; 199 | } 200 | 201 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 202 | } 203 | 204 | /** 205 | * @param string $packageName 206 | * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference 207 | */ 208 | public static function getReference($packageName) 209 | { 210 | foreach (self::getInstalled() as $installed) { 211 | if (!isset($installed['versions'][$packageName])) { 212 | continue; 213 | } 214 | 215 | if (!isset($installed['versions'][$packageName]['reference'])) { 216 | return null; 217 | } 218 | 219 | return $installed['versions'][$packageName]['reference']; 220 | } 221 | 222 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 223 | } 224 | 225 | /** 226 | * @param string $packageName 227 | * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. 228 | */ 229 | public static function getInstallPath($packageName) 230 | { 231 | foreach (self::getInstalled() as $installed) { 232 | if (!isset($installed['versions'][$packageName])) { 233 | continue; 234 | } 235 | 236 | return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; 237 | } 238 | 239 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 240 | } 241 | 242 | /** 243 | * @return array 244 | * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} 245 | */ 246 | public static function getRootPackage() 247 | { 248 | $installed = self::getInstalled(); 249 | 250 | return $installed[0]['root']; 251 | } 252 | 253 | /** 254 | * Returns the raw installed.php data for custom implementations 255 | * 256 | * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. 257 | * @return array[] 258 | * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} 259 | */ 260 | public static function getRawData() 261 | { 262 | @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); 263 | 264 | if (null === self::$installed) { 265 | // only require the installed.php file if this file is loaded from its dumped location, 266 | // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 267 | if (substr(__DIR__, -8, 1) !== 'C') { 268 | self::$installed = include __DIR__ . '/installed.php'; 269 | } else { 270 | self::$installed = array(); 271 | } 272 | } 273 | 274 | return self::$installed; 275 | } 276 | 277 | /** 278 | * Returns the raw data of all installed.php which are currently loaded for custom implementations 279 | * 280 | * @return array[] 281 | * @psalm-return list}> 282 | */ 283 | public static function getAllRawData() 284 | { 285 | return self::getInstalled(); 286 | } 287 | 288 | /** 289 | * Lets you reload the static array from another file 290 | * 291 | * This is only useful for complex integrations in which a project needs to use 292 | * this class but then also needs to execute another project's autoloader in process, 293 | * and wants to ensure both projects have access to their version of installed.php. 294 | * 295 | * A typical case would be PHPUnit, where it would need to make sure it reads all 296 | * the data it needs from this class, then call reload() with 297 | * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure 298 | * the project in which it runs can then also use this class safely, without 299 | * interference between PHPUnit's dependencies and the project's dependencies. 300 | * 301 | * @param array[] $data A vendor/composer/installed.php data set 302 | * @return void 303 | * 304 | * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} $data 305 | */ 306 | public static function reload($data) 307 | { 308 | self::$installed = $data; 309 | self::$installedByVendor = array(); 310 | } 311 | 312 | /** 313 | * @return array[] 314 | * @psalm-return list}> 315 | */ 316 | private static function getInstalled() 317 | { 318 | if (null === self::$canGetVendors) { 319 | self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); 320 | } 321 | 322 | $installed = array(); 323 | 324 | if (self::$canGetVendors) { 325 | foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { 326 | if (isset(self::$installedByVendor[$vendorDir])) { 327 | $installed[] = self::$installedByVendor[$vendorDir]; 328 | } elseif (is_file($vendorDir.'/composer/installed.php')) { 329 | $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; 330 | if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { 331 | self::$installed = $installed[count($installed) - 1]; 332 | } 333 | } 334 | } 335 | } 336 | 337 | if (null === self::$installed) { 338 | // only require the installed.php file if this file is loaded from its dumped location, 339 | // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 340 | if (substr(__DIR__, -8, 1) !== 'C') { 341 | self::$installed = require __DIR__ . '/installed.php'; 342 | } else { 343 | self::$installed = array(); 344 | } 345 | } 346 | $installed[] = self::$installed; 347 | 348 | return $installed; 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /vendor/composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /vendor/composer/autoload_classmap.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/composer/InstalledVersions.php', 10 | ); 11 | -------------------------------------------------------------------------------- /vendor/composer/autoload_files.php: -------------------------------------------------------------------------------- 1 | $baseDir . '/core/common.php', 10 | ); 11 | -------------------------------------------------------------------------------- /vendor/composer/autoload_namespaces.php: -------------------------------------------------------------------------------- 1 | array($baseDir . '/core'), 10 | ); 11 | -------------------------------------------------------------------------------- /vendor/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | = 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); 30 | if ($useStaticLoader) { 31 | require __DIR__ . '/autoload_static.php'; 32 | 33 | call_user_func(\Composer\Autoload\ComposerStaticInitacba2ce365c74acc98a9fb19fde0dc62::getInitializer($loader)); 34 | } else { 35 | $map = require __DIR__ . '/autoload_namespaces.php'; 36 | foreach ($map as $namespace => $path) { 37 | $loader->set($namespace, $path); 38 | } 39 | 40 | $map = require __DIR__ . '/autoload_psr4.php'; 41 | foreach ($map as $namespace => $path) { 42 | $loader->setPsr4($namespace, $path); 43 | } 44 | 45 | $classMap = require __DIR__ . '/autoload_classmap.php'; 46 | if ($classMap) { 47 | $loader->addClassMap($classMap); 48 | } 49 | } 50 | 51 | $loader->register(true); 52 | 53 | if ($useStaticLoader) { 54 | $includeFiles = Composer\Autoload\ComposerStaticInitacba2ce365c74acc98a9fb19fde0dc62::$files; 55 | } else { 56 | $includeFiles = require __DIR__ . '/autoload_files.php'; 57 | } 58 | foreach ($includeFiles as $fileIdentifier => $file) { 59 | composerRequireacba2ce365c74acc98a9fb19fde0dc62($fileIdentifier, $file); 60 | } 61 | 62 | return $loader; 63 | } 64 | } 65 | 66 | /** 67 | * @param string $fileIdentifier 68 | * @param string $file 69 | * @return void 70 | */ 71 | function composerRequireacba2ce365c74acc98a9fb19fde0dc62($fileIdentifier, $file) 72 | { 73 | if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { 74 | $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; 75 | 76 | require $file; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /vendor/composer/autoload_static.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/../..' . '/core/common.php', 11 | ); 12 | 13 | public static $prefixLengthsPsr4 = array ( 14 | 'c' => 15 | array ( 16 | 'core\\' => 5, 17 | ), 18 | ); 19 | 20 | public static $prefixDirsPsr4 = array ( 21 | 'core\\' => 22 | array ( 23 | 0 => __DIR__ . '/../..' . '/core', 24 | ), 25 | ); 26 | 27 | public static $classMap = array ( 28 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 29 | ); 30 | 31 | public static function getInitializer(ClassLoader $loader) 32 | { 33 | return \Closure::bind(function () use ($loader) { 34 | $loader->prefixLengthsPsr4 = ComposerStaticInitacba2ce365c74acc98a9fb19fde0dc62::$prefixLengthsPsr4; 35 | $loader->prefixDirsPsr4 = ComposerStaticInitacba2ce365c74acc98a9fb19fde0dc62::$prefixDirsPsr4; 36 | $loader->classMap = ComposerStaticInitacba2ce365c74acc98a9fb19fde0dc62::$classMap; 37 | 38 | }, null, ClassLoader::class); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /vendor/composer/installed.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [], 3 | "dev": true, 4 | "dev-package-names": [] 5 | } 6 | -------------------------------------------------------------------------------- /vendor/composer/installed.php: -------------------------------------------------------------------------------- 1 | array( 3 | 'pretty_version' => 'dev-master', 4 | 'version' => 'dev-master', 5 | 'type' => 'library', 6 | 'install_path' => __DIR__ . '/../../', 7 | 'aliases' => array(), 8 | 'reference' => '543cc1481efb0acbdfd514a350c27cd45da43129', 9 | 'name' => 'php/php-yield-webserver', 10 | 'dev' => true, 11 | ), 12 | 'versions' => array( 13 | 'php/php-yield-webserver' => array( 14 | 'pretty_version' => 'dev-master', 15 | 'version' => 'dev-master', 16 | 'type' => 'library', 17 | 'install_path' => __DIR__ . '/../../', 18 | 'aliases' => array(), 19 | 'reference' => '543cc1481efb0acbdfd514a350c27cd45da43129', 20 | 'dev_requirement' => false, 21 | ), 22 | ), 23 | ); 24 | --------------------------------------------------------------------------------