Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of sebastian/environment.
4
 *
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace SebastianBergmann\Environment;
11
 
12
use const PHP_BINARY;
13
use const PHP_BINDIR;
14
use const PHP_MAJOR_VERSION;
15
use const PHP_SAPI;
16
use const PHP_VERSION;
17
use function array_map;
18
use function array_merge;
19
use function defined;
20
use function escapeshellarg;
21
use function explode;
22
use function extension_loaded;
23
use function getenv;
24
use function ini_get;
25
use function is_readable;
26
use function parse_ini_file;
27
use function php_ini_loaded_file;
28
use function php_ini_scanned_files;
29
use function phpversion;
30
use function sprintf;
31
use function strpos;
32
 
33
/**
34
 * Utility class for HHVM/PHP environment handling.
35
 */
36
final class Runtime
37
{
38
    /**
39
     * @var string
40
     */
41
    private static $binary;
42
 
43
    /**
44
     * Returns true when Xdebug or PCOV is available or
45
     * the runtime used is PHPDBG.
46
     */
47
    public function canCollectCodeCoverage(): bool
48
    {
49
        return $this->hasXdebug() || $this->hasPCOV() || $this->hasPHPDBGCodeCoverage();
50
    }
51
 
52
    /**
53
     * Returns true when Zend OPcache is loaded, enabled,
54
     * and is configured to discard comments.
55
     */
56
    public function discardsComments(): bool
57
    {
58
        if (!$this->isOpcacheActive()) {
59
            return false;
60
        }
61
 
62
        if (ini_get('opcache.save_comments') !== '0') {
63
            return false;
64
        }
65
 
66
        return true;
67
    }
68
 
69
    /**
70
     * Returns true when Zend OPcache is loaded, enabled,
71
     * and is configured to perform just-in-time compilation.
72
     */
73
    public function performsJustInTimeCompilation(): bool
74
    {
75
        if (PHP_MAJOR_VERSION < 8) {
76
            return false;
77
        }
78
 
79
        if (!$this->isOpcacheActive()) {
80
            return false;
81
        }
82
 
83
        if (strpos(ini_get('opcache.jit'), '0') === 0) {
84
            return false;
85
        }
86
 
87
        return true;
88
    }
89
 
90
    /**
91
     * Returns the path to the binary of the current runtime.
92
     * Appends ' --php' to the path when the runtime is HHVM.
93
     */
94
    public function getBinary(): string
95
    {
96
        // HHVM
97
        if (self::$binary === null && $this->isHHVM()) {
98
            // @codeCoverageIgnoreStart
99
            if ((self::$binary = getenv('PHP_BINARY')) === false) {
100
                self::$binary = PHP_BINARY;
101
            }
102
 
103
            self::$binary = escapeshellarg(self::$binary) . ' --php' .
104
                ' -d hhvm.php7.all=1';
105
            // @codeCoverageIgnoreEnd
106
        }
107
 
108
        if (self::$binary === null && PHP_BINARY !== '') {
109
            self::$binary = escapeshellarg(PHP_BINARY);
110
        }
111
 
112
        if (self::$binary === null) {
113
            // @codeCoverageIgnoreStart
114
            $possibleBinaryLocations = [
115
                PHP_BINDIR . '/php',
116
                PHP_BINDIR . '/php-cli.exe',
117
                PHP_BINDIR . '/php.exe',
118
            ];
119
 
120
            foreach ($possibleBinaryLocations as $binary) {
121
                if (is_readable($binary)) {
122
                    self::$binary = escapeshellarg($binary);
123
 
124
                    break;
125
                }
126
            }
127
            // @codeCoverageIgnoreEnd
128
        }
129
 
130
        if (self::$binary === null) {
131
            // @codeCoverageIgnoreStart
132
            self::$binary = 'php';
133
            // @codeCoverageIgnoreEnd
134
        }
135
 
136
        return self::$binary;
137
    }
138
 
139
    public function getNameWithVersion(): string
140
    {
141
        return $this->getName() . ' ' . $this->getVersion();
142
    }
143
 
144
    public function getNameWithVersionAndCodeCoverageDriver(): string
145
    {
146
        if (!$this->canCollectCodeCoverage() || $this->hasPHPDBGCodeCoverage()) {
147
            return $this->getNameWithVersion();
148
        }
149
 
150
        if ($this->hasPCOV()) {
151
            return sprintf(
152
                '%s with PCOV %s',
153
                $this->getNameWithVersion(),
154
                phpversion('pcov')
155
            );
156
        }
157
 
158
        if ($this->hasXdebug()) {
159
            return sprintf(
160
                '%s with Xdebug %s',
161
                $this->getNameWithVersion(),
162
                phpversion('xdebug')
163
            );
164
        }
165
    }
166
 
167
    public function getName(): string
168
    {
169
        if ($this->isHHVM()) {
170
            // @codeCoverageIgnoreStart
171
            return 'HHVM';
172
            // @codeCoverageIgnoreEnd
173
        }
174
 
175
        if ($this->isPHPDBG()) {
176
            // @codeCoverageIgnoreStart
177
            return 'PHPDBG';
178
            // @codeCoverageIgnoreEnd
179
        }
180
 
181
        return 'PHP';
182
    }
183
 
184
    public function getVendorUrl(): string
185
    {
186
        if ($this->isHHVM()) {
187
            // @codeCoverageIgnoreStart
188
            return 'http://hhvm.com/';
189
            // @codeCoverageIgnoreEnd
190
        }
191
 
192
        return 'https://secure.php.net/';
193
    }
194
 
195
    public function getVersion(): string
196
    {
197
        if ($this->isHHVM()) {
198
            // @codeCoverageIgnoreStart
199
            return HHVM_VERSION;
200
            // @codeCoverageIgnoreEnd
201
        }
202
 
203
        return PHP_VERSION;
204
    }
205
 
206
    /**
207
     * Returns true when the runtime used is PHP and Xdebug is loaded.
208
     */
209
    public function hasXdebug(): bool
210
    {
211
        return ($this->isPHP() || $this->isHHVM()) && extension_loaded('xdebug');
212
    }
213
 
214
    /**
215
     * Returns true when the runtime used is HHVM.
216
     */
217
    public function isHHVM(): bool
218
    {
219
        return defined('HHVM_VERSION');
220
    }
221
 
222
    /**
223
     * Returns true when the runtime used is PHP without the PHPDBG SAPI.
224
     */
225
    public function isPHP(): bool
226
    {
227
        return !$this->isHHVM() && !$this->isPHPDBG();
228
    }
229
 
230
    /**
231
     * Returns true when the runtime used is PHP with the PHPDBG SAPI.
232
     */
233
    public function isPHPDBG(): bool
234
    {
235
        return PHP_SAPI === 'phpdbg' && !$this->isHHVM();
236
    }
237
 
238
    /**
239
     * Returns true when the runtime used is PHP with the PHPDBG SAPI
240
     * and the phpdbg_*_oplog() functions are available (PHP >= 7.0).
241
     */
242
    public function hasPHPDBGCodeCoverage(): bool
243
    {
244
        return $this->isPHPDBG();
245
    }
246
 
247
    /**
248
     * Returns true when the runtime used is PHP with PCOV loaded and enabled.
249
     */
250
    public function hasPCOV(): bool
251
    {
252
        return $this->isPHP() && extension_loaded('pcov') && ini_get('pcov.enabled');
253
    }
254
 
255
    /**
256
     * Parses the loaded php.ini file (if any) as well as all
257
     * additional php.ini files from the additional ini dir for
258
     * a list of all configuration settings loaded from files
259
     * at startup. Then checks for each php.ini setting passed
260
     * via the `$values` parameter whether this setting has
261
     * been changed at runtime. Returns an array of strings
262
     * where each string has the format `key=value` denoting
263
     * the name of a changed php.ini setting with its new value.
264
     *
265
     * @return string[]
266
     */
267
    public function getCurrentSettings(array $values): array
268
    {
269
        $diff  = [];
270
        $files = [];
271
 
272
        if ($file = php_ini_loaded_file()) {
273
            $files[] = $file;
274
        }
275
 
276
        if ($scanned = php_ini_scanned_files()) {
277
            $files = array_merge(
278
                $files,
279
                array_map(
280
                    'trim',
281
                    explode(",\n", $scanned)
282
                )
283
            );
284
        }
285
 
286
        foreach ($files as $ini) {
287
            $config = parse_ini_file($ini, true);
288
 
289
            foreach ($values as $value) {
290
                $set = ini_get($value);
291
 
292
                if (empty($set)) {
293
                    continue;
294
                }
295
 
296
                if ((!isset($config[$value]) || ($set !== $config[$value]))) {
297
                    $diff[$value] = sprintf('%s=%s', $value, $set);
298
                }
299
            }
300
        }
301
 
302
        return $diff;
303
    }
304
 
305
    private function isOpcacheActive(): bool
306
    {
307
        if (!extension_loaded('Zend OPcache')) {
308
            return false;
309
        }
310
 
311
        if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && ini_get('opcache.enable_cli') === '1') {
312
            return true;
313
        }
314
 
315
        if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg' && ini_get('opcache.enable') === '1') {
316
            return true;
317
        }
318
 
319
        return false;
320
    }
321
}