Skip to content

Commit 78d6a57

Browse files
committed
Fix isXdebugActive if used before instantiation
1 parent 6555461 commit 78d6a57

4 files changed

Lines changed: 47 additions & 45 deletions

File tree

src/XdebugHandler.php

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ class XdebugHandler
4242
/** @var bool */
4343
private static $xdebugActive;
4444

45+
/** @var string|null */
46+
private static $xdebugMode;
47+
48+
/** @var string|null */
49+
private static $xdebugVersion;
50+
4551
/** @var bool */
4652
private $cli;
4753

@@ -54,12 +60,6 @@ class XdebugHandler
5460
/** @var string */
5561
private $envOriginalInis;
5662

57-
/** @var string|null */
58-
private $loaded;
59-
60-
/** @var string|null */
61-
private $mode;
62-
6363
/** @var bool */
6464
private $persistent;
6565

@@ -89,13 +89,7 @@ public function __construct($envPrefix)
8989
$this->envAllowXdebug = self::$name.self::SUFFIX_ALLOW;
9090
$this->envOriginalInis = self::$name.self::SUFFIX_INIS;
9191

92-
if (extension_loaded('xdebug')) {
93-
$version = phpversion('xdebug');
94-
$this->loaded = $version !== false ? $version : 'unknown';
95-
$this->mode = $this->getXdebugMode($this->loaded);
96-
}
97-
98-
self::$xdebugActive = $this->loaded !== null && $this->mode !== 'off';
92+
self::setXdebugDetails();
9993
self::$inRestart = false;
10094

