php 扩展 MySQLi 类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1820421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Extending the MySQLi class
提问by bennn
I want to be able to make classes which extend the MySQLi class to perform all its SQL queries.
我希望能够创建扩展 MySQLi 类以执行其所有 SQL 查询的类。
$mysql = new mysqli('localhost', 'root', 'password', 'database') or die('error connecting to the database');
I dont know how to do this without globalising the $mysql object to use in my other methods or classes.
如果不将 $mysql 对象全球化以在我的其他方法或类中使用,我不知道如何做到这一点。
class Blog {
public function comment() {
global $mysql;
//rest here
}
}
Any help would be appreciated.
任何帮助,将不胜感激。
Thanks.
谢谢。
回答by Yada
I was working on something similar. I'm happy about this singleton class that encapsulates the database login.
我正在做类似的事情。我很高兴这个封装了数据库登录的单例类。
<?php
class db extends mysqli
{
protected static $instance;
protected static $options = array();
private function __construct() {
$o = self::$options;
// turn of error reporting
mysqli_report(MYSQLI_REPORT_OFF);
// connect to database
@parent::__construct(isset($o['host']) ? $o['host'] : 'localhost',
isset($o['user']) ? $o['user'] : 'root',
isset($o['pass']) ? $o['pass'] : '',
isset($o['dbname']) ? $o['dbname'] : 'world',
isset($o['port']) ? $o['port'] : 3306,
isset($o['sock']) ? $o['sock'] : false );
// check if a connection established
if( mysqli_connect_errno() ) {
throw new exception(mysqli_connect_error(), mysqli_connect_errno());
}
}
public static function getInstance() {
if( !self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
public static function setOptions( array $opt ) {
self::$options = array_merge(self::$options, $opt);
}
public function query($query) {
if( !$this->real_query($query) ) {
throw new exception( $this->error, $this->errno );
}
$result = new mysqli_result($this);
return $result;
}
public function prepare($query) {
$stmt = new mysqli_stmt($this, $query);
return $stmt;
}
}
To use you can have something like this:
要使用你可以有这样的东西:
<?php
require "db.class.php";
$sql = db::getInstance();
$result = $sql->query("select * from city");
/* Fetch the results of the query */
while( $row = $result->fetch_assoc() ){
printf("%s (%s)\n", $row['Name'], $row['Population']);
}
?>
回答by Ben Fransen
My suggestion is to create a Singleton DataAccess class, instantiate that class in a global config file and call it in your Blog class like $query = DataAccess::query("SELECT * FROM blog WHERE id = ".$id).
我的建议是创建一个 Singleton DataAccess 类,在全局配置文件中实例化该类并在您的 Blog 类中调用它,如$query = DataAccess::query("SELECT * FROM blog WHERE id = ".$id).
Look into the Singleton pattern, it's a pretty easy to understand designpattern. Perfect for this situation.
看看单例模式,这是一个非常容易理解的设计模式。非常适合这种情况。
Your DataAccess class can have several methods like query, fetchAssoc, numRows, checkUniqueValue, transactionStart, transactionCommit, transactionRollbacketc etc. Those function could also be setup as an Interface which gets implemented by the DataAccess class. That way you can easily extend your DataAccess class for multiple database management systems.
你的数据访问类可以有几种方法,如query,fetchAssoc,numRows,checkUniqueValue,transactionStart,transactionCommit,transactionRollback等等等等,这些功能也可以设置为它获取由数据访问类实现的接口。这样您就可以轻松地为多个数据库管理系统扩展您的 DataAccess 类。
The above pretty much describes my DataAccess model.
上面几乎描述了我的 DataAccess 模型。
回答by Emre Yazici
You can use PHP's extends keyword just for any other class:
您可以将 PHP 的 extends 关键字用于任何其他类:
class MyCustomSql extends mysqli {
public function __construct($host, $user, $password, $database) {
parent::__construct($host, $user, $password, $database);
}
public function someOtherMethod() {
}
}
$sql = new MyCustomSql('localhost', 'root', 'password', 'database') or die('Cannot connect!');
or better use object aggregation instead of inheritance:
或者更好地使用对象聚合而不是继承:
class MySqlManipulator {
private $db;
public function __construct($host, $user, $password, $database) {
$this->db = new mysqli($host, $user, $password, $database);
}
public function someOtherMethod() {
return $this->db->query("SELECT * FROM blah_blah");
}
}
$mysqlmanipulator = new MySqlManipulator('localhost', 'root', 'password', 'database') or die('Cannot connect!');
回答by dnagirl
My standard method is to make a singletonclass that acts as the database accessor, and a base class that everything requiring such access inherits from.
我的标准方法是创建一个充当数据库访问器的单例类,以及一个需要此类访问的所有内容都继承自的基类。
So:
所以:
class Base {
protected $db;
function __construct(){
$this->db= MyDBSingleton::get_link();
//any other "global" vars you might want
}
}
class myClass extends Base {
function __construct($var) {
parent::__construct();// runs Base constructor
$this->init($var);
}
function init($id) {
$id=(int) $id;
$this->db->query("SELECT * FROM mytable WHERE id=$id");
//etc.
}
}
回答by chelmertz
Have a look at PDO, which throw exceptions for you to catch if a query fails. It's widely used and tested so you shouldn't have a problem finding existing solutions whilst using it.
看看PDO,如果查询失败,它会抛出异常供您捕获。它被广泛使用和测试,因此您在使用它时应该不会遇到找到现有解决方案的问题。
To inject it into your blog class:
要将其注入您的博客类:
class Blog {
private $_db;
public function __construct(PDO $db) {
$this->_db = $db
}
public function comment() {
return $this->_db->query(/*something*/);
}
}

