假设我在一个论坛上工作,当然有用户,以及添加评论、开放主题等的选项。
现在对于这个东西,我需要一些功能,例如:登录/注销;添加/编辑/删除评论;私人消息..好吧,你明白了。
因此,如果我使用 oop 来执行此操作,那么对于所有这些选项,仅使用一个巨大的类会非常笨拙,而且我认为效率会降低,因此最好为上述每个类创建一个类。但问题是,如果这样做,我需要在每个类中建立与数据库的连接,而同时使用多个连接到同一个数据库会浪费资源。那么,这个问题的最佳解决方案是什么?:-)
In OOP you just create your objects. They do what they should do.
And when I write, you just create the objects, I mean that literally. There is no database so far, you don't care how these objects are stored yet.
Write your unit tests, get the objects to work what they should do.
Then start to bring those objects together. They still don't need to be stored. Just bring them together, like:
$user = $session->getUser();
$user->login(username, password);
And so on. Your application should just not need to care about the database.
Then when you finalize your application, next to where you instantiate the objects in each action, you also instantiate a DataMapper
that is able to fetch object from the data-store.
User <--> UserMapper <--> Datastore
As you can see, the User
object knows nothing about the Datastore
, not even about the UserMapper
. The UserMapper
knows what a User
is, but as written above, this comes later, so first get your important objects running, write the unit tests for them and then the integration tests and then when you've done that, start thinking about the database - whatever it will be then that time.
OOP is all about the logical segregation of code into dedicated blocks, but with a basis for sharing, inheritance and interoperability where required. With this in mind, declare the connection as a static property of the class (since there is presumably no need for it to be recreated for each instance).
This would work (and be pretty efficient) whether your main code blocks are class extensions, or methods of, your base Forum class.
class Forum {
public static $db = "I'm the database!";
public function post() {
echo self::$db;
}
}
class Post extends Forum {
public function getDB() {
echo parent::$db;
}
}
//post as its own sub-class
$post = new Post();
$post->getDB(); //I'm the database!
//post as method of class
$forum = new Forum();
$forum->post(); //I'm the database!
[EDIT] - it seems PHP cannot parse non-trivial values for static properties, i.e. they cannot be expressions or calls to functions.
One way round this is as follows:
class Forum {
static $db;
public function post() {
self::$db; //do something with DB connection here
}
}
Forum::$db = new mysqli(); //<-- the key - screw you, static property limitations
class Post extends Forum {
public function getDB() {
parent::$db; //do something with DB connection here
}
}
...i.e. we declare the static property (our DB handler) after the class declaration. Someone else might know a more graceful way of doing this.
使用此代码。以 Databasehandler.php 的名称保存它。并将它包含在您的 index.php 中,并在整个项目中需要时使用它的功能。它使用 PDO 对您的数据库进行安全查询。可能需要进行细微的修改。
<?php
Class DatabaseHandler
{
private static $_mhandler;
private function __construct() { }
private static function GetHandler()
{
if(!isset($_mhandler))
{
try
{
self::$_mhandler = new PDO (PDO_DSN, DB_USERNAME, DB_PASSWORD, array(PDO::ATTR_PERSISTENT => DB_PERSISTENCY));
self::$_mhandler -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
self::Close();
trigger_error($e -> getMessage(), E_USER_ERROR);
}
return self::$_mhandler; // Returning DATABASE Handler Object.
}
}
public static function Close()
{
$_mhandler = NULL;
}
public static function Execute($sqlquery, $params = NULL)
{
try
{
$dbh = self::GetHandler(); //DataBaseHandler
$sth = $dbh -> prepare($sqlquery); //StatementHandler
$sth -> execute($params);
}
catch(PDOException $e)
{
self::Close();
trigger_error($e -> getMessage(), E_USER_ERROR);
}
}
public static function GetAll($sqlquery, $params = NULL, $fetchstyle = PDO::FETCH_ASSOC)
{
$result = NULL;
try
{
$dbh = self::GetHandler();
$sth = $dbh -> prepare($sqlquery);
$sth -> execute($params);
$result = $sth -> fetchAll($fetchstyle);
}
catch(PDOException $e)
{
self::Close();
trigger_error($e -> getMessage(), E_USER_ERROR);
}
return $result;
}
public static function GetRow($sqlquery, $params = NULL, $fetchstyle = PDO::FETCH_ASSOC)
{
$result = NULL;
try
{
$dbh = self::GetHandler();
$sth = $dbh -> prepare($sqlquery);
$sth -> execute($params);
$result = $sth -> fetch($fetchstyle);
}
catch(PDOException $e)
{
self::Close();
trigger_error($e -> getMessage(), E_USER_ERROR);
}
return $result;
}
public static function GetOne($sqlquery, $params = NULL)
{
$result = NULL;
try
{
$dbh = self::GetHandler();
$sth = $dbh -> prepare($sqlquery);
$sth -> execute($params);
$result = $sth -> fetch(PDO::FETCH_NUM);
$result = $result[0];
}
catch(PDOException $e)
{
self::Close();
trigger_error($e -> getMessage(), E_USER_ERROR);
}
return $result;
}
}
?>