我在优化PHP脚本时遇到问题。例如:
MySQL表:
option_name || option_value ===================================================== base_url || http://mysite.com/myproject theme_name || default language || en
MyScript.php文件:
class options {
private $options = null;
public function get($optionName) {
if(!isset($this->options))
self::get_data();
return $this->options[$optionName];
}
protected function get_Data() {
// ...
// DO A MYSQL QUERY AND SAVE IT TO $this->options
// ...
}
}
此类返回的数据是常量。因此,每次我需要访问例如base_url
值时都不需要运行MySQL查询。 创建对象并将其全局使用的最佳方法是什么?
$OPTIONS = new options;
function load_option($optName) {
global $OPTIONS;
return $OPTIONS->get($optName);
}
这个功能可能吗?有人告诉我这是最糟糕的可能方式。
我需要帮助。谢谢!
答案 0 :(得分:1)
您的问题在于,您不了解SOLID和DI原则是什么。您应该实现为每个单一职责提供服务的类,然后根据需要注入实例。
在你的情况下,它看起来像这样,
class Config
{
protected $pdo;
protected $cache;
public function __construct($pdo)
{
$this->pdo = $pdo;
}
public function read($key)
{
// Read a value by its key from a table
// Here should be a SELECT query
// You can also prevent reading the same thing twice
// by storing it in a cache
}
public function write(array $data)
{
foreach ($data as $key => $value) {
// Here should be INSERT statement
}
}
public function delete($key)
{
// Here comes a DELETE statement
}
}
每次需要读取配置值时,只需将Config
的实例注入需要它的类中。
class Foo
{
protected $config;
public function __construct(Config $config)
{
$this->config = $config;
}
public function doSomethingDependingOnConfig()
{
if ($this->config->read('lang') === 'en') {
// do something
}
}
}
你可以使用它,
$pdo = new PDO(...);
$config = new Config($pdo);
// Test
echo $config->read('lang'); //en
// So,
$foo = new Foo($config);
$foo->doSomethingDependingOnConfig();
答案 1 :(得分:0)
实际上,我认为这不是最糟糕的方式。
许多配置设置不需要存储在数据库中。有些甚至不能(像数据库的地址和凭据)。
很明显,一些硬编码配置很方便。如果你要研究现有的PHP应用程序,你会发现它们中的大多数都有一些全局可配置的选项。
全局变量的缺点是它非常严格且难以改变它的用法。很快你会发现自己在整个应用程序中都使用了这个全局。
但是您已经通过在函数中包装对它的访问来反驳,因此您可以在以后轻松更改选项,而无需更改整个应用程序。您通过创建此包装函数隐藏了选项的存储方式。如果您愿意,您仍然可以从数据库中获取它们,或者开始将它们存储在文件中,因为您需要更改的是此功能。实际上,这是一个非常好的解决方案。
您可以采取一些措施来改进此代码:
也许你可以将它包装在Config单例类中。这样做的好处是,您实际上可以将配置存储在该类中,摆脱全局变量,从而摆脱对该全局变量的意外访问。您将强制自己始终使用函数/类访问选项。