2012-12-26 64 views
1

所以我試圖做一個簡單的方法來管理一堆mysql連接。PHP OOP - 如何將mysqli方法繼承到其他類?

我有2個基本類:serverConnections

服務器剛剛設置爲在您看到它時保存一行數據。 (有沒有更好的方法來做到這一點?)

在連接我想通過它的ID調用連接並創建連接,並能夠查詢它。

這適用於mysql庫,但是當我嘗試使用mysqli庫時,它不會將$mysqli作爲連接句柄傳遞給$msi$mysqli->query()工程,但$msi->query()沒有。

PHP Fatal error: Call to undefined method Connections::query() 

我需要擴展/實現與庫MySQLi我的連接類或以不同的方式返回$mysqli

謝謝!

<?php 
    class server { 
     public $id, $type, $subid, $host, $user, $pw, $port, $db; 

     public function __construct($id,$type,$subid,$host,$user,$pw,$port,$db) { 
      $this->id = $id; 
      $this->type = $type; 
      $this->subid = $subid; 
      $this->host = $host; 
      $this->user = $user; 
      $this->pw = $pw; 
      $this->port = $port; 
      $this->db = $db; 
     } 
    } 

    class Connections { 
     public $servers; 

     function __construct($id) { 
      $this->servers[] = new server("mysql","mysql","main","hostname","username","password","3306","dbname"); 
      $this->servers[] = new server("mysql2","mysqli","main","hostname","username","password","3306","dbname"); 

      $rt = null; 
      foreach($this->servers as $server) { 
       if ($id == $server->id) { 
        $rt = $server; 
        break; 
       } 
      } 

      if($rt->type == "mysql"){ 
       $con = mysql_connect($rt->host,$rt->user,$rt->pw); 
       mysql_select_db($rt->db, $con); 
        if($con) { return $con; } 
      } 
      elseif($rt->type == "mysqli"){ 
       $mysqli = new mysqli($rt->host, $rt->user, $rt->pw, $rt->db, $rt->port); 
         if ($mysqli->connect_errno) { 
           echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error; 
         } 
         else{ 
           return $mysqli; 
         } 
      } 

     } 
    } 

    /* 
    ### this works 
    $nc = new Connections("mysql"); 
    $q = "select 1+2 as asdf"; 
    $r = mysql_query($q); 
    while($row = mysql_fetch_array($r)){ 
     echo $row['asdf']."\n"; 
    } 
    */ 

    #### this does not work 
    $msi = new Connections("mysql2"); 
    $res = $msi->query("SELECT 2+2 as asdf"); 
    while($row = $res->fetch_assoc()){ 
     echo $row['asdf']."\n"; 
    } 
    ?> 

編輯 - >我是能夠使這項工作以不同的方式與另一篇文章here

這裏是我修改後的代碼的幫助:

<?php 
class server { 
    public $id, $type, $subid, $host, $user, $pw, $port, $alt; 
    public function __construct($id,$type,$subid,$host,$user,$pw,$port,$alt) { 
     $this->id = $id; 
     $this->type = $type; 
     $this->subid = $subid; 
     $this->host = $host; 
     $this->user = $user; 
     $this->pw = $pw; 
     $this->port = $port; 
     $this->alt = $alt; 
    } 
} 

class MySQLiContainer extends SplObjectStorage{ 
    var $server, $servers; 
    function __construct($id) { 
     $this->servers[] = new server("mysql","mysql","main","hostname","username","password","3306","dbname"); 
     $this->servers[] = new server("mysql2","mysqli","main","hostname","username","password","3306","dbname"); 

     foreach($this->servers as $server) { 
       if ($id == $server->id) { 
        $this->server = $server; 
        break; 
       } 
      } 
    } 
    public function newConnection() { 

    $mysqli = new mysqli($this->server->host, $this->server->user, $this->server->pw, $this->server->alt, $this->server->port); 
    $this->attach($mysqli); 
    return $mysqli; 
    } 
} 

//usage 
$mysqliContainer = new MySQLiContainer("mysql2"); 
$c1 = $mysqliContainer->newConnection(); 
$res = $c1->query('SELECT 2+4 as asdf'); 
while($row = $res->fetch_assoc()){ 
    echo $row['asdf']."\n"; 
} 
echo $c1->host_info . "\n"; 

$ms2 = new MySQLiContainer("mysql"); 
$c2 = $ms2->newConnection(); 
$r = $c2->query('SELECT 2+4 as dfdf'); 
while($ra = $r->fetch_assoc()){ 
    echo $ra['dfdf']."\n"; 
} 
echo $c2->host_info . "\n"; 
?> 

回答

2

你的代碼基於一個錯誤的前提:你可以從構造函數中返回任何東西。

你不能從構造函數返回任何東西。 new運算符的結果始終是該類的一個實例。

如果不清楚,請給我留言。由於return的值被丟棄,所以不能從構造函數返回任何東西

你似乎想要做的是extend mysqli。

但是,你實際上並不想爲兩大理由這樣做:

  1. 的mysqli不會使它可能返回相關的類,如語句句柄或結果處理,因爲派生類。這可能會嚴重限制功能。如果您確實想要擴展數據庫處理程序,請使用PDO
  2. 你爲什麼要編寫自己的數據庫抽象庫?有數十個其中。去看看Zend Db或任何教義使用。它們將對您有用 - 由合格的第三方創建並經過良好測試。
+0

感謝您澄清我對__construct()方法的誤解。 我正在嘗試編寫自己的數據庫抽象庫,因爲我有多個使用多個負載均衡EC2實例後面的共享Amazon RDS實例的站點。我想以某種方式對數據進行分片並將非關鍵信息從RDS實例中提取出來,並在EC2實例上運行它以增加整體連接容量,同時不增加當前成本。 – neutron

+0

我不羨慕那個任務。祝你好運! – Charles