简体   繁体   English

PHP类共享SQL查询数据的设计模式

[英]Design pattern for PHP classes sharing data from SQL queries

I'm a beginner to OOP. 我是OOP的初学者。 The following is the jist of my code, which I am trying to find a proper design pattern for: 以下是我的代码的要旨,我正在尝试为其找到合适的设计模式:

class data {
public $location = array();
public $restaurant = array();
}

$data = new data;
$query = mysqli_query($mysqli, "SELECT * FROM restaurants"); 
//actually a big long query, simplified for illustrative purposes here
$i = 0;
while ($row = mysqli_fetch_array($query)) {
$data->location[] = $i.')'.$row['location']."<br>";
$data->restaurant[] = $row['restaurant']."<br>";
$i++;
}

I'd like to access the data class from another PHP page. 我想从另一个PHP页面访问数据类。 (To print out information in HTML, hence the (以HTML格式打印信息,因此
tags). 标签)。 I prefer not to run the query twice. 我宁愿不要两次运行查询。 I understand that classes are created and destroyed in a single PHP page load. 我知道类是在单个PHP页面加载中创建和销毁的。 I'd appreciated design pattern guidance for managing HTTP application state and minimizing computer resources in such a situation. 我非常感谢在这种情况下用于管理HTTP应用程序状态并最大程度地减少计算机资源的设计模式指南。

SELECT data in database is rather inexpensive, in general speaking. 一般来说,数据库中的SELECT数据非常便宜。 You didn't need to worry about running the query twice. 您无需担心两次运行查询。 MySQL will do the caching part. MySQL将做缓存部分。

From your codes, you mixed up database data with HTML. 从代码中,您将数据库数据与HTML混合在一起。 I suggest to separate it. 我建议将其分开。

// fetch data part
while ($row = mysqli_fetch_array($query)) {
  $data->location[] = $row['location'];
  $data->restaurant[] = $row['restaurant'];
}

// print HTML part
$i = 0;
foreach($data->location as $loc) {
  echo $i . ')' . $loc . '<br />';
}

If you store the data object in a $_SESSION variable, you will have access to it from other pages and upon refresh. 如果将数据对象存储在$ _SESSION变量中,则可以从其他页面和刷新时访问它。 As mentioned in other post and comments, you want to separate out the HTML from data processing. 如其他文章和评论中所述,您希望将HTML与数据处理分开。

class data {
  public $location = array();
  public $restaurant = array();
}

// start your session
session_start();

$data = new data;
$query = mysqli_query($mysqli, "SELECT * FROM restaurants"); 
//actually a big long query, simplified for illustrative purposes here
$i = 0;
while ($row = mysqli_fetch_array($query)) {
  $data->location[] = $i.')'.$row['location'];
  $data->restaurant[] = $row['restaurant'];
$i++;
}

// HTML (separate from data processing)
foreach ($data->location as $location) {
  echo $location . '<br />';
}

// save your session
$_SESSION['data'] = $data;

When you wish to reference the data object from another page 当您希望从另一个页面引用数据对象时

// start your session
session_start();

// get data object
$data = $_SESSION['data'];

// do something with data
foreach($data->location as $location) {
  echo $location . '<br />';
}

First you say this: 首先,您要这样说:

I'm a beginner to OOP. 我是OOP的初学者。

Then you say this: 然后你这样说:

I prefer not to run the query twice. 我宁愿不要两次运行查询。 I understand that classes are created and destroyed in a single PHP page load. 我知道类是在单个PHP页面加载中创建和销毁的。

You are overthinking this. 您想得太多了。 PHP is a scripting language based on a user request to that script. PHP是基于用户对该脚本的请求的脚本语言。 Meaning, it will always reload—and rerun—the code on each load of the PHP page. 意思是,它将始终在每次加载PHP页面时重新加载并重新运行代码。 So there is no way around that. 所以没有办法解决。

And when I say you are overthinking this, PHP is basically a part of a LAMP stack (Linux, Apache, MySQL & PHP) so the burden of query speed rests on the MySQL server which will cache the request anyway. 而且,当我说您想得太多时,PHP基本上是LAMP堆栈(Linux,Apache,MySQL和PHP)的一部分,因此查询速度的负担落在了将始终缓存请求的MySQL服务器上。

Meaning while you are thinking of PHP efficiency, the inherent architecture of PHP insists that queries be run on each load. 这意味着在考虑PHP效率时,PHP的固有体系结构坚持要求在每个负载上运行查询。 And with that in mind the burden of managing the queries falls on MySQL and on the efficiency of the server & the design of the data structures in the database. 考虑到这一点,管理查询的重担将落在MySQL以及服务器的效率和数据库中数据结构的设计上。

So if you are worried about you code eating up resources, think about improving MySQL efficiency in some way. 因此,如果您担心代码会耗尽资源,则可以考虑以某种方式提高MySQL效率。 But each layer of a LAMP stack has its purpose. 但是LAMP堆栈的每一层都有其用途。 And the PHP layer's purpose is to just reload & rerun scripts in each request. PHP层的目的是仅在每个请求中重新加载并重新运行脚本。

You are probably are looking for the Repository pattern. 您可能正在寻找存储库模式。

The general idea is to have a class that can retrieve data objects for you. 通常的想法是拥有一个可以为您检索数据对象的类。

Example: 例:

$db = new Db(); // your db instance; you can use PDO for this.

$repo = new RestaurantRepository($db); // create a repo instance

$restaurants = $repo->getRestaurants(); // retrieve and array of restaurants instances

Implentation: 实施:

class RestaurantRepository {
    public function  __construct($db) {
        $this->db = $db;
    }

    public function getRestaurants() {
        // do query and return an array of instances
    }
}

Code is untested and may have typos but it's a starter. 代码未经测试,可能有错别字,但这是一个开始。

Saving the query results to a $_SESSION variable in the form of an array results in not having to re-run the query on another page. 以数组形式将查询结果保存到$_SESSION变量中,从而不必在另一页上重新运行查询。 Additionally, it manages state correctly as I can unset($_SESSION['name']) if the query is re-run with different parameters. 另外,如果使用不同的参数重新运行查询,它可以正确地管理状态,因为我可以unset($_SESSION['name'])

I can also save the output of class data to a session variable. 我还可以将类数据的输出保存到会话变量中。 It seems to me that this design pattern makes more sense than running a new query for page refreshes. 在我看来,这种设计模式比运行新的页面刷新查询更有意义。

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

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