我想弄清楚我想如何处理我的PHP应用程序中的设置。我几乎决定使用Confg类文件,以便将来自动加载和灵活。以下是我正在玩的一些东西。
我知道你不能设置一个变量来弹出一个常量,所以我尝试使用一个公共静态属性。
为什么我不能设置 public static $ ip = $ _SERVER ['REMOTE_ADDR']; ??
<?php
// config.class.php
class Config
{
const URL = 'http://www.foo.com';
const DB_User = 'dbname';
public static $test = 'test string';
public static $ip = $_SERVER['REMOTE_ADDR'];
}
///////////////////////////////////////////////////////
//index.php
// works
echo Config::URL;
// works
echo Config::$test;
// DOES NOT WORK
echo Config::$ip;
?>
答案 0 :(得分:3)
成员。如果您尝试使用动态表达式初始化成员(如变量或函数调用的值),PHP将给出解析错误...
这与其他一些lang类似,比如python或者javascript,它们认为类定义与可执行表达式相同......所以你的想法非常实用,但php现在至少不支持它...... / p>
但有一些替代方法可以解决这个问题:
在类定义后添加初始化:
class C {...}
C::$var = $_SERVER['REMOTE_ADDR'];
或者有一个init函数:
function init()
{
if (self::$init === false) {
self::$var = $_SERVER['REMOTE_ADDR'];
self::$init = true;
}
}
C::init();
或者使用较新的php,您可以使用__autoload()钩子进行一些静态初始化...
答案 1 :(得分:2)
虽然这不能回答你的问题(jspcal正确回答),但是一个可能符合你需求的快速解决方案会使用Singleton design pattern。这是另一种选择:
<?php
// config.class.php
class Config
{
/**
* Instance container
* @var Config
*/
private static $instance = null;
/**
* Constants container
* @var array
*/
private $constants = array(
'url' => 'http://www.foo.com/',
'db_user' => 'dbname'
);
/**
* Options container
* @var array
*/
private $options = array();
/**
* Don't allow outside initialization
*/
private function __construct()
{
// Set options (could load from external source)
$this->options = array(
'test' => 'test string',
'ip' => $_SERVER['REMOTE_ADDR']
);
}
/**
* Disable cloning
*/
private function __clone() { }
/**
* Get new instance of class
*/
public function getInstance()
{
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Retrieve value with constants being a higher priority
* @param $key Key to get
*/
public function __get( $key )
{
if ( isset( $this->constants[$key] ) ) {
return $this->constants[$key];
} elseif ( isset( $this->options[$key] ) ) {
return $this->options[$key];
}
}
/**
* Set a new or update a key / value pair
* @param $key Key to set
* @param $value Value to set
*/
public function __set( $key, $value )
{
$this->options[$key] = $value;
}
}
///////////////////////////////////////////////////////
//index.php
// works
$config = Config::getInstance();
echo $config->url;
echo $config->test;
echo $config->ip;
更新:不确定您是否希望常量/选项具有此类优先级。这只是一个例子。
答案 2 :(得分:2)
尝试使用define()来做(给一个常量!):
// config.class.php
define(REMOTE_ADDR, $_SERVER['REMOTE_ADDR']);
class Config
{
const URL = 'http://www.foo.com';
const DB_User = 'dbname';
public static $test = 'test string';
public static $ip = REMOTE_ADDR;
}
答案 3 :(得分:1)
不能直接回答您的问题,但为什么不使用较少硬编码的方法,例如:您可以在应用中重复使用的通用配置类
// MyConfig.php
class MyConfig {
protected $_data;
public function __construct($path)
{
$config = include $path;
$this->_data = $config;
}
public function __get($val)
{
if(array_key_exists($val, $this->_data)) {
return $this->_data['val'];
} else {
trigger_error("Key $val does not exist", E_USER_NOTICE);
}
}
}
您可以从特定应用的数组中填写
// app-config.php
return array(
'ip' => $_SERVER['REMOTE_ADDR'],
'url' => 'http://www.foo.com';
'db' => array(
'host' => 'foo.com',
'port' => 3306
),
'caching' => array(
'enabled' => false
)
);
然后在你的引导程序中使用,如
$config = new MyConfig('/path/to/app-config.php');
答案 4 :(得分:1)
这不是回答你的问题,但在我看来,处理配置的更好方法实际上是使用真正的配置文件,如INI或XML文件。
您可以使用例如Zend Config类来读取和写入这样的文件(这个类甚至可以处理普通的PHP数组作为配置。
最后,这将使您的代码更易于维护。
在阅读其他答案和评论后,您可能也会对Zend Registry课程感兴趣。
一般来说,我建议使用框架或现成的组件来做这些事情。你不需要重新发明轮子,你可以从对方的经验中获益。
答案 5 :(得分:0)
它不起作用,因为PHP不允许它。
一般情况下,我不会建议将你的应用程序的配置放到一个类中(至少不是在PHP中),我认为没有真正的优势 - 最好将它放入全局数组中:)
答案 6 :(得分:0)
PHP根本不允许这样做。如果你考虑一下,将REMOTE_ADDR作为配置数据的一部分是没有意义的。您可以将其视为请求数据的一部分,而不是应用程序配置。
至于您的配置,我建议您使用.ini文件进行配置,因为PHP有一个内置的INI解析器(请参阅parse_ini_file函数)。这与PHP为自己的配置(即php.ini)选择的INI文件格式一致。
查看此问题,例如:What's Is the Best File Format for Configuration Files
答案 7 :(得分:0)
不能将 $_SERVER['REMOTE_ADDR'] 分配给 class 属性的简单原因是这个。
在 PHP 中,Class 属性值只能是数据类型,不能是变量,而且由于 $_SERVER 是全局数组变量,所以不能赋值给属性。