Source for file Config.php
Documentation is available at Config.php
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2004 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 3.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available through the world-wide-web at the following url: |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Stig Bakken <ssb@php.net> |
// +----------------------------------------------------------------------+
// $Id: Config.php,v 1.52 2004/01/08 17:33:12 sniper Exp $
require_once 'System.php';
* Last created PEAR_Config instance.
$GLOBALS['_PEAR_Config_instance'] = null;
if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR ) {
$PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear';
$PEAR_INSTALL_DIR = PEAR_INSTALL_DIR;
// Below we define constants with default values for all configuration
// parameters except username/password. All of them can have their
// defaults set through environment variables. The reason we use the
// PHP_ prefix is for some security, PHP protects environment
// variables starting with PHP_*.
if (getenv('PHP_PEAR_SYSCONF_DIR')) {
define('PEAR_CONFIG_SYSCONFDIR', getenv ('PHP_PEAR_SYSCONF_DIR'));
} elseif (getenv('SystemRoot')) {
define('PEAR_CONFIG_SYSCONFDIR', getenv ('SystemRoot'));
define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR );
// Default for master_server
if (getenv('PHP_PEAR_MASTER_SERVER')) {
define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv ('PHP_PEAR_MASTER_SERVER'));
define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net');
// Default for http_proxy
if (getenv('PHP_PEAR_HTTP_PROXY')) {
define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv ('PHP_PEAR_HTTP_PROXY'));
} elseif (getenv('http_proxy')) {
define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv ('http_proxy'));
define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', '');
if (getenv('PHP_PEAR_INSTALL_DIR')) {
define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv ('PHP_PEAR_INSTALL_DIR'));
if (@is_dir($PEAR_INSTALL_DIR)) {
define('PEAR_CONFIG_DEFAULT_PHP_DIR',
define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
if (getenv('PHP_PEAR_EXTENSION_DIR')) {
define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv ('PHP_PEAR_EXTENSION_DIR'));
define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get ('extension_dir'));
} elseif (defined('PEAR_EXTENSION_DIR') && @is_dir(PEAR_EXTENSION_DIR )) {
define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR );
} elseif (defined('PHP_EXTENSION_DIR')) {
define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR );
define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.');
if (getenv('PHP_PEAR_DOC_DIR')) {
define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv ('PHP_PEAR_DOC_DIR'));
define('PEAR_CONFIG_DEFAULT_DOC_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR. 'docs');
if (getenv('PHP_PEAR_BIN_DIR')) {
define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv ('PHP_PEAR_BIN_DIR'));
define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR );
if (getenv('PHP_PEAR_DATA_DIR')) {
define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv ('PHP_PEAR_DATA_DIR'));
define('PEAR_CONFIG_DEFAULT_DATA_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR. 'data');
if (getenv('PHP_PEAR_TEST_DIR')) {
define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv ('PHP_PEAR_TEST_DIR'));
define('PEAR_CONFIG_DEFAULT_TEST_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR. 'tests');
if (getenv('PHP_PEAR_CACHE_DIR')) {
define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv ('PHP_PEAR_CACHE_DIR'));
define('PEAR_CONFIG_DEFAULT_CACHE_DIR',
System ::tmpdir () . DIRECTORY_SEPARATOR . 'pear' .
DIRECTORY_SEPARATOR . 'cache');
if (getenv('PHP_PEAR_PHP_BIN')) {
define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv ('PHP_PEAR_PHP_BIN'));
define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR.
DIRECTORY_SEPARATOR. 'php'. (OS_WINDOWS ? '.exe' : ''));
if (getenv('PHP_PEAR_VERBOSE')) {
define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv ('PHP_PEAR_VERBOSE'));
define('PEAR_CONFIG_DEFAULT_VERBOSE', 1 );
// Default for preferred_state
if (getenv('PHP_PEAR_PREFERRED_STATE')) {
define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv ('PHP_PEAR_PREFERRED_STATE'));
define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable');
if (getenv('PHP_PEAR_UMASK')) {
define('PEAR_CONFIG_DEFAULT_UMASK', getenv ('PHP_PEAR_UMASK'));
define('PEAR_CONFIG_DEFAULT_UMASK', decoct (umask ()));
if (getenv('PHP_PEAR_CACHE_TTL')) {
define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv ('PHP_PEAR_CACHE_TTL'));
define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600 );
if (getenv('PHP_PEAR_SIG_TYPE')) {
define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv ('PHP_PEAR_SIG_TYPE'));
define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg');
if (getenv('PHP_PEAR_SIG_BIN')) {
define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv ('PHP_PEAR_SIG_BIN'));
define('PEAR_CONFIG_DEFAULT_SIG_BIN',
'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg'));
// Default for sig_keydir
if (getenv('PHP_PEAR_SIG_KEYDIR')) {
define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv ('PHP_PEAR_SIG_KEYDIR'));
define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR',
PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys');
* This is a class for storing configuration data, keeping track of
* which are system-defined, user-defined or defaulted.
class PEAR_Config extends PEAR
* Array of config files used.
* @var array layer => config file
* Configuration data, two-dimensional array where the first
* dimension is the config layer ('user', 'system' and 'default'),
* and the second dimension is keyname => value.
* The order in the first dimension is important! Earlier
* layers will shadow later ones when a config value is
* requested (if a 'user' value exists, it will be returned first,
* then 'system' and finally 'default').
* @var array layer => array(keyname => value, ...)
var $configuration = array (
* Information about the configuration data. Stores the type,
* default value and a documentation string for each configuration
* @var array layer => array(infotype => value, ...)
var $configuration_info = array (
'master_server' => array (
'default' => 'pear.php.net',
'doc' => 'name of the main PEAR server',
'prompt' => 'PEAR server',
'group' => 'Internet Access',
'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY ,
'doc' => 'HTTP proxy (host:port) to use when downloading packages',
'prompt' => 'HTTP Proxy Server Address',
'group' => 'Internet Access',
'default' => PEAR_CONFIG_DEFAULT_PHP_DIR ,
'doc' => 'directory where .php files are installed',
'prompt' => 'PEAR directory',
'group' => 'File Locations',
'default' => PEAR_CONFIG_DEFAULT_EXT_DIR ,
'doc' => 'directory where loadable extensions are installed',
'prompt' => 'PHP extension directory',
'group' => 'File Locations',
'default' => PEAR_CONFIG_DEFAULT_DOC_DIR ,
'doc' => 'directory where documentation is installed',
'prompt' => 'PEAR documentation directory',
'group' => 'File Locations',
'default' => PEAR_CONFIG_DEFAULT_BIN_DIR ,
'doc' => 'directory where executables are installed',
'prompt' => 'PEAR executables directory',
'group' => 'File Locations',
'default' => PEAR_CONFIG_DEFAULT_DATA_DIR ,
'doc' => 'directory where data files are installed',
'prompt' => 'PEAR data directory',
'group' => 'File Locations (Advanced)',
'default' => PEAR_CONFIG_DEFAULT_TEST_DIR ,
'doc' => 'directory where regression tests are installed',
'prompt' => 'PEAR test directory',
'group' => 'File Locations (Advanced)',
'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR ,
'doc' => 'directory which is used for XMLRPC cache',
'prompt' => 'PEAR Installer cache directory',
'group' => 'File Locations (Advanced)',
'default' => PEAR_CONFIG_DEFAULT_PHP_BIN ,
'doc' => 'PHP CLI/CGI binary for executing scripts',
'prompt' => 'PHP CLI/CGI binary',
'group' => 'File Locations (Advanced)',
'doc' => '(maintainers) your PEAR account name',
'prompt' => 'PEAR username (for maintainers)',
'group' => 'Maintainers',
'doc' => '(maintainers) your PEAR account password',
'prompt' => 'PEAR password (for maintainers)',
'group' => 'Maintainers',
'default' => PEAR_CONFIG_DEFAULT_VERBOSE ,
'doc' => 'verbosity level
'prompt' => 'Debug Log Level',
'preferred_state' => array (
'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE ,
'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified',
'stable', 'beta', 'alpha', 'devel', 'snapshot'),
'prompt' => 'Preferred Package State',
'default' => PEAR_CONFIG_DEFAULT_UMASK ,
'doc' => 'umask used when creating files (Unix-like systems only)',
'prompt' => 'Unix file mask',
'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL ,
'doc' => 'amount of secs where the local cache is used and not updated',
'prompt' => 'Cache TimeToLive',
'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE ,
'doc' => 'which package signature mechanism to use',
'valid_set' => array ('gpg'),
'prompt' => 'Package Signature Type',
'group' => 'Maintainers',
'default' => PEAR_CONFIG_DEFAULT_SIG_BIN ,
'doc' => 'which package signature mechanism to use',
'prompt' => 'Signature Handling Program',
'group' => 'Maintainers',
'doc' => 'which key to use for signing with',
'prompt' => 'Signature Key Id',
'group' => 'Maintainers',
'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR ,
'doc' => 'which package signature mechanism to use',
'prompt' => 'Signature Key Directory',
'group' => 'Maintainers',
// {{{ PEAR_Config([file], [defaults_file])
* @param string (optional) file to read user-defined options from
* @param string (optional) file to read system-wide defaults from
* @see PEAR_Config::singleton
function PEAR_Config ($user_file = '', $system_file = '')
$sl = DIRECTORY_SEPARATOR;
$user_file = getenv('HOME') . $sl . '.pearrc';
if (empty ($system_file)) {
$this->files['user'] = $user_file;
$this->files['system'] = $system_file;
$this->readConfigFile ($user_file);
$this->mergeConfigFile ($system_file, false , 'system');
foreach ($this->configuration_info as $key => $info) {
$this->configuration['default'][$key] = $info['default'];
//$GLOBALS['_PEAR_Config_instance'] = &$this;
// {{{ singleton([file], [defaults_file])
* Static singleton method. If you want to keep only one instance
* of this class in use, this method will give you a reference to
* the last created PEAR_Config object if one exists, or create a
* @param string (optional) file to read user-defined options from
* @param string (optional) file to read system-wide defaults from
* @return object an existing or new PEAR_Config instance
* @see PEAR_Config::PEAR_Config
function &singleton ($user_file = '', $system_file = '')
if (is_object($GLOBALS['_PEAR_Config_instance'])) {
return $GLOBALS['_PEAR_Config_instance'];
$GLOBALS['_PEAR_Config_instance'] =
&new PEAR_Config ($user_file, $system_file);
return $GLOBALS['_PEAR_Config_instance'];
// {{{ readConfigFile([file], [layer])
* Reads configuration data from a file. All existing values in
* the config layer are discarded and replaced with data from the
* @param string (optional) file to read from, if NULL or not
* specified, the last-used file for the same layer (second param)
* @param string (optional) config layer to insert data into
* @return bool TRUE on success or a PEAR error on failure
function readConfigFile ($file = null , $layer = 'user')
if (empty ($this->files[$layer])) {
return $this->raiseError (" unknown config file type `$layer'" );
$file = $this->files[$layer];
$data = $this->_readConfigDataFrom ($file);
if (PEAR ::isError ($data)) {
$this->_decodeInput ($data);
$this->configuration[$layer] = $data;
// {{{ mergeConfigFile(file, [override], [layer])
* Merges data into a config layer from a file. Does the same
* thing as readConfigFile, except it does not replace all
* existing values in the config layer.
* @param string file to read from
* @param bool (optional) whether to overwrite existing data
* @param string config layer to insert data into ('user' or
* @return bool TRUE on success or a PEAR error on failure
function mergeConfigFile ($file, $override = true , $layer = 'user')
if (empty ($this->files[$layer])) {
return $this->raiseError (" unknown config file type `$layer'" );
$file = $this->files[$layer];
$data = $this->_readConfigDataFrom ($file);
if (PEAR ::isError ($data)) {
$this->_decodeInput ($data);
$this->configuration[$layer] = array_merge($this->configuration[$layer], $data);
$this->configuration[$layer] = array_merge($data, $this->configuration[$layer]);
// {{{ writeConfigFile([file], [layer])
* Writes data into a config layer from a file.
* @param string file to read from
* @param bool (optional) whether to overwrite existing data
* @param string config layer to insert data into ('user' or
* @return bool TRUE on success or a PEAR error on failure
function writeConfigFile ($file = null , $layer = 'user', $data = null )
if ($layer == 'both' || $layer == 'all') {
foreach ($this->files as $type => $file) {
$err = $this->writeConfigFile ($file, $type, $data);
if (PEAR ::isError ($err)) {
if (empty ($this->files[$layer])) {
return $this->raiseError (" unknown config file type `$layer'" );
$file = $this->files[$layer];
$data = ($data === null ) ? $this->configuration[$layer] : $data;
$this->_encodeOutput ($data);
$opt = array ('-p', dirname($file));
return $this->raiseError ("could not create directory: " . dirname($file));
return $this->raiseError (" no write access to $file!" );
$fp = @fopen($file, "w");
return $this->raiseError (" PEAR_Config::writeConfigFile fopen('$file','w') failed" );
$contents = "#PEAR_Config 0.9\n" . serialize($data);
if (!@fwrite($fp, $contents)) {
return $this->raiseError ("PEAR_Config::writeConfigFile: fwrite failed");
// {{{ _readConfigDataFrom(file)
* Reads configuration data from a file and returns the parsed data
* @param string file to read from
* @return array configuration data or a PEAR error on failure
function _readConfigDataFrom ($file)
$fp = @fopen($file, "r");
return $this->raiseError (" PEAR_Config::readConfigFile fopen('$file','r') failed" );
$contents = fread($fp, $size);
if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) {
$error = " PEAR_Config: bad data in $file";
return $this->raiseError ($error);
// return PEAR::raiseError($error);
// add parsing of newer formats here...
return $this->raiseError (" $file: unknown version `$version'" );
// {{{ getConfFile(layer)
* Gets the file used for storing the config for a layer
* @param string $layer 'user' or 'system'
function getConfFile ($layer)
return $this->files[$layer];
// {{{ _encodeOutput(&data)
* Encodes/scrambles configuration data before writing to files.
* Currently, 'password' values will be base64-encoded as to avoid
* that people spot cleartext passwords by accident.
* @param array (reference) array to encode values in
* @return bool TRUE on success
function _encodeOutput (&$data)
foreach ($data as $key => $value) {
if (!isset ($this->configuration_info[$key])) {
$type = $this->configuration_info[$key]['type'];
// we base64-encode passwords so they are at least
// not shown in plain by accident
$data[$key] = octdec($data[$key]);
// {{{ _decodeInput(&data)
* Decodes/unscrambles configuration data after reading from files.
* @param array (reference) array to encode values in
* @return bool TRUE on success
* @see PEAR_Config::_encodeOutput
function _decodeInput (&$data)
foreach ($data as $key => $value) {
if (!isset ($this->configuration_info[$key])) {
$type = $this->configuration_info[$key]['type'];
$data[$key] = decoct($data[$key]);
* Returns a configuration value, prioritizing layers as per the
* @param string config key
* @return mixed the config value, or NULL if not found
function get ($key, $layer = null )
foreach ($this->layers as $layer) {
if (isset ($this->configuration[$layer][$key])) {
return $this->configuration[$layer][$key];
} elseif (isset ($this->configuration[$layer][$key])) {
return $this->configuration[$layer][$key];
// {{{ set(key, value, [layer])
* Set a config value in a specific layer (defaults to 'user').
* Enforces the types defined in the configuration_info array. An
* integer config variable will be cast to int, and a set config
* variable will be validated against its legal values.
* @param string config key
* @param string config value
* @param string (optional) config layer
* @return bool TRUE on success, FALSE on failure
function set ($key, $value, $layer = 'user')
if (empty ($this->configuration_info[$key])) {
extract($this->configuration_info[$key]);
// If a valid_set is specified, require the value to
// be in the set. If there is no valid_set, accept
if ((key($valid_set) === 0 && !in_array($value, $valid_set)) ||
(key($valid_set) !== 0 && empty ($valid_set[$value])))
$this->configuration[$layer][$key] = $value;
* Get the type of a config value.
* @param string config key
* @return string type, one of "string", "integer", "file",
* "directory", "set" or "password".
if (isset ($this->configuration_info[$key])) {
return $this->configuration_info[$key]['type'];
* Get the documentation for a config value.
* @param string config key
* @return string documentation string
if (isset ($this->configuration_info[$key])) {
return $this->configuration_info[$key]['doc'];
* Get the short documentation for a config value.
* @param string config key
* @return string short documentation string
if (isset ($this->configuration_info[$key])) {
return $this->configuration_info[$key]['prompt'];
* Get the parameter group for a config key.
* @param string config key
* @return string parameter group
if (isset ($this->configuration_info[$key])) {
return $this->configuration_info[$key]['group'];
* Get the list of parameter groups.
* @return array list of parameter groups
foreach ($this->configuration_info as $key => $info) {
$tmp[$info['group']] = 1;
* Get the list of the parameters in a group.
* @param string $group parameter group
* @return array list of parameters in $group
function getGroupKeys ($group)
foreach ($this->configuration_info as $key => $info) {
if ($info['group'] == $group) {
* Get the list of allowed set values for a config value. Returns
* NULL for config values that are not sets.
* @param string config key
* @return array enumerated array of set values, or NULL if the
* config key is unknown or not a set
function getSetValues ($key)
if (isset ($this->configuration_info[$key]) &&
isset ($this->configuration_info[$key]['type']) &&
$this->configuration_info[$key]['type'] == 'set')
$valid_set = $this->configuration_info[$key]['valid_set'];
if (key($valid_set) === 0 ) {
* Get all the current config keys.
* @return array simple array of config keys
foreach ($this->layers as $layer) {
$keys = array_merge($keys, $this->configuration[$layer]);
// {{{ remove(key, [layer])
* Remove the a config key from a specific config layer.
* @param string config key
* @param string (optional) config layer
* @return bool TRUE on success, FALSE on failure
function remove ($key, $layer = 'user')
if (isset ($this->configuration[$layer][$key])) {
unset ($this->configuration[$layer][$key]);
// {{{ removeLayer(layer)
* Temporarily remove an entire config layer. USE WITH CARE!
* @param string config key
* @param string (optional) config layer
* @return bool TRUE on success, FALSE on failure
function removeLayer ($layer)
if (isset ($this->configuration[$layer])) {
$this->configuration[$layer] = array ();
* Stores configuration data in a layer.
* @param string config layer to store
* @return bool TRUE on success, or PEAR error on failure
function store ($layer = 'user', $data = null )
return $this->writeConfigFile (null , $layer, $data);
* Unset the user-defined value of a config key, reverting the
* value to the system-defined one.
* @param string config key
* @return bool TRUE on success, FALSE on failure
trigger_error("PEAR_Config::toDefault() deprecated, use PEAR_Config::remove() instead", E_USER_NOTICE );
return $this->remove ($key, 'user');
* Tells what config layer that gets to define a key.
* @param string config key
* @return string the config layer, or an empty string if not found
foreach ($this->layers as $layer) {
if (isset ($this->configuration[$layer][$key])) {
* Tells whether a config value has a system-defined value.
* @param string config key
function isDefaulted ($key)
trigger_error("PEAR_Config::isDefaulted() deprecated, use PEAR_Config::definedBy() instead", E_USER_NOTICE );
return $this->definedBy ($key) == 'system';
* Tells whether a given key exists as a config value.
* @param string config key
* @return bool whether <config key> exists in this object
foreach ($this->layers as $layer) {
if (isset ($this->configuration[$layer][$key])) {
// {{{ isDefinedLayer(key)
* Tells whether a given config layer exists.
* @param string config layer
* @return bool whether <config layer> exists in this object
function isDefinedLayer ($layer)
return isset ($this->configuration[$layer]);
* Returns the layers defined (except the 'default' one)
* @return array of the defined layers
$cf = $this->configuration;
Documentation generated on Mon, 11 Mar 2019 14:23:56 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|