我想就设计概念寻求建议。我创建了自己的MVC框架。
对于模型类,这些是主要从我的数据库中检索数据的类。
例如,在一个类(User
)中,我有以下方法
-
get_user
. -
get_recent_activity
.
基本上,例如get_recent_activity
方法中,我将有一个执行以获取数据的sql语句。
我正在考虑另一种设计,即扩展每个类(例如 User
)与Sql
类。在此类中,它将包含所有 sql 必需的查询。
例如,使用 sql 类的插入查询将如下所示
$sqlqueries->select("table","user=john&email=john@hotmail.com");
这会是一个更好的设计吗?为了维护什么?我担心性能问题,因为现在要从方法中获取数据,首先sql类中的选择方法需要首先处理变量。
你提到的Sql类对我来说看起来像一个存储库模式。确实具有维护优势,但也有助于单元测试,更好的分离和更干净的代码。
这是我在使用
数据库时如何设计自己的框架类的个人说明。
通常,在设计 MVC 框架时,我会列出开发类的两个核心概念:
- 管理各个方面(如查询构建、行计数返回、插入 ID 等)的单个数据库类。
- 一个接口数据类,用于确保每个类保持一致(例如,每个类必须具有所有四个 CRUD 操作)
数据库类
我的数据库类通常如下所示。您会注意到底部有您指定的突变器函数。这些专门设计用于从类本身设置和获取数据。有少量验证(get_connection中if(is_resource(...))
),尽管我听说这种代码应该在模型级别。
public $error;
private $location = '';
private $username = '';
private $password = '';
private $database = '';
public function __construct()
{
$connection = mysql_connect($this->location,$this->username,$this->password);
$this->set_connection($connection);
$db_select = mysql_select_db($this->database,$this->get_connection());
}
public function query()
{
$query = mysql_query($this->query,$this->connection);
$this->set_insert_id(mysql_insert_id($this->connection));
switch(substr(strtolower($this->query),0,6))
{
case 'select':
$this->set_row_count(mysql_num_rows($query));
$row_count = $this->get_row_count();
if($row_count == 0)
{
$this->set_results(0);
}
else
{
while($result = mysql_fetch_assoc($query))
{
$results = $this->get_results();
$results[] = $result;
$this->set_results($results);
}
}
break;
case 'insert':
case 'update':
case 'delete':
case 'replace':
default:
$this->set_results(($query === true));
break;
}
}
public function get_query()
{
return $this->query;
}
public function set_query($query)
{
$this->query = $query;
}
public function get_insert_id()
{
return $this->insert_id;
}
public function set_insert_id($insert_id)
{
if(is_numeric($insert_id))
{
$this->insert_id = $insert_id;
}
}
public function get_results()
{
return $this->results;
}
public function set_results($results)
{
$this->results = $results;
}
public function get_row_count()
{
return $this->row_count;
}
public function set_row_count($row_count)
{
if(is_numeric($row_count))
{
$this->row_count = $row_count;
}
}
public function get_connection()
{
return $this->connection;
}
public function set_connection($connection)
{
if(is_resource($connection))
{
$this->connection = $connection;
}
else
{
$this->connection = false;
}
}
}
?>
数据类
接口数据类只是其他类的准则,因此非常简单。执行此方法时,很容易处理数据。
<?php
interface Data {
public function create();
public function read();
public function update();
public function delete();
}
?>
示例类
下面是一个示例类,我通常会将其与前面所述的操作数据库和数据类的类一起使用。使用典型的 CRUD 操作时,我调用数据库类,设置查询,查询数据库,然后返回结果。这很简单,任何其他进一步的要求都可以附加到每个函数中。
<?php
require_once('classes/class.Data.php');
require_once('classes/class.Database.php');
class Settings implements Data {
private $profile_id;
private $settings = array();
public function create()
{
$settings_instance = new Database;
$sql = 'INSERT INTO settings (' . implode(',',array_keys($this->settings)) . ') VALUES ("' . implode('","',array_values($this->settings)) . '");';
$settings_instance->set_query($sql);
$settings_instance->query();
return $settings_instance->get_results();
}
public function read()
{
$settings_instance = new Database;
$sql = 'SELECT * FROM settings WHERE profile_id = "' . $this->profile_id . '"';
$settings_instance->set_query($sql);
$settings_instance->query();
$settings_results = $settings_instance->get_results();
if($settings_results)
{
$this->set_settings($settings_results[0]);
}
}
public function update()
{
$keys = array_keys($this->settings);
$values = array_values($this->settings);
$settings_instance = new Database;
$sql = 'UPDATE settings SET ';
foreach($keys as $index => $key)
{
if($keys[$index] == "profile_id")
continue;
$sql .= $keys[$index] . ' = "' . $values[$index] . '", ';
}
$sql = rtrim($sql,', ');
$sql .= ' WHERE profile_id = "' . $this->profile_id . '"';
$settings_instance->set_query($sql);
$settings_instance->query();
return $settings_instance->get_results();
}
public function delete()
{
$settings_instance = new Database;
$sql = 'DELETE FROM settings WHERE profile_id = "' . $this->profile_id . '"';
$settings_instance->set_query($sql);
$settings_instance->query();
return $settings_instance->get_results();
}
public function get_profile_id()
{
return $this->profile_id;
}
public function set_profile_id($profile_id)
{
if(is_numeric($profile_id))
{
$this->profile_id = $profile_id;
}
}
public function get_setting($index)
{
if(isset($this->settings[$index]))
{
return $this->settings[$index];
}
}
public function set_setting($index,$new_value)
{
if(isset($this->settings[$index]))
{
$this->settings[$index] = $new_value;
}
}
public function get_settings()
{
return $this->settings;
}
public function set_settings($settings)
{
if(is_array($settings))
{
$this->settings = $settings;
}
}
public function get_setting_types()
{
return $this->setting_types;
}
public function set_setting_types($setting_types)
{
if(is_array($setting_types))
{
$this->setting_types = $setting_types;
}
}
}
?>
一些示例代码
下面是一些采用此方法的示例模型代码。我发现这很有可读性。它将在数据库中创建一个新的设置行,profile_id = 1。
require_once('class.Settings.php');
$Settings = new Settings;
$Settings->set_profile_id(1);
$Settings->create();