抱歉这个愚蠢的问题是一个新手在php中oop ...我有一个问题wiriting mysqli类thet返回一个连接处理程序,使我在其他类/方法中的连接处理程序.我运行一个小程序博客,想要转换为oop.这是我工作的代码示例.请在必要时为我重构.预先感谢.
$db_link = mysqli_connect(DB,HOST,DB_USER,DB,PASS,DB_NAME) or die(mysql_error());
class myDB extends mysqli
{
public function getConfig($id, $db_link) // thanks cbuckley
{
$db_link = $this->db_link;
$res = mysqli_query($this->db_link,"SELECT * from config where id='1'");
$row = mysqli_fetch_array($res);
return $row['option'];
}
}
Run Code Online (Sandbox Code Playgroud)
我已经定义了常量,连接成功,但是选择不起作用.在索引页面上,这是
include('inc/dbc.php');
$db = new MyDB();
echo $db->getConfig(1, $db_link);
Run Code Online (Sandbox Code Playgroud)
任何帮助表示赞赏
你的问题不是很具体,我觉得你并不知道你的具体问题是什么.您已经接受了一个答案,它会为您提供一些代码,但会使您处于错误的方向,因为它无法解决您的潜在问题并浪费代码.
如果你想利用PHP的mysqli扩展的面向对象接口,你应该知道的第一件事是,Mysqli该类代表了数据库连接(为程序方法命名的"链接"):
require('inc/dbc.php');
$dbConnection = new Mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
Run Code Online (Sandbox Code Playgroud)
那已经是它了.当然你可能想在这里使用一些错误处理:
if ($dbConnection->connect_error)
{
throw new Exception(
sprintf('(#%d) %s', $dbConnection->connect_errorno,
$dbConnection->connect_error)
);
}
Run Code Online (Sandbox Code Playgroud)
抛出异常而不是让我们说die('message')完成,因为你可以轻松地创建一个异常处理程序,这样你就可以从一个中心位置向用户显示一个更有用的响应,而不是处理它出现的每个异常错误情况(实际上在这个地方)die会在哪里).
您还可以记录和邮寄回溯,以便您可以更轻松地修复问题.当然,您不需要使用异常,但经验法则是die仅在您丢弃的脚本中使用,例如一周,并且它不适用于面向对象的设计.
因为在需要数据库连接的所有地方,无论如何都需要此代码,您可以创建自己的连接对象,将这些部分组合在一起:
class DatabaseException extends Exception
{
}
class DatabaseConnection extends Mysqli
{
public function __construct($host, $user, $password, $database = "", $port = NULL, $socket = NULL) {
parent::__construct($host, $user, $password, $database, $port, $socket);
$this->throwConnectionExceptionOnConnectionError();
}
private function throwConnectionExceptionOnConnectionError() {
if (!$this->connect_error) return;
$message = sprintf('(%s) %s', $this->connect_errno, $this->connect_error);
throw new DatabaseException($message);
}
}
Run Code Online (Sandbox Code Playgroud)
用法实际上很简单,非常相同,只有类的名称不同,需要加载它的定义:
require('inc/dbc.php');
require('inc/database.php');
$dbConnection = new DatabaseConnection(DB_HOST, DB_USER, DB_PASS, DB_NAME);
Run Code Online (Sandbox Code Playgroud)
如上所述,连接对象已经表示您的数据库连接.因此,应用程序中需要它的每个部分都必须要求它.我们来看看你的示例函数:
function getOption($id, $db_link)
{
// $db_link = $this->db_link;
$res = mysqli_query($this->db_link,"SELECT * from config where id='1'");
$row = mysqli_fetch_array($res);
return $row['option'];
}
Run Code Online (Sandbox Code Playgroud)
我重命名了这个函数,我评论了第一行,即使这可能是你想要的.实际上,如果该函数是DatabaseConnection对象的一部分,它可以像这样工作:
class DatabaseConnection extends Mysqli
{
...
public function getOption($id) {
$statement = $this->prepare('SELECT `option` FROM config WHERE id=?');
$statement->bind_param('i', $id);
$statement->execute();
$statement->bind_result($option);
$statement->fetch();
$statement->close();
return $option;
}
Run Code Online (Sandbox Code Playgroud)
如此示例所示,数据库连接已存在.但是,这是不可取的.想象一下,你不仅有选择,还有这个和那个等等,而不是更多.您将在一个类中创建另一个函数.对于一个甚至可能正常工作的小应用程序,但想象越来越多.你会得到一个非常大的课程,负责很多事情.所以这样做会很糟糕,即使你$this已经可以使用它来准备声明了.
另请注意,您应准备陈述.这已经在这里得到了很多次回答,如果你不习惯它,阅读它,它是值得的.有一些更好的方法可以在进入面向对象时不重复代码(DRY:不要重复自己)(你甚至应该已经用程序执行此操作).
因此,将这一切都放在一个类中将是一个问题,而是将它放在它自己的类中:
class DatabaseModelBase
{
protected $connection;
public function __construct(Connection $connection) {
$this->connection = $connection;
}
protected function prepare($query) {
$connection = $this->connection;
$statement = $connection->prepare($query);
if (!$statement) {
throw new DatabaseException(
sprintf('(%s) %s', $connection->error, $connection->errno)
);
}
return $statement;
}
}
class Option extends DatabaseModelBase
{
public function find($id) {
$statement = $this->prepare('SELECT `option` FROM config WHERE id=?');
$statement->bind_param('i', $id);
$statement->execute();
$statement->bind_result($option);
$statement->fetch();
$statement->close();
return $option;
}
}
Run Code Online (Sandbox Code Playgroud)
这有一些扩展的错误处理,因为大多数错误都是在SQL查询中进行的.正如您所看到的,获取某些特定数据的单个函数被放置在它自己的类中.您可以使用此类对特定数据类型的提取和更新进行分组.
用法全部:
$dbConnection = new Connection(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$option = new Option($dbConnection);
$optionValue = $option->find(1);
echo $optionValue; # value for option with ID1
Run Code Online (Sandbox Code Playgroud)
Option对象的名称可能不太好,我试图保持示例轻量级但也提供一些分离.对于其他风格,您可能希望更喜欢某种不同类型如何访问数据库连接,因为它是Option通过它的构造函数注入的,Option不再处理有关如何创建数据库连接的详细信息.
例如,您可以使数据库连接对象更加智能,只有在第一次准备或查询实际使用时才连接到数据库.因此,对您的网站的不需要数据库连接的请求不会不必要地连接到数据库.
您可以在其他问题中找到更多示例,并且可能希望了解依赖注入.此外,你总是希望彼此分开,所以你有一些只是轻微相互连接的物体.