【问题标题】:OOP php5 structureOOP php5 结构
【发布时间】:2009-08-17 16:37:53
【问题描述】:

我一直在尝试制作 OOP PHP5 代码。但我认为我的尝试很笨拙。这些是我的问题:

  • 它们是一种更好、更精简的方式来包含数据库配置信息吗?
  • 我能否以某种方式避免在我创建的每个函数中声明 $db = new Db()?
  • 我应该使用 PEAR 作为数据库抽象层而不是 Mysqli_database.php 吗?

Mysqli_database.php

<?php
class Db {
    private $connection;

    private function open_connection() {
        if (file_exists('config.inc.php')) {
            require('config.inc.php');
        } else {
            require('../config.inc.php');
        }
        try
        {
            $this->connection = mysqli_connect($dbhost,$dbuser,$dbpass,$dbname);
        }
        catch (Exception $e)
        {
            throw $e;
        }
    }
    private function close_connection() {
        try
        {
            mysqli_close($this->connection);
        }
        catch (Exception $e)
        {
            throw $e;
        }
    }
    public function query($query) {
        try
        {
            $this->open_connection();
            $result = mysqli_query($this->connection,$query);
            return $result;
        }
        catch (Exception $e)
        {
            throw $e;
        }
        $this->close_connection();
    }
    public function fetchArray($query) {
        $row = mysqli_fetch_assoc($query);
        return $row;
    }
    public function count_rows($query) {
        $row = mysqli_num_rows($query);
        return $row;
    }
    public function rows_affected() {
        $row = mysqli_affected_rows($this->connection);
        return $row;
    }
    public function created_id() {
        $row = mysqli_insert_id($this->connection);
        return $row;
    }
}
?>

Test_data.php

<?php
class Test_data {
    public function show_text() {
        $db = new Db();
        $sql = $db->query("SELECT * FROM test_table");
        $row = $db->fetchArray($sql);
        echo 'This is the output: '.$row['text'];
    }
}
?>

config.inc.php

<?php
$dbname     = 'database_name';
$dbhost     = 'localhost';
$dbuser     = 'database_user';
$dbpass     = 'database_password';
?>

includes.php

<?php
require_once('config.inc.php');
require_once('Mysqli_database.php');
$db = new Db();
$test_data = new Test_data();
?>

index.php

<?php
require_once('includes.php');
$test_data->show_text();
?>

【问题讨论】:

    标签: php oop mysqli pear


    【解决方案1】:

    配置信息是个人喜好问题。但它会更好地存储在配置对象中,并以更面向对象的方式检索,然后包括来自另一个文件的全局变量。

    您可以使用singleton pattern 来绕过创建新对象。

    您选择的抽象层越多,从一个数据库移动到另一个数据库就越容易。你也可以看看PDO

    【讨论】:

    • 对,配置信息的持有是个人喜好问题,我喜欢用CONSTANTS,那么你就知道它在全局范围内不会改变。
    【解决方案2】:

    建立数据库连接有一些非常常见的模式:Singleton、Factory,有时还有 Registry。

    这是一个人的样子。

    <?php
    
    class DbConn
    {
      const CONN_DEV_1  = 'dev.db1';
      const CONN_PROD_1 = 'prod.db1';
      const CONN_DEV_2  = 'dev.db2';
      const CONN_PROD_2 = 'prod.db2';
    
      protected static $instances = array();
    
      protected $conn;
    
      public static function factory( $database, $env )
      {
        $connectionName = "$env.$database";
        if ( !isset( self::$instances[$connectionName] ) )
        {
          switch ( $connectionName )
          {
            case self::CONN_DEV_1:
              $dbname = 'dev1';
              $dbhost = 'localhost';
              $dbuser = 'database_user';
              $dbpass = 'database_password';
              break;
            case self::CONN_PROD_1:
              $dbname = 'prod1';
              $dbhost = 'some.server';
              $dbuser = 'database_user';
              $dbpass = 'database_password';
              break;
            case self::CONN_DEV_2:
              $dbname = 'dev2';
              $dbhost = 'localhost';
              $dbuser = 'database_user';
              $dbpass = 'database_password';
              break;
            case self::CONN_PROD_2:
              $dbname = 'prod2';
              $dbhost = 'some.server';
              $dbuser = 'database_user';
              $dbpass = 'database_password';
              break;
            default:
              throw new Exception( 'Unrecognized database connection!' );
          }
          self::$instances[$connectionName] = new self( $dbhost,$dbuser,$dbpass,$dbname );
        }
        return self::$instances[$connectionName];
      }
    
      private function __construct( $dbhost, $dbuser, $dbpass, $dbname )
      {
        $this->conn = mysqli_connect( $dbhost, $dbuser, $dbpass, $dbname );
      }
    
      /* all your other methods here */
    }
    

    在使用中

    $db1 = DbConn::factory( 'db1', 'dev' );
    

    显然,这里的重点是从当前应用程序配置中提取 $env 的值,无论它来自哪里。

    现在就使用而言,通常您希望传递/处理函数/类数据库连接,而不是让它们自己负责建立连接。这提供了更松散的耦合。使用您的示例:

    <?php
    class Test_data
    {
        protected $db;
    
        public function __construct( DbConn $db )
        {
            $this->db = $db;
        }
    
        public function show_text()
        {
            $sql = $this->db->query( "SELECT * FROM test_table" );
            $row = $this->db->fetchArray($sql);
            echo 'This is the output: '.$row['text'];
        }
    }
    ?>
    

    【讨论】:

      【解决方案3】:

      至于在每个函数中捕获一个实例,像这样的 DB 对象是为单例模式提供的事实上的示例。它真的很适合这里。

      这是一个粗略的例子:

      class DB
      {
      
         // Private Constructor so external code cannot directly instantiate
         private function __construct() {  
      
         }
      
         public static function instance() {
           static $instance = false;
      
           if (!$instance)
             $instance = new DB();
      
           return $instance;
      
         }
      
      }
      

      还有一个小变化,如果你想打开多个数据库连接(到不同的数据库),那么实例方法是这样的:

      public static function instance($dsn) {
         static $instances = array();
      
         if (!isset($instances[$dsn]))
             $instances[$dsn] = new DB($dsn);
      
         return $instances[$dsn];
      
      }
      

      【讨论】:

        猜你喜欢
        • 2012-07-26
        • 1970-01-01
        • 1970-01-01
        • 2010-12-01
        • 1970-01-01
        • 2015-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多