PHP OOP:类中的重复代码
我有一个包含两个方法的PHP类。一个连接到MySQL数据库进行输出,另一个连接到MySQL数据库进行输入 我的问题是,对于这两个函数,我重复了连接到数据库的代码。有什么更好的方法可以让类中的第三个函数连接到DB,让另外两个调用函数来建立连接,而不是重复代码两次?我是一个PHPN00B,试图改进我的OOP编码。注意我是如何两次连接到DB的——使用完全相同的代码:PHP OOP:类中的重复代码,php,mysql,sql,Php,Mysql,Sql,我有一个包含两个方法的PHP类。一个连接到MySQL数据库进行输出,另一个连接到MySQL数据库进行输入 我的问题是,对于这两个函数,我重复了连接到数据库的代码。有什么更好的方法可以让类中的第三个函数连接到DB,让另外两个调用函数来建立连接,而不是重复代码两次?我是一个PHPN00B,试图改进我的OOP编码。注意我是如何两次连接到DB的——使用完全相同的代码: class output_mysql { var $db_name = 'database'; var $db_username = '
class output_mysql {
var $db_name = 'database';
var $db_username = 'name';
var $db_password = 'mypassword';
function print_table_cell($tbl_name, $colm_name, $array_index_num) {
try {
$pdo = new PDO("mysql:host=localhost;dbname=$this->db_name", $this->db_username, $this->db_password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
$error = 'Unable to connect to the database server.';
include 'output_mysql_error.php';
exit();
}
try {
$sql = "SELECT $colm_name FROM $tbl_name";
$result = $pdo->query($sql);
}
catch (PDOException $e) {
$error = 'Error fetching content: ' . $e->getMessage();
include 'output_mysql_error.php';
exit();
}
while ($row = $result->fetch()) {
$all_content[] = $row["$colm_name"];
}
echo $all_content[$array_index_num];
}
function update_content($tbl_name, $colm_name, $error_message_text, $id_num) {
try {
$pdo = new PDO("mysql:host=localhost;dbname=$this->db_name", $this->db_username, $this->db_password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
$error = 'Unable to connect to the database server.';
include 'output_mysql_error.php';
exit();
}
try {
$sql = 'UPDATE website_content SET
content = :content,
date_added = CURDATE()
WHERE id = :id';
$s = $pdo->prepare($sql);
$s->bindValue(':content', $error_message_text);
$s->bindValue(':id', $id_num);
$s->execute();
}
catch (PDOException $e) {
$error = 'Error: ' . $e->getMessage();
include 'output_mysql_error.php';
exit();
}
}
}
这个问题被标记为[oop],但其中的代码与oop相去甚远 你的方法做得太多了。您应该做的是将数据库连接注入
output\u mysql
类的构造函数中(顺便说一句,这是一个糟糕的名称)
如果您有一个名为
print\u table\u cell
的方法,则很可能是OOP错误,因为这可能意味着您的代码做得太多,并且可能违反了规则。我的意思是,在几乎所有情况下,类都不需要访问任何表的任何列。这个问题被标记为[oop],但其中的代码远远不是oop
class Model
{
protected $pdo;
/**
* Inject the pdo driver in the model.
*/
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function print_table_cell($tbl_name, $colm_name, $array_index_num)
{
// Use the pdo object $this->pdo
}
}
// Create the connection
$dbName = '';
$dbUsername = '';
$dbPassword = '';
$pdo = new PDO("mysql:host=localhost;dbname=$dbName", $dbUsername, $dbPassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Create your model and inject the pdo object.
$model = new Model($pdo);
$model->print_table_cell() ...
你的方法做得太多了。您应该做的是将数据库连接注入output\u mysql
类的构造函数中(顺便说一句,这是一个糟糕的名称)
如果您有一个名为print\u table\u cell
的方法,则很可能是OOP错误,因为这可能意味着您的代码做得太多,并且可能违反了规则。我的意思是,在几乎所有情况下,类都不需要访问任何表的任何列
class Model
{
protected $pdo;
/**
* Inject the pdo driver in the model.
*/
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function print_table_cell($tbl_name, $colm_name, $array_index_num)
{
// Use the pdo object $this->pdo
}
}
// Create the connection
$dbName = '';
$dbUsername = '';
$dbPassword = '';
$pdo = new PDO("mysql:host=localhost;dbname=$dbName", $dbUsername, $dbPassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Create your model and inject the pdo object.
$model = new Model($pdo);
$model->print_table_cell() ...
如上所述,您需要使用准备好的语句,因为PDO将转义阻止SQL注入的值。但无论如何,所有输入数据都必须经过过滤:您有一些基本的过滤器
模型类应该只与数据库交互,不打印任何内容
对于priting输出,可以使用所谓的View类,该类从模型中获取数据并显示数据
class View
{
protected $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function render()
{
echo $this->model->getData();
}
}
class Model
{
protected $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function getData()
{
// Do your query here with $this->pdo and prepared statement.
// and return the data
}
}
$pdo = new PDO(...);
$model = new Model($pdo);
$view = new View($model);
$view->render();
如上所述,您需要使用准备好的语句,因为PDO将转义阻止SQL注入的值。但无论如何,所有输入数据都必须经过过滤:您有一些基本的过滤器
模型类应该只与数据库交互,不打印任何内容
对于priting输出,可以使用所谓的View类,该类从模型中获取数据并显示数据
class View
{
protected $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function render()
{
echo $this->model->getData();
}
}
class Model
{
protected $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function getData()
{
// Do your query here with $this->pdo and prepared statement.
// and return the data
}
}
$pdo = new PDO(...);
$model = new Model($pdo);
$view = new View($model);
$view->render();
答案可以在您的问题中找到:
在类中有第三个函数连接到DB,并让其他两个调用该函数来建立连接
注意,确保这样做,但请注意,您有机会在代码中注入SQL,因为它是这样的……KingDave,第二个方法中的prepared语句不保护我不受SQL注入的影响吗?第一种方法只是执行输出。答案可以在您的问题中找到:在类中有第三个函数连接到DB,并让其他两个调用该函数建立连接
注意,确保这是假定的,但请注意,您有机会在代码中注入SQL,因为它是这样的……KingDave,第二个方法中的prepared语句不保护我不受SQL注入的影响吗?第一种方法是只做output.+1,用于对准备好的语句提供建议。然而,模型是一个层而不是某个类,模型也不等于数据库。数据库是持久层。这只是模型层中的一层。模型是不属于表示层的所有类。+1用于对准备好的语句提供建议。然而,模型是一个层而不是某个类,模型也不等于数据库。数据库是持久层。这只是模型层中的一层。模型是不属于表示层的所有类。