Chris@0
|
1 <?php
|
Chris@0
|
2 /*
|
Chris@14
|
3 * This file is part of sebastian/environment.
|
Chris@0
|
4 *
|
Chris@0
|
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
|
Chris@0
|
6 *
|
Chris@0
|
7 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
8 * file that was distributed with this source code.
|
Chris@0
|
9 */
|
Chris@0
|
10
|
Chris@14
|
11 declare(strict_types=1);
|
Chris@14
|
12
|
Chris@0
|
13 namespace SebastianBergmann\Environment;
|
Chris@0
|
14
|
Chris@0
|
15 /**
|
Chris@0
|
16 * Utility class for HHVM/PHP environment handling.
|
Chris@0
|
17 */
|
Chris@14
|
18 final class Runtime
|
Chris@0
|
19 {
|
Chris@0
|
20 /**
|
Chris@0
|
21 * @var string
|
Chris@0
|
22 */
|
Chris@0
|
23 private static $binary;
|
Chris@0
|
24
|
Chris@0
|
25 /**
|
Chris@0
|
26 * Returns true when Xdebug is supported or
|
Chris@14
|
27 * the runtime used is PHPDBG.
|
Chris@0
|
28 */
|
Chris@14
|
29 public function canCollectCodeCoverage(): bool
|
Chris@0
|
30 {
|
Chris@0
|
31 return $this->hasXdebug() || $this->hasPHPDBGCodeCoverage();
|
Chris@0
|
32 }
|
Chris@0
|
33
|
Chris@0
|
34 /**
|
Chris@14
|
35 * Returns true when OPcache is loaded and opcache.save_comments=0 is set.
|
Chris@14
|
36 *
|
Chris@14
|
37 * Code taken from Doctrine\Common\Annotations\AnnotationReader::__construct().
|
Chris@14
|
38 */
|
Chris@14
|
39 public function discardsComments(): bool
|
Chris@14
|
40 {
|
Chris@14
|
41 if (\extension_loaded('Zend Optimizer+') && (\ini_get('zend_optimizerplus.save_comments') === '0' || \ini_get('opcache.save_comments') === '0')) {
|
Chris@14
|
42 return true;
|
Chris@14
|
43 }
|
Chris@14
|
44
|
Chris@14
|
45 if (\extension_loaded('Zend OPcache') && \ini_get('opcache.save_comments') == 0) {
|
Chris@14
|
46 return true;
|
Chris@14
|
47 }
|
Chris@14
|
48
|
Chris@14
|
49 return false;
|
Chris@14
|
50 }
|
Chris@14
|
51
|
Chris@14
|
52 /**
|
Chris@0
|
53 * Returns the path to the binary of the current runtime.
|
Chris@0
|
54 * Appends ' --php' to the path when the runtime is HHVM.
|
Chris@0
|
55 */
|
Chris@14
|
56 public function getBinary(): string
|
Chris@0
|
57 {
|
Chris@0
|
58 // HHVM
|
Chris@0
|
59 if (self::$binary === null && $this->isHHVM()) {
|
Chris@14
|
60 // @codeCoverageIgnoreStart
|
Chris@14
|
61 if ((self::$binary = \getenv('PHP_BINARY')) === false) {
|
Chris@0
|
62 self::$binary = PHP_BINARY;
|
Chris@0
|
63 }
|
Chris@0
|
64
|
Chris@14
|
65 self::$binary = \escapeshellarg(self::$binary) . ' --php' .
|
Chris@14
|
66 ' -d hhvm.php7.all=1';
|
Chris@14
|
67 // @codeCoverageIgnoreEnd
|
Chris@0
|
68 }
|
Chris@0
|
69
|
Chris@14
|
70 if (self::$binary === null && PHP_BINARY !== '') {
|
Chris@14
|
71 self::$binary = \escapeshellarg(PHP_BINARY);
|
Chris@0
|
72 }
|
Chris@0
|
73
|
Chris@0
|
74 if (self::$binary === null) {
|
Chris@14
|
75 // @codeCoverageIgnoreStart
|
Chris@14
|
76 $possibleBinaryLocations = [
|
Chris@0
|
77 PHP_BINDIR . '/php',
|
Chris@0
|
78 PHP_BINDIR . '/php-cli.exe',
|
Chris@0
|
79 PHP_BINDIR . '/php.exe'
|
Chris@14
|
80 ];
|
Chris@0
|
81
|
Chris@0
|
82 foreach ($possibleBinaryLocations as $binary) {
|
Chris@14
|
83 if (\is_readable($binary)) {
|
Chris@14
|
84 self::$binary = \escapeshellarg($binary);
|
Chris@0
|
85 break;
|
Chris@0
|
86 }
|
Chris@0
|
87 }
|
Chris@14
|
88 // @codeCoverageIgnoreEnd
|
Chris@0
|
89 }
|
Chris@0
|
90
|
Chris@0
|
91 if (self::$binary === null) {
|
Chris@14
|
92 // @codeCoverageIgnoreStart
|
Chris@0
|
93 self::$binary = 'php';
|
Chris@14
|
94 // @codeCoverageIgnoreEnd
|
Chris@0
|
95 }
|
Chris@0
|
96
|
Chris@0
|
97 return self::$binary;
|
Chris@0
|
98 }
|
Chris@0
|
99
|
Chris@14
|
100 public function getNameWithVersion(): string
|
Chris@0
|
101 {
|
Chris@0
|
102 return $this->getName() . ' ' . $this->getVersion();
|
Chris@0
|
103 }
|
Chris@0
|
104
|
Chris@14
|
105 public function getName(): string
|
Chris@0
|
106 {
|
Chris@0
|
107 if ($this->isHHVM()) {
|
Chris@14
|
108 // @codeCoverageIgnoreStart
|
Chris@0
|
109 return 'HHVM';
|
Chris@14
|
110 // @codeCoverageIgnoreEnd
|
Chris@14
|
111 }
|
Chris@14
|
112
|
Chris@14
|
113 if ($this->isPHPDBG()) {
|
Chris@14
|
114 // @codeCoverageIgnoreStart
|
Chris@0
|
115 return 'PHPDBG';
|
Chris@14
|
116 // @codeCoverageIgnoreEnd
|
Chris@0
|
117 }
|
Chris@14
|
118
|
Chris@14
|
119 return 'PHP';
|
Chris@0
|
120 }
|
Chris@0
|
121
|
Chris@14
|
122 public function getVendorUrl(): string
|
Chris@0
|
123 {
|
Chris@0
|
124 if ($this->isHHVM()) {
|
Chris@14
|
125 // @codeCoverageIgnoreStart
|
Chris@0
|
126 return 'http://hhvm.com/';
|
Chris@14
|
127 // @codeCoverageIgnoreEnd
|
Chris@0
|
128 }
|
Chris@14
|
129
|
Chris@14
|
130 return 'https://secure.php.net/';
|
Chris@0
|
131 }
|
Chris@0
|
132
|
Chris@14
|
133 public function getVersion(): string
|
Chris@0
|
134 {
|
Chris@0
|
135 if ($this->isHHVM()) {
|
Chris@14
|
136 // @codeCoverageIgnoreStart
|
Chris@0
|
137 return HHVM_VERSION;
|
Chris@14
|
138 // @codeCoverageIgnoreEnd
|
Chris@0
|
139 }
|
Chris@14
|
140
|
Chris@14
|
141 return PHP_VERSION;
|
Chris@0
|
142 }
|
Chris@0
|
143
|
Chris@0
|
144 /**
|
Chris@0
|
145 * Returns true when the runtime used is PHP and Xdebug is loaded.
|
Chris@0
|
146 */
|
Chris@14
|
147 public function hasXdebug(): bool
|
Chris@0
|
148 {
|
Chris@14
|
149 return ($this->isPHP() || $this->isHHVM()) && \extension_loaded('xdebug');
|
Chris@0
|
150 }
|
Chris@0
|
151
|
Chris@0
|
152 /**
|
Chris@0
|
153 * Returns true when the runtime used is HHVM.
|
Chris@0
|
154 */
|
Chris@14
|
155 public function isHHVM(): bool
|
Chris@0
|
156 {
|
Chris@14
|
157 return \defined('HHVM_VERSION');
|
Chris@0
|
158 }
|
Chris@0
|
159
|
Chris@0
|
160 /**
|
Chris@0
|
161 * Returns true when the runtime used is PHP without the PHPDBG SAPI.
|
Chris@0
|
162 */
|
Chris@14
|
163 public function isPHP(): bool
|
Chris@0
|
164 {
|
Chris@0
|
165 return !$this->isHHVM() && !$this->isPHPDBG();
|
Chris@0
|
166 }
|
Chris@0
|
167
|
Chris@0
|
168 /**
|
Chris@0
|
169 * Returns true when the runtime used is PHP with the PHPDBG SAPI.
|
Chris@0
|
170 */
|
Chris@14
|
171 public function isPHPDBG(): bool
|
Chris@0
|
172 {
|
Chris@0
|
173 return PHP_SAPI === 'phpdbg' && !$this->isHHVM();
|
Chris@0
|
174 }
|
Chris@0
|
175
|
Chris@0
|
176 /**
|
Chris@0
|
177 * Returns true when the runtime used is PHP with the PHPDBG SAPI
|
Chris@0
|
178 * and the phpdbg_*_oplog() functions are available (PHP >= 7.0).
|
Chris@0
|
179 *
|
Chris@14
|
180 * @codeCoverageIgnore
|
Chris@0
|
181 */
|
Chris@14
|
182 public function hasPHPDBGCodeCoverage(): bool
|
Chris@0
|
183 {
|
Chris@14
|
184 return $this->isPHPDBG();
|
Chris@0
|
185 }
|
Chris@0
|
186 }
|