diff --git a/bin/composer b/bin/composer
index ca6ecc6b5..385508e75 100755
--- a/bin/composer
+++ b/bin/composer
@@ -10,6 +10,7 @@ require __DIR__.'/../src/bootstrap.php';
use Composer\Console\Application;
use Composer\XdebugHandler\XdebugHandler;
+use Composer\Util\Platform;
error_reporting(-1);
@@ -57,8 +58,7 @@ if (function_exists('ini_set')) {
unset($memoryLimit);
}
-$_SERVER['COMPOSER_BINARY'] = realpath($_SERVER['argv'][0]);
-putenv('COMPOSER_BINARY='.$_SERVER['COMPOSER_BINARY']);
+Platform::setEnv('COMPOSER_BINARY', realpath($_SERVER['argv'][0]));
// run the command application
$application = new Application();
diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php
index 8d7bd73a4..474efcbd5 100644
--- a/src/Composer/Autoload/AutoloadGenerator.php
+++ b/src/Composer/Autoload/AutoloadGenerator.php
@@ -24,6 +24,7 @@ use Composer\Repository\PlatformRepository;
use Composer\Semver\Constraint\Bound;
use Composer\Semver\Constraint\MatchAllConstraint;
use Composer\Util\Filesystem;
+use Composer\Util\Platform;
use Composer\Script\ScriptEvents;
use Composer\Util\PackageSorter;
use Composer\Json\JsonFile;
@@ -158,8 +159,7 @@ class AutoloadGenerator
// set COMPOSER_DEV_MODE in case not set yet so it is available in the dump-autoload autoload
if (!isset($_SERVER['COMPOSER_DEV_MODE'])) {
- $_SERVER['COMPOSER_DEV_MODE'] = $this->devMode ? '1' : '0';
- putenv('COMPOSER_DEV_MODE='.$_SERVER['COMPOSER_DEV_MODE']);
+ Platform::putEnv('COMPOSER_DEV_MODE', $this->devMode ? '1' : '0');
}
$this->eventDispatcher->dispatchScript(ScriptEvents::PRE_AUTOLOAD_DUMP, $this->devMode, array(), array(
diff --git a/src/Composer/Command/CreateProjectCommand.php b/src/Composer/Command/CreateProjectCommand.php
index 4734f9cab..9bdd33ae3 100644
--- a/src/Composer/Command/CreateProjectCommand.php
+++ b/src/Composer/Command/CreateProjectCommand.php
@@ -37,6 +37,7 @@ use Symfony\Component\Finder\Finder;
use Composer\Json\JsonFile;
use Composer\Config\JsonConfigSource;
use Composer\Util\Filesystem;
+use Composer\Util\Platform;
use Composer\Util\ProcessExecutor;
use Composer\Package\Version\VersionParser;
@@ -453,8 +454,7 @@ EOT
$io->writeError('Created project in ' . $directory . '');
chdir($directory);
- $_SERVER['COMPOSER_ROOT_VERSION'] = $package->getPrettyVersion();
- putenv('COMPOSER_ROOT_VERSION='.$_SERVER['COMPOSER_ROOT_VERSION']);
+ Platform::putEnv('COMPOSER_ROOT_VERSION', $package->getPrettyVersion());
return $installedFromVcs;
}
diff --git a/src/Composer/Command/GlobalCommand.php b/src/Composer/Command/GlobalCommand.php
index 96a6b5f5e..c78ea7109 100644
--- a/src/Composer/Command/GlobalCommand.php
+++ b/src/Composer/Command/GlobalCommand.php
@@ -14,6 +14,7 @@ namespace Composer\Command;
use Composer\Factory;
use Composer\Util\Filesystem;
+use Composer\Util\Platform;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\StringInput;
@@ -81,8 +82,7 @@ EOT
// The COMPOSER env var should not apply to the global execution scope
if (getenv('COMPOSER')) {
- putenv('COMPOSER');
- unset($_SERVER['COMPOSER']);
+ Platform::clearEnv('COMPOSER');
}
// change to global dir
diff --git a/src/Composer/Command/RunScriptCommand.php b/src/Composer/Command/RunScriptCommand.php
index c45507b1f..1ecf1e0c1 100644
--- a/src/Composer/Command/RunScriptCommand.php
+++ b/src/Composer/Command/RunScriptCommand.php
@@ -15,6 +15,7 @@ namespace Composer\Command;
use Composer\Script\Event as ScriptEvent;
use Composer\Script\ScriptEvents;
use Composer\Util\ProcessExecutor;
+use Composer\Util\Platform;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
@@ -103,8 +104,7 @@ EOT
ProcessExecutor::setTimeout((int) $timeout);
}
- $_SERVER['COMPOSER_DEV_MODE'] = $devMode ? '1' : '0';
- putenv('COMPOSER_DEV_MODE='.$_SERVER['COMPOSER_DEV_MODE']);
+ Platform::putEnv('COMPOSER_DEV_MODE', $devMode ? '1' : '0');
return $composer->getEventDispatcher()->dispatchScript($script, $devMode, $args);
}
diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php
index bdb8700aa..177f7220a 100644
--- a/src/Composer/Console/Application.php
+++ b/src/Composer/Console/Application.php
@@ -143,8 +143,7 @@ class Application extends BaseApplication
if ($input->hasParameterOption('--no-cache')) {
$io->writeError('Disabling cache usage', true, IOInterface::DEBUG);
- $_SERVER['COMPOSER_CACHE_DIR'] = Platform::isWindows() ? 'nul' : '/dev/null';
- putenv('COMPOSER_CACHE_DIR='.$_SERVER['COMPOSER_CACHE_DIR']);
+ Platform::putEnv('COMPOSER_CACHE_DIR', Platform::isWindows() ? 'nul' : '/dev/null');
}
// switch working dir
diff --git a/src/Composer/EventDispatcher/EventDispatcher.php b/src/Composer/EventDispatcher/EventDispatcher.php
index a18112c4b..5a06314d8 100644
--- a/src/Composer/EventDispatcher/EventDispatcher.php
+++ b/src/Composer/EventDispatcher/EventDispatcher.php
@@ -247,9 +247,12 @@ class EventDispatcher
}
if (strpos($exec, '@putenv ') === 0) {
- putenv(substr($exec, 8));
- list($var, $value) = explode('=', substr($exec, 8), 2);
- $_SERVER[$var] = $value;
+ if (false === strpos($exec, '=')) {
+ Platform::clearEnv(substr($exec, 8));
+ } else {
+ list($var, $value) = explode('=', substr($exec, 8), 2);
+ Platform::putEnv($var, $value);
+ }
continue;
}
@@ -274,8 +277,7 @@ class EventDispatcher
$finder = new PhpExecutableFinder();
$phpPath = $finder->find(false);
if ($phpPath) {
- $_SERVER['PHP_BINARY'] = $phpPath;
- putenv('PHP_BINARY=' . $_SERVER['PHP_BINARY']);
+ Platform::putEnv('PHP_BINARY', $phpPath);
}
if (Platform::isWindows()) {
@@ -539,8 +541,7 @@ class EventDispatcher
if (is_dir($binDir)) {
$binDir = realpath($binDir);
if (isset($_SERVER[$pathStr]) && !preg_match('{(^|'.PATH_SEPARATOR.')'.preg_quote($binDir).'($|'.PATH_SEPARATOR.')}', $_SERVER[$pathStr])) {
- $_SERVER[$pathStr] = $binDir.PATH_SEPARATOR.getenv($pathStr);
- putenv($pathStr.'='.$_SERVER[$pathStr]);
+ Platform::putEnv($pathStr, $binDir.PATH_SEPARATOR.getenv($pathStr));
}
}
}
diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php
index 8e2a49367..c803edfdf 100644
--- a/src/Composer/Installer.php
+++ b/src/Composer/Installer.php
@@ -56,6 +56,7 @@ use Composer\Repository\RepositoryInterface;
use Composer\Repository\RepositoryManager;
use Composer\Repository\LockArrayRepository;
use Composer\Script\ScriptEvents;
+use Composer\Util\Platform;
/**
* @author Jordi Boggiano
@@ -224,8 +225,7 @@ class Installer
}
if ($this->runScripts) {
- $_SERVER['COMPOSER_DEV_MODE'] = $this->devMode ? '1' : '0';
- putenv('COMPOSER_DEV_MODE='.$_SERVER['COMPOSER_DEV_MODE']);
+ Platform::putEnv('COMPOSER_DEV_MODE', $this->devMode ? '1' : '0');
// dispatch pre event
// should we treat this more strictly as running an update and then running an install, triggering events multiple times?
diff --git a/src/Composer/Util/Git.php b/src/Composer/Util/Git.php
index 3290c6d85..67d42b7c2 100644
--- a/src/Composer/Util/Git.php
+++ b/src/Composer/Util/Git.php
@@ -353,29 +353,24 @@ class Git
// added in git 1.7.1, prevents prompting the user for username/password
if (getenv('GIT_ASKPASS') !== 'echo') {
- putenv('GIT_ASKPASS=echo');
- $_SERVER['GIT_ASKPASS'] = 'echo';
+ Platform::putEnv('GIT_ASKPASS', 'echo');
}
// clean up rogue git env vars in case this is running in a git hook
if (getenv('GIT_DIR')) {
- putenv('GIT_DIR');
- unset($_SERVER['GIT_DIR']);
+ Platform::clearEnv('GIT_DIR');
}
if (getenv('GIT_WORK_TREE')) {
- putenv('GIT_WORK_TREE');
- unset($_SERVER['GIT_WORK_TREE']);
+ Platform::clearEnv('GIT_WORK_TREE');
}
// Run processes with predictable LANGUAGE
if (getenv('LANGUAGE') !== 'C') {
- putenv('LANGUAGE=C');
- $_SERVER['LANGUAGE'] = 'C';
+ Platform::putEnv('LANGUAGE', 'C');
}
// clean up env for OSX, see https://github.com/composer/composer/issues/2146#issuecomment-35478940
- putenv("DYLD_LIBRARY_PATH");
- unset($_SERVER['DYLD_LIBRARY_PATH']);
+ Platform::clearEnv('DYLD_LIBRARY_PATH');
}
public static function getGitHubDomainsRegex(Config $config)
diff --git a/src/Composer/Util/Platform.php b/src/Composer/Util/Platform.php
index 5693247c8..deca14db2 100644
--- a/src/Composer/Util/Platform.php
+++ b/src/Composer/Util/Platform.php
@@ -24,6 +24,33 @@ class Platform
/** @var ?bool */
private static $isWindowsSubsystemForLinux = null;
+ /**
+ * putenv() equivalent but updates the runtime global variables too
+ *
+ * @param string $name
+ * @param string $value
+ * @return void
+ */
+ public function putEnv($name, $value)
+ {
+ $value = (string) $value;
+ putenv($name . '=' . $value);
+ $_SERVER[$name] = $_ENV[$name] = $value;
+ }
+
+ /**
+ * putenv('X') equivalent but updates the runtime global variables too
+ *
+ * @param string $name
+ * @param string $value
+ * @return void
+ */
+ public function clearEnv($name)
+ {
+ putenv($name);
+ unset($_SERVER[$name], $_ENV[$name]);
+ }
+
/**
* Parses tildes and environment variables in paths.
*
diff --git a/src/Composer/Util/Svn.php b/src/Composer/Util/Svn.php
index da934c161..2f7d070ab 100644
--- a/src/Composer/Util/Svn.php
+++ b/src/Composer/Util/Svn.php
@@ -85,8 +85,7 @@ class Svn
public static function cleanEnv()
{
// clean up env for OSX, see https://github.com/composer/composer/issues/2146#issuecomment-35478940
- putenv("DYLD_LIBRARY_PATH");
- unset($_SERVER['DYLD_LIBRARY_PATH']);
+ Platform::clearEnv('DYLD_LIBRARY_PATH');
}
/**
diff --git a/tests/Composer/Test/ApplicationTest.php b/tests/Composer/Test/ApplicationTest.php
index 31fdcd1ec..f3fb28ab2 100644
--- a/tests/Composer/Test/ApplicationTest.php
+++ b/tests/Composer/Test/ApplicationTest.php
@@ -18,6 +18,13 @@ use Symfony\Component\Console\Output\OutputInterface;
class ApplicationTest extends TestCase
{
+ public function tearDown()
+ {
+ parent::tearDown();
+
+ putenv('COMPOSER_NO_INTERACTION');
+ }
+
public function testDevWarning()
{
$application = new Application;