10195
if ($this->cli = PHP_SAPI === 'cli') {
@@ -153,7 +147,7 @@ public function setPersistent()
153147
*/
154148
public function check()
155149
{
156-
$this->notify(Status::CHECK, $this->loaded.'|'.$this->mode);
150+
$this->notify(Status::CHECK, self::$xdebugVersion.'|'.self::$xdebugMode);
157151
$envArgs = explode('|', (string) getenv($this->envAllowXdebug));
158152

159153
if (!((bool) $envArgs[0]) && $this->requiresRestart(self::$xdebugActive)) {
@@ -174,7 +168,7 @@ public function check()
174168
Process::setEnv($this->envAllowXdebug);
175169
self::$inRestart = true;
176170

177-
if ($this->loaded === null) {
171+
if (self::$xdebugVersion === null) {
178172
// Skipped version is only set if Xdebug is not loaded
179173
self::$skipped = $envArgs[1];
180174
}
@@ -271,6 +265,7 @@ public static function getSkippedVersion()
271265
*/
272266
public static function isXdebugActive()
273267
{
268+
self::setXdebugDetails();
274269
return self::$xdebugActive;
275270
}
276271

@@ -492,7 +487,7 @@ private function setEnvironment($scannedInis, array $iniFiles)
492487
// Flag restarted process and save values for it to use
493488
$envArgs = array(
494489
self::RESTART_ID,
495-
$this->loaded,
490+
self::$xdebugVersion,
496491
(int) $scannedInis,
497492
false === $scanDir ? '*' : $scanDir,
498493
false === $phprc ? '*' : $phprc,
@@ -700,38 +695,50 @@ private function tryEnableSignals()
700695
}
701696

702697
/**
703-
* Returns the Xdebug mode if available
704-
*
705-
* @param string $version
698+
* Sets static properties $xdebugActive, $xdebugVersion and $xdebugMode
706699
*
707-
* @return string|null
700+
* @return void
708701
*/
709-
private function getXdebugMode($version)
702+
private static function setXdebugDetails()
710703
{
711-
if (version_compare($version, '3.1', '>=')) {
704+
if (self::$xdebugActive !== null) {
705+
return;
706+
}
707+
708+
self::$xdebugActive = false;
709+
if (!extension_loaded('xdebug')) {
710+
return;
711+
}
712+
713+
$version = phpversion('xdebug');
714+
self::$xdebugVersion = $version !== false ? $version : 'unknown';
715+
716+
if (version_compare(self::$xdebugVersion, '3.1', '>=')) {
712717
$modes = xdebug_info('mode');
713-
return count($modes) === 0 ? 'off' : implode(',', $modes);
718+
self::$xdebugMode = count($modes) === 0 ? 'off' : implode(',', $modes);
719+
self::$xdebugActive = self::$xdebugMode !== 'off';
720+
return;
714721
}
715722

716723
// See if xdebug.mode is supported in this version
717724
$iniMode = ini_get('xdebug.mode');
718725
if ($iniMode === false) {
719-
return null;
726+
return;
720727
}
721728

722729
// Environment value wins but cannot be empty
723730
$envMode = (string) getenv('XDEBUG_MODE');
724731
if ($envMode !== '') {
725-
$mode = $envMode;
732+
self::$xdebugMode = $envMode;
726733
} else {
727-
$mode = $iniMode !== '' ? $iniMode : 'off';
734+
self::$xdebugMode = $iniMode !== '' ? $iniMode : 'off';
728735
}
729736

730737
// An empty comma-separated list is treated as mode 'off'
731-
if (Preg::isMatch('/^,+$/', str_replace(' ', '', $mode))) {
732-
$mode = 'off';
738+
if (Preg::isMatch('/^,+$/', str_replace(' ', '', self::$xdebugMode))) {
739+
self::$xdebugMode = 'off';
733740
}
734741

735-
return $mode;
742+
self::$xdebugActive = self::$xdebugMode !== 'off';
736743
}
737744
}

tests/Helpers/BaseTestCase.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ protected function checkRestart($xdebug)
142142
self::assertSame(true, isset($_SERVER[CoreMock::ORIGINAL_INIS]));
143143

144144
// Skipped version must only be reported if it was unloaded in the restart
145-
if (!$xdebug->parentLoaded) {
145+
if ($xdebug->parentXdebugVersion === null) {
146146
// Mocked successful restart without Xdebug
147147
$version = '';
148148
} elseif ($xdebug instanceof FailMock) {

tests/Mocks/CoreMock.php

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class CoreMock extends XdebugHandler
3535
/** @var bool */
3636
public $restarted;
3737

38-
/** @var bool */
39-
public $parentLoaded;
38+
/** @var string|null */
39+
public $parentXdebugVersion;
4040

4141
/** @var null|static */
4242
protected $childProcess;
@@ -80,7 +80,7 @@ public static function createAndCheck($loaded, $parentProcess = null, $settings
8080
// properties on the parent and child
8181
$parentProcess->restarted = true;
8282
$xdebug->restarted = true;
83-
$xdebug->parentLoaded = $parentProcess->parentLoaded;
83+
$xdebug->parentXdebugVersion = $parentProcess->parentXdebugVersion;
8484

8585
// Make the child available
8686
$parentProcess->childProcess = $xdebug;
@@ -109,15 +109,15 @@ final public function __construct($loaded, $mode)
109109
parent::__construct('mock');
110110

111111
$this->refClass = new \ReflectionClass('Composer\XdebugHandler\XdebugHandler');
112-
$this->parentLoaded = $loaded ? static::TEST_VERSION : null;
112+
$this->parentXdebugVersion = $loaded ? static::TEST_VERSION : null;
113113

114-
// Set private loaded
115-
$prop = $this->refClass->getProperty('loaded');
114+
// Set private static xdebugVersion
115+
$prop = $this->refClass->getProperty('xdebugVersion');
116116
$prop->setAccessible(true);
117-
$prop->setValue($this, $this->parentLoaded);
117+
$prop->setValue($this, $this->parentXdebugVersion);
118118

119-
// Set private mode
120-
$prop = $this->refClass->getProperty('mode');
119+
// Set private static xdebugMode
120+
$prop = $this->refClass->getProperty('xdebugMode');
121121
$prop->setAccessible(true);
122122
$prop->setValue($this, $mode);
123123

@@ -131,11 +131,6 @@ final public function __construct($loaded, $mode)
131131
$prop->setAccessible(true);
132132
$prop->setValue($this, null);
133133

134-
// Ensure static private inRestart is unset
135-
$prop = $this->refClass->getProperty('inRestart');
136-
$prop->setAccessible(true);
137-
$prop->setValue($this, null);
138-
139134
$this->restarted = false;
140135
}
141136

tests/SettingsTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public function testSyncSettings()
8686
putenv(CoreMock::ORIGINAL_INIS);
8787
unset($_SERVER[CoreMock::ORIGINAL_INIS]);
8888

89-
// Mock not loaded ($inRestart and $skipped statics are unset)
89+
// Mock not loaded (static $skipped is unset in mock constructor)
9090
$loaded = false;
9191
CoreMock::createAndCheck($loaded);
9292

0 commit comments

Comments
 (0)