我一直在尝试制作OOP PHP5代码。但我认为我的尝试很笨拙。这些是我的问题:
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();
?>
答案 0 :(得分:3)
配置信息是品味的问题。但它最好存储在配置对象中,并以更多OO方式进行检索,然后包含来自另一个文件的全局变量。
您可以使用singleton pattern来创建新对象。
您选择的抽象层越多,从一个数据库移动到另一个数据库就越容易。您还可以查看PDO。
答案 1 :(得分:3)
建立数据库连接有一些非常常见的模式: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'];
}
}
?>
答案 2 :(得分:2)
对于捕获每个函数中的实例,像这样的DB对象是Singleton模式的事实示例。它真的非常适合这里。
这是一个粗略的例子:
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];
}