为查询优化设置一个全局的php对象

时间:2013-08-04 07:43:46

标签: php oop query-optimization

我在优化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);
}

这个功能可能吗?有人告诉我这是最糟糕的可能方式

我需要帮助。谢谢!

2 个答案:

答案 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单例类中。这样做的好处是,您实际上可以将配置存储在该类中,摆脱全局变量,从而摆脱对该全局变量的意外访问。您将强制自己始终使用函数/类访问选项。