2013-09-27 70 views
-1

在一箇舊的網站(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

順便說一句,不推薦使用的東西不(但)意味着您需要更改代碼。它仍然有效,它只是警告你,接下來你需要計劃重構代碼以利用新的數據庫客戶端API。這是一個警告,不是一個致命的錯誤。 PHP手冊指導瞭如何從一個PHP版本遷移到另一個PHP版本。 3至4:http://www.helmholtz-muenchen.de/ibb/homepage/karsten.rodenacker/php_html/migration4.html 4至5:http://php.net/manual/en/faq.migration5 .php – hakre

回答

-1

您需要閱讀mysqli的文檔 - 請參閱http://php.net/manual/en/book.mysqli.php

該庫也可用於功能性方式。大部分的庫調用來mysql_庫將在mysqli_一個類似

+0

請添加,作爲對上面鏈接的規範問題的評論,而不是在這裏(如果它不存在那裏)。謝謝! – hakre

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

+0

請添加,作爲對上面鏈接的規範問題的評論,不在這裏。 – hakre

+0

我現在親自照顧。 – hakre

1

更新該類的最好方法是在它旁邊創建一個新的恕我直言。這將允許您逐步更改代碼而不破壞現有代碼(或至少以更受控制的方式)。

您可以通過首先將接口從現有類中提取出來,然後實現實現相同接口的新類來實現。

你用PHP Storm這樣的IDE最容易做到這一點,但這不是必需的,你也可以手工完成。

首先你提取接口出db類,例如DbInterface(在PHPStorm在類名「DB」單擊鼠標右鍵,然後選擇重構 - >提取物 - >接口):

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 { 

現在再次測試你的代碼,一切都應該運行沒有任何問題。

這個界面已經顯示了一些毛病,你最好是值得大家注意的,所以我們沒有在以後想念他們:

  1. 該類的對象配置了一些代碼,分配數據庫配置和憑據通過公共成員,所以有其他代碼(在你的問題中不可見)。隨着數據庫客戶端庫的更改,類的配置方式也可能會發生變化。配置代碼也應該被封裝,以便它可以被替換(例如移入類或配置對象)。
  2. close方法需要從外部連接數據庫。由於類本身控制連接,所以該鏈接實際上應該是內部信息。

此時您可以決定如何繼續。我建議你從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->getLink()); 

更換

mysql_something($link); 

但是你實際上必須從那裏刪除功能。所以改變$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?,瞭解有關的更多信息。

+0

謝謝Hakre對你的大力幫助。似乎我在這個舊網站上有很多工作。我的第一次測試並不確定,我想我會從零開始。我會告訴你。再次感謝你。 – guillaume

+0

好吧,把這個答案作爲一個*建議*。你應該做的第一件事是把你的代碼放在版本控制之下。然後考慮下一步。從頭開始重寫大多數情況下都不會實現,只是舊代碼的維護成本很高,而且不能輕易逃脫。答案只是表明一件事情:您可以將新舊代碼結合在一起,以便在您引入新代碼時不破壞工作代碼。關於第二個界面的部分答案不好。只是我只看到了一小部分代碼,這使得答案總是有限的。 – hakre