简体   繁体   English

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

[英]PHP OOP Class vs Functions vs Static Functions efficiency

Sorry if I am not using the best jargon, but I have run into an issue I want to solve early before I write too much code. 对不起,如果我没有使用最好的行话,但我遇到了一个问题,我想在我编写太多代码之前提前解决。 Which of these options below is "better"? 以下哪个选项“更好”? And is there a better way of doing this? 还有更好的方法吗? Someone mentioned to me abstracting my code but another class seems to be the last thing I need. 有人提到我抽象我的代码,但另一个类似乎是我需要的最后一件事。 Also I feel like there's something I can do by potentially making my "get" function seen below into a public static function so that I can use it differently. 另外我觉得我可以通过将下面的“获取”功能看到公共静态函数来做我可以做的事情,这样我就可以用不同的方式。 (its not static right now) (现在不是静态的)

Here is my situation: 这是我的情况:

  • I have 2 (relevant to this question) classes, DB (database) and Page (for getting my content to display on my website) 我有2个(与此问题相关)类,DB(数据库)和页面(用于获取我的内容以显示在我的网站上)
  • the DB class has a query method that prepares and execute my queries DB类有一个准备和执行我的查询的查询方法
  • the DB class also has methods for inserting, getting, deleting things from the database. DB类还具有从数据库中插入,获取,删除内容的方法。
  • I now feel that I may not even need my page class because right on the webpage I can just use those DB methods to call my content. 我现在觉得我可能甚至不需要我的页面类,因为在网页上我可以使用这些数据库方法来调用我的内容。 (I store all images, content, page title, description in mysql). (我在mysql中存储所有图像,内容,页面标题,描述)。 Is this not a legitimate way to do this? 这不是一种合法的方式吗? Won't I need to create a new object each time? 我不是每次都需要创建一个新对象吗? such as: 如:

     $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); 

I do not like this potential solution just because to me its counter intuitive. 我不喜欢这种潜在的解决方案,因为对我来说它的反直觉。 Why should I have to create new objects just to reuse a function? 为什么我必须创建新对象只是为了重用一个函数? However, what I do right now is something I feel is going to get me some hate mail. 但是,我现在做的是我觉得会给我一些讨厌的邮件。

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

These are 3 separate functions in my Page class that perform very similar things. 这些是我的Page类中的3个独立函数,它们执行非常相似的操作。 Find gets my pages content out of the database and returns it as an object. 查找从数据库中获取我的页面内容并将其作为对象返回。 Lookup does basically the same thing but only needs to pass one variable because its only to do with the html structure of each page regardless of which language is being accessed. Lookup基本上做同样的事情,但只需传递一个变量,因为它只与每个页面的html结构有关,无论访问哪种语言。 retrieve gets all images from a table that get shown in a slider with different language descriptions. retrieve从表中获取所有图像,这些图像显示在具有不同语言描述的滑块中。 But as you can see, all three functions do basically the same thing! 但正如你所看到的,这三个功能基本上都是一样的! They query the database. 他们查询数据库。 Thanks for the help with this I am literally just getting into this OOP and its driving me insane. 感谢您的帮助,我真的只是进入这个OOP,它让我疯了。 Stack has been very helpful and I think I just didn't know how to search for this to find the answer. Stack非常有帮助,我想我只是不知道如何搜索这个以找到答案。 Feel free to point me to other questions/answers that I may have missed. 请随意指出我可能错过的其他问题/答案。 It was hard for me to think of the keywords to search for. 我很难想到要搜索的关键字。

I don't want to get into the weeds on a SPECIFIC implementation for you situation, rather I am going to offer some generic guidance. 我不想针对您的情况进入针对SPECIFIC实施的杂草,而是我将提供一些通用指导。

First off, you shouldn't have to create a separate database object (dbo) for title, images, or structure. 首先,您不必为标题,图像或结构创建单独的数据库对象(dbo)。 Chances are the DSN used for each dbo you are initializing are the exact same, so I would create a singleton dbo which can be shared across multiple objects. 有可能你正在初始化的每个dbo使用的DSN完全相同,所以我会创建一个可以在多个对象之间共享的单例dbo。 For reference take a look at Doctrine's connection manager . 有关参考,请查看Doctrine的连接管理器

Secondly, I think your objectification could be implemented better. 其次,我认为你的客观化可以更好地实施。 Following most ORMS implementation, you have a Record class and a Table class. 在大多数ORMS实现之后,您有一个Record类和一个Table类。 The Record class is a specific instance of a Record in your schema, whereas the Table class executes queries against your store which may result in multiple records. Record类是模式中Record的特定实例,而Table类对您的商店执行查询,这可能会导致多个记录。 These results are then hydrated into an array (of records). 然后将这些结果水合成阵列(记录)。

So what I would suggest is something like this (code has not been tested and some of it has been stubbed for brevity): 所以我建议的是这样的事情(代码尚未经过测试,其中一些代码为简洁起见):

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(){}
}

Hopefully this separation of Record and methods affecting a single, or multiple records makes sense. 希望记录和方法的这种分离能够影响单个或多个记录。 You should take a look at a DBAL, like Doctrine . 你应该看一下DBAL,比如Doctrine

we may create other classes indeed, but efficiently so. 我们确实可以创建其他类,但效率很高。 Maybe we can render DB a public state function. 也许我们可以将DB渲染为公共状态函数。 I like the idea of creating a database object, pass it as parameter to an other object, which could then format data with the link he just received: 我喜欢创建数据库对象的想法,将其作为参数传递给另一个对象,然后可以使用刚刚收到的链接格式化数据:

$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.

then, from inside your function, you can call images, titles and structures at will from $this 然后,从你的函数里面,你可以调用图片,标题和结构随意从$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);

and you can those other method as well 而你也可以使用其他方法

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

Now we do not need to create a new object each time we want information from the database. 现在,每当我们需要来自数据库的信息时,我们就不需要创建新对象。

Now... 现在...

the way I access member functions here $this->pgID is better used by defining a getter: $this->pgID() . 我在这里访问成员函数的方式$this->pgID最好通过定义一个getter来使用: $this->pgID() I like my getter to have the same name as the property. 我喜欢我的吸气剂与酒店的名称相同。 This might not be a very good idea though. 但这可能不是一个好主意。

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

As for abstract classes.. 至于抽象类......

I did in fact come very lately into thinking abstract classes were quite cool indeed. 事实上我最近确实认为抽象类确实非常酷。 I've some problem with wording it, having a constant constructor with custom mandatory functions and possible different implementation of classes seems awesome: 我在措辞方面遇到了一些问题,有一个带有自定义强制函数的常量构造函数,并且可能有不同的类实现看起来很棒:

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;
  }
}

ok, hope you're still there! 好的,希望你还在那里! Now we have a Structure and Image class with requisites constructor arguments, generic functions and a custom retrieve function. 现在我们有一个Structure和Image类,其中包含必需构造函数参数,泛型函数和自定义检索函数。 We could use them that way: 我们可以这样使用它们:

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

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

I do hope you do not have to create a new instance of DB if you use a different page id :-) 如果您使用不同的页面ID,我希望您不必创建新的DB实例:-)

jokes appart this helps me using classes in a better structured way, as I might have many different classes to represent different parts of a site, but when called from an index all of them will have the same function names, like retrieve() or print() , list() ... 笑话appart这有助于我以更好的结构化方式使用类,因为我可能有许多不同的类来表示站点的不同部分,但是当从索引调用时,所有这些类都将具有相同的函数名称,如retrieve()print()list() ......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM