PHP OOP类vs函数与静态函数效率

时间:2014-06-17 21:13:50

标签: php mysql class oop static-methods

很抱歉,如果我没有使用最好的术语,但我遇到了一个问题,我想在编写太多代码之前提前解决。以下哪个选项是"更好"?还有更好的方法吗?有人提到我抽象我的代码,但另一个类似乎是我需要的最后一件事。此外,我觉得我可以通过潜在地制作我的" get"下面看到的函数进入公共静态函数,以便我可以以不同的方式使用它。 (现在不是静态的)

以下是我的情况:

  • 我有2个(与此问题相关)类,DB(数据库)和页面(用于让我的内容显示在我的网站上)
  • DB类有一个准备和执行查询的查询方法
  • DB类还具有从数据库中插入,获取,删除内容的方法。
  • 我现在觉得我甚至可能不需要我的页面类,因为在网页上我可以使用这些数据库方法来调用我的内容。 (我在mysql中存储所有图像,内容,页面标题,描述)。这不是一种合法的方式吗?我不是每次都需要创建一个新对象吗?如:

    $pg_ID = 2;
    $title = new DB($pgID);
    $title->get('pages', $pgID, $lang); // 3 tables to pull from for each page
    
    $images = new DB($pgID);
    $images->get('images', $pgID, $lang);
    
    $structure = new DB($pgID); // I need these tables mostly because my site is in two languages
    $images->get('pages_list', $pgID);
    

我不喜欢这种潜在的解决方案只是因为对我来说它的反直觉。为什么我必须创建新对象只是为了重用一个函数?但是,我现在做的是我觉得会给我一些讨厌的邮件。

    $page = new Page();
    $page->find('pages', $pgID, $lang);
    $page->lookup($pgID);
    $page->retrieve('images', $pgID, $lang);

这是我的Page类中的3个独立函数,它们执行非常相似的操作。查找从数据库中获取我的页面内容并将其作为对象返回。 Lookup基本上做同样的事情,但只需传递一个变量,因为它只与每个页面的html结构有关,无论访问哪种语言。 retrieve从表中获取所有图像,这些图像显示在具有不同语言描述的滑块中。但正如你所看到的,这三个功能基本上都是一样的!他们查询数据库。感谢您的帮助,我真的只是进入这个OOP,它让我疯了。 Stack非常有帮助,我想我只是不知道如何搜索这个以找到答案。请随意指出我可能错过的其他问题/答案。我很难想到要搜索的关键字。

2 个答案:

答案 0 :(得分:1)

我不想针对您的情况进入针对SPECIFIC实施的杂草,而是我将提供一些通用指导。

首先,您不必为标题,图像或结构创建单独的数据库对象(dbo)。有可能你正在初始化的每个dbo使用的DSN完全相同,所以我会创建一个可以在多个对象之间共享的单例dbo。如需参考,请查看Doctrine's connection manager

其次,我认为你的客观化可以更好地实施。在大多数ORMS实施之后,您有一个记录类和一个类。 Record类是模式中Record的特定实例,而Table类对您的商店执行查询,这可能会导致多个记录。然后将这些结果水合成一个阵列(记录)。

所以我建议的是这样的事情(代码尚未经过测试,其中一些内容为了简洁起见):

class PageTable
{
    public static function getById($id)
    {
        // Validate id, if invalid throw exception

        $dbo = Database::getConnection();

        $stmt = $dbo->prepare('SELECT * FROM page WHERE id = :id');

        $stmt->bindParam(array('id' => $id));

        $stmt->execute();

        $result = $stmt->fetch();

        $page = new Page;

        // Hydration
        $page->setId($result['id']);
        $page->setImages($result['images']);

        return $page;
    }
}

class Page
{
    protected $id;

    protected $title;

    public function setId($id){}

    public function getId(){}
}

希望记录和方法的这种分离能够影响单个或多个记录。你应该看一下DBAL,比如Doctrine

答案 1 :(得分:1)

我们确实可以创建其他类,但效率很高。也许我们可以将DB呈现为公共 state 函数。我喜欢创建数据库对象的想法,将其作为参数传递给另一个对象,然后可以使用刚刚收到的链接格式化数据:

$pg_ID = 2;
$db = new DB($pg_id);
$page = new Page($db,$pg_ID);
 // make sure you assign the parameters a private properties in `Page()` ctor.

然后,从您的函数内部,您可以随意调用图像,标题和结构$this

$title = $this->DB->get('pages', $this->pgID, $lang);
$images = $this->DB->get('images', $this->pgID, $lang);
$structure = $this->DB->get('pages_list', $this->pgID);

你可以使用其他方法

$page->find('pages', $this->pgID, $lang);
$page->lookup($this->pgID);
$page->retrieve('images', $this->pgID, $lang);

现在,每当我们需要来自数据库的信息时,我们就不需要创建新对象。

立即...

通过定义getter:$this->pgID可以更好地使用$this->pgID()访问成员函数的方式。我喜欢我的吸气剂与酒店的名称相同。这可能不是一个好主意。

private function pgID() {
  return $this->pgID;
}

至于抽象类......

事实上我最近确实认为抽象类确实非常酷。我有一些问题,有一个带有自定义强制函数的常量构造函数和可能的类的不同实现看起来很棒:

abstract class Page {
  function __construct($db,$pgID,$lang,$params='') {
    $this->db = $db;
    $this->pgID = $pgID;
    $this->lang = $lang;
    $this->init($params);
  }
  function pgID() {
   return $this->pgID;
  }
  function lang() {
   return $this->lang;
  }
  abstract function init();
  abstract function retrieve();
}

class Structure extends Page {
  function init($params) {
    // some specific to Structure foo here
  }
  function retrieve($what='pages_list') {
    return $this->db->get($what,$this->pgID,$this->lang);
  }
}

class Image extends Page {
  function init($params) {
    // some specific to Image foo here
  }
  function retrieve($what='images') {
    $images = $this->db->get($what,$this->pgID,$this->lang);
    // plus some foo to resize each images
    return $images;
  }
}
好的,希望你还在那里!现在我们有一个Structure和Image类,其中包含必需构造函数参数,泛型函数和自定义检索函数。我们可以这样使用它们:

$db = new DB(2);
$template = new Structure($db,2,'fr');
$template->retrieve();

$slideshow = new Image($db,4,'en');
$slideshow->retrieve();

如果您使用不同的页面ID,我希望您不必创建DB的新实例: - )

笑话appart这有助于我以更好的结构化方式使用类,因为我可能有许多不同的类来表示站点的不同部分,但是当从索引调用时,所有这些类都将具有相同的函数名,例如{{ 1}}或retrieve()print() ...