您好我有一个简单的问题。我有用mysql扩展编写的类我的问题是如何将该类从mysql迁移到mysqli面向对象的样式而不是程序。 我是这个mysqli扩展的新手。
<?php
class DBController {
private $host = "";
private $user = "";
private $password = "";
private $database = "";
function __construct() {
$conn = $this->connectDB();
if(!empty($conn)) {
$this->selectDB($conn);
}
}
function connectDB() {
$conn = mysql_connect($this->host,$this->user,$this->password);
return $conn;
}
function selectDB($conn) {
mysql_select_db($this->database,$conn);
}
function runQuery($query) {
$result = mysql_query($query);
while($row=mysql_fetch_assoc($result)) {
$resultset[] = $row;
}
if(!empty($resultset))
return $resultset;
}
function numRows($query) {
$result = mysql_query($query);
$rowcount = mysql_num_rows($result);
return $rowcount;
}
}
?>
答案 0 :(得分:0)
拥有这样的类确实是个好主意,但是不幸的是,从mysql_*
API转移到mysqli
类并不是那么简单。它需要重写大量代码并改变思维方式。
如果您计划从mysql_*
API进行升级,则可能意味着您到目前为止一直在使用PHP 4。如果您使用的是PHP 5,那么您将使用PHP 4的思维方式。自那时以来,PHP已经走了很长一段路。现在,我们有了适当的类,命名空间,更好的错误报告等。在数据库交互方面,我们现在有了两个新扩展:mysqli和PDO。在这两个中,您应该使用PDO。。但是,如果您使用的是包装类,那么尝试创建从mysqli到PDO的更改应该非常容易。仅出于这个原因,这样的包装器类是一个好主意。
mysqli扩展的主要原因是保持旧扩展的熟悉语法并添加必要的新功能,例如准备好的语句和正确的错误报告。 如果您习惯于将PHP变量直接放入SQL查询中,则必须改变思维方式。现在,您应该使用参数化查询并分别绑定值。
一个简单的示例,说明您的改进类是什么样的:
<?php
class DBController {
/**
* mysqli instance
*
* @var \mysqli
*/
private $mysqli;
public function __construct(
$host = null,
$username = null,
$passwd = null,
$dbname = null,
$charset = 'utf8mb4',
$port = null,
$socket = null
) {
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$this->mysqli = new \mysqli($host, $username, $passwd, $dbname, $port, $socket);
$this->mysqli->set_charset($charset);
}
public function runQuery(string $sql, array $params = []): ?array {
$stmt = $this->mysqli->prepare($sql);
if ($params) {
$stmt->bind_param(str_repeat("s", count($params)), ...$params);
}
$stmt->execute();
if ($result = $stmt->get_result()) {
return $result->fetch_all(MYSQLI_BOTH);
}
return null;
}
}
警告::这不是此类包装器类的完整实现。您很可能需要实现其他方法,并根据需要添加更多逻辑。这仅是出于演示目的。
首先,在构造方法中,我们应该执行3个步骤。启用错误报告,创建mysqli
类的实例,并设置正确的字符集(使用utf8mb4
,它是MySQL 5.5中添加的,现在是标准字符集)。
您的runQuery()
方法现在接受2个参数。第一个是使用占位符而不是插值的SQL查询,第二个是要绑定的值的数组。
很可能您不需要selectDB()
,而且您绝对不需要numRows()
。如果您想知道检索到的数组中的行数,可以使用count()
在PHP中对其进行计数。
使用此类非常简单。
$db = new DBController('localhost', 'username', 'password', 'db_name');
$result = $db->runQuery('SELECT Id, Name FROM table1 WHERE uuid=?', ['myuuid']);
if ($result) {
// Get the name of found record
echo $result[0]['Name'];
} else {
echo 'No records found';
}
如果您想将实现切换到PDO,则可以在不更改使用方式的情况下替换该类。
class DBController {
/**
* PDO instance
*
* @var \PDO
*/
private $pdo;
public function __construct(
$host = null,
$username = null,
$passwd = null,
$dbname = null,
$charset = 'utf8mb4',
$port = null,
$socket = null
) {
$dsn = "mysql:host=$host;dbname=$dbname;charset=$charset;port=$port;socket=$socket";
$options = [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false,
];
$this->pdo = new PDO($dsn, $username, $passwd, $options);
}
public function runQuery(string $sql, array $params = []): ?array {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
}
警告::这不是此类包装器类的完整实现。您很可能需要实现其他方法,并根据需要添加更多逻辑。这仅是出于演示目的。