在一个旧网站(PHP 3)上工作,我需要更新它的代码,特别是这个数据库连接类(mysql_db_query似乎已被弃用):
class db {
var $host;
var $port;
var $login;
var $pass;
var $data_base;
function db(){
$this->host = "";
$this->port = "";
$this->login = "";
$this->pass = "";
$this->data_base = "";
}
function connect() {
return mysql_connect($this->host.':'.$this->port, $this->login, $this->pass);
}
function query( $query ){
if ( $query )
return mysql_db_query($this->data_base,$query);
return mysql_query($query);
return 0;
}
function close( $link ){
mysql_close($link);
}
}
有人能告诉我如何更新吗?
提前感谢您的帮助。
答案 0 :(得分:1)
更新该类的最佳方法是在其旁边创建一个新的IMHO。这将允许您逐步更改代码而不会破坏现有代码(或至少以更加受控的方式)。
您可以首先从现有类中提取接口,然后实现实现相同接口的新类。
使用像PHP Storm这样的IDE最容易做到这一点,但这不是必须的,你也可以手动完成。
首先,您从类db
中提取界面,例如DbInterface
(在PHPStorm中右键单击类名" db"然后选择Refactor - &gt ;提取 - >接口):
interface DbInterface {
/**
* @param $link
* @return mixed
*/
function close($link);
/**
* @param string $query
* @return mixed
*/
function query($query);
function connect();
}
我还添加了一些缺少的docblock评论。我们还使用db
类来实现接口:
class db implements DbInterface {
现在再次测试你的代码,一切都应该没有任何问题。
这个界面已经显示了一些值得注意的缺陷,所以我们以后不会错过它们:
此时您可以决定如何继续。我建议你先从2.)开始,然后重构代码以将$link
变量拉入其中,而不是将其外部化到类中。但是,也可以进行外部化,它只需要一个新类型,然后作为新接口引入:
interface DbLinkInterface {
/**
* @return mixed
*/
public function getLink();
/**
* @return DbInterface
*/
public function getDatabase();
public function close();
}
然后这个接口由一个新类实现,该类主要封装有关链接的详细信息:
class DbLink implements DbLinkInterface
{
private $link;
/**
* @var DbInterface
*/
private $db;
public function __construct($link, DbInterface $db) {
$this->link = $link;
$this->db = $db;
}
/**
* @return mixed
*/
public function getLink() {
return $this->link;
}
/**
* @return DbInterface
*/
public function getDatabase() {
return $this->db;
}
public function close() {
$this->db->close($this);
}
}
现在进行测试时,您的代码仍应运行完美。每个小步骤后测试。
接下来的步骤是将此类引入现有类,以便可以将数据库链接作为具体类型传递。此步骤有点危险,因为根据您在其他地方的代码中使用$link
的方式,所以事情可能需要更多的更改才能像往常一样运行,因此您需要进行测试。例如,您可以替换
mysql_something($link);
至少
mysql_something($link->getLink());
但是你实际上必须从那里删除该功能。因此,更改$link
的类型实际上会使所有这些地方都可见。然后将方法添加到DbInterface
和/或DbLinkInterface
,以便您可以更流利地执行操作:
$link->something();
但这很大程度上取决于您的代码以及您重构的程度(请参阅链接的重复问题,它建议以不同的方式扫描所有文件,并使用兼容的API自动替换,如果您认为的话)不值得抽象分支。)
首先,DbLinkInterface
引入了DbInterface
:
interface DbInterface {
/**
* @param DbLinkInterface $link
* @return void
*/
function close(DbLinkInterface $link);
...
这将使现有代码失败,因为db
中的接口不满足,然后至少需要进行此更改:
class db implements DbInterface {
...
function close(DbLinkInterface $link) {
if ($link->getDatabase() instanceof $this) {
return mysql_close($link->getLink());
}
throw new InvalidArgumentException('Invalid Link given. Can only close link of my own type.');
}
}
现在可以再次加载代码,但是在将链接传递到close
的位置会出现致命错误。因此,当返回该链接时,类db
需要另一个更改:
class db implements DbInterface {
...
function connect() {
$link = mysql_connect($this->host . ':' . $this->port, $this->login, $this->pass);
return new DbLink($link, $this);
}
...
当您仅使用链接关闭数据库连接时(因为它看起来有点像),您的整个代码应该再次运行。测试一下就可以了。
所以现在终于将旧类抽象为两个接口,这将允许您更容易地替换它。这意味着您将添加其他代码,以便旧应用程序仍可以使用旧代码运行,您也可以使用新代码进行测试。您需要做的就是在您使用它的位置进行更改,通常是单个对象实例(变量)。
现在,您将介绍使用新数据库客户端API的类:
class db_mysqli extends db implements DbInterface {
/**
* @var mysqli
*/
private $db;
function connect() {
$this->db = new mysqli($this->host, $this->login, $this->pass, $this->data_base, $this->port);
return new DbLink($this->db, $this);
}
function query($query) {
return $this->db->query($query);
}
function close(DbLinkInterface $link) {
if ($link->getDatabase() instanceof $this) {
return $link->getLink()->close();
}
throw new InvalidArgumentException('Invalid Link given. Can only close link of my own type.');
}
}
您现在可以互换使用此类而不是另一个类,因此出于测试目的而您不需要在整个应用程序中使用它,或者您可以通过脚本或类似方式继续使用脚本。
正如此示例所示,外部化链接确实会引入需要首先封装的差异。
因为您不会更改数据库服务器,所以可以保留旧代码的配置和部分内容。
将您的代码置于版本控制之下,以便您可以轻松地逐步执行此操作,并在您引入错误和/或此处概述的某个概念不适合您的情况下还原。
我希望这会有所帮助。并记住要做一些小步骤,并考虑如何在不改变旧代码的情况下引入新代码。例如。就像我在这里做的一个新课而不是改变旧班。
为了使此过程更加健壮,您还可以引入断言,有关详细信息,请参阅Should I be using assert in my PHP code?。
答案 1 :(得分:0)
网上有很多关于如何迁移的文章,这是关于课堂的例子:
class db {
var $host;
var $port;
var $login;
var $pass;
var $data_base;
function db(){
$this->host = "";
$this->port = "";
$this->login = "";
$this->pass = "";
$this->data_base = "";
}
function connect() {
$mysqli = new mysqli($this->host, $this->login, $this->pass, $this->data_base, $this->port);
if( $mysqli->connect_errno )
return 0;
else
return $mysqli;
}
function query( $query ){
if ( $query )
return mysqli_query($query);
return 0;
}
function close( $link ){
mysqli_close($link);
}
}
这里有一个很棒的源扫描工具,用于将mysql转换为mysqli:
Converting to MySQLi
答案 2 :(得分:-1)
您需要阅读mysqli的文档 - 请参阅http://php.net/manual/en/book.mysqli.php。
此库也可以以功能方式使用。大多数对mysql_库的库调用都会在mysqli _
中有类似的调用