PHP Class - 如何只连接一次数据库
PHP Class - How to connect to the database only once
我试着做一个简单的SQLclass。
只有一个问题:
function __classDBREAD($table, $where, $value, $back)
{
$link = mysql_connect('127.0.0.1','XXXX','XXXXXX');
mysql_select_db('XXXX', $link);
mysql_set_charset('utf8');
$sql = "SELECT * FROM $table WHERE $where = '$value' LIMIT 1";
$result = mysql_query($sql, $link) or die(mysql_error());
$row = mysql_fetch_assoc($result);
return $row[$back];
mysql_close($link);
}
现在,我怎样才能只连接到 SQL 一次并添加诸如“dbUpdate”、“dbInsert”和“dbRead”之类的函数而不是每次都连接到数据库?
teamspeak 连接也是如此。
举个例子:
require_once ("lib/TeamSpeak3/TeamSpeak3.php");
$ts3_VirtualServer = TeamSpeak3::factory("serverquery://XXXXX:XXXX@127.0.0.1:10011/?server_port=XXXX");
$__varTeamspeakClients = $ts3_VirtualServer->clientList();
$__intTeamspeakClientsOnline = $ts3_VirtualServer["virtualserver_clientsonline"] - 1;
$ts3_VirtualServer->request('clientupdate client_nickname='.$this->__classRndString(8));
同样的问题。当我在页面中包含 Class 时,如何只定义一次连接?
首先,您根本不应该使用 mysql_* 函数。它们已被弃用并且使用起来很危险。但是假设地,你可以使用全局变量。
在函数外部(在全局范围内)定义您的连接,然后使用 global
为您的函数提供访问权限。现在您所要做的就是在所有需要它的函数中包含这一 "global" 行。
$link = mysql_connect('127.0.0.1','XXXX','XXXXXX');
function __classDBREAD($table, $where, $value, $back)
{
global $link;
mysql_select_db('XXXX', $link);
mysql_set_charset('utf8');
$sql = "SELECT * FROM $table WHERE $where = '$value' LIMIT 1";
$result = mysql_query($sql, $link) or die(mysql_error());
$row = mysql_fetch_assoc($result);
return $row[$back];
mysqli_close($link);
}
编辑...
我没有仔细阅读。我看到您正在处理 class,因此全局变量不是最佳选择。考虑这个..
class mydbclassthing {
private $conn;
public function __construct(){
$this->conn = mysql_connect('127.0.0.1','XXXX','XXXXXX');
}
function __classDBREAD($table, $where, $value, $back)
{
$link = $this->con;
mysql_select_db('XXXX', $link);
mysql_set_charset('utf8');
$sql = "SELECT * FROM $table WHERE $where = '$value' LIMIT 1";
$result = mysql_query($sql, $link) or die(mysql_error());
$row = mysql_fetch_assoc($result);
return $row[$back];
mysql_close($link);
}
}
正如 PHP 文档所说的有关持久数据库连接 (http://php.net/manual/en/features.persistent-connections.php) 的内容:
an instance of the PHP interpreter is created and destroyed for every
page request (for a PHP page) to your web server. Because it is
destroyed after every request, any resources that it acquires (such as
a link to an SQL database server) are closed when it is destroyed. In
this case, you do not gain anything from trying to use persistent
connections -- they simply don't persist.
如果您想要更有效地重用代码,那么以 OOP 方式进行是关键。
我以后可能会想到更好的解决方案,但我会做的是使用class成员将link存储到SQL,所以他们没有每次创建:
class MySQL {
protected $mysql_link;
protected $server = '127.0.0.1'; //and so on...
public function __construct() {
$this->link = mysql_connect($this->server,$this->user,$this->password);
mysql_select_db($this->selected_db, $this->link);
mysql_set_charset('utf8');
}
public function link() {
return $this->link;
}
public function close() {
return mysql_close($this->link);
}
}
现在,在您的应用程序的其余部分使用 OOP(类似于依赖注入)会很棒,但如果不是,无论如何,您总是可以实例化您正在创建的 class 甚至存储该对象在 $_SESSION 变量中。
使用 $object->link() 将始终 return 该实例的 link,而不是每次需要执行任何查询时都创建新实例,
既然大家都在往环里扔自己的OOP(注意:我准备做PDO因为我比较懂,不过原理是一样的,只是代入连接):
<?php
class DatabaseConnection
{
# Create a singleton to store the connection for reuse
private static $singleton,
$con;
# save connection to singleton and return itself (the full object)
public function __construct()
{
# If your singleton is not set
if(!isset(self::$singleton))
# assign it this class
self::$singleton = $this;
# return this class
return self::$singleton;
}
# This is a connection method because your __construct
# is not able to return the $pdo connection
public function connection($host='hostname',$username='username',$password='password',$database='database')
{
# In the connection, you can assign the PDO to a static
# variable to send it back if it's already set
if(self::$con instanceof \PDO)
return self::$con;
# If not already a PDO connection, try and make one
try {
# PDO settings you can apply at connection time
$opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_EMULATE_PREPARES => false);
# Assign your PDO Conneciton here.
self::$con = new PDO("mysql:host={$host};dbname={$database}",$username,$password,$opts);
# Return the connection
return self::$con;
}
catch (PDOException $e){
exit('Database error');
}
}
}
您可以在函数内外的任何地方使用它,类,随您便。每次都会 return 相同的连接。如果您将 spl_autoload_register()
与自动加载功能一起使用,您将万事俱备,甚至不必每次都显式使用 require_once()
!
<?php
require_once('class.DatabaseConnection.php');
// Instantiate connection class
$pdo = new DatabaseConnection();
// Assign the connection to $con (or whatever variable you like)
$con = $pdo->connection();
请注意,singleton
模式通常很少使用。通常使用 new Objects()
而不分配 singleton
会更好。不过,我个人喜欢 singleton
用于此用途。
简单演示 - 考虑这种情况:
<?php
// Here is an example of the singlton with an echo
// which shows that the class is returning itself
// like a global
class DatabaseConnection
{
private static $singleton;
public function __construct()
{
// If your singleton is not set
if(!isset(self::$singleton)) {
echo 'NEW Object'.PHP_EOL;
// assign it this class
self::$singleton = $this;
}
else
echo 'SAME Object'.PHP_EOL;
// return this class
return self::$singleton;
}
}
function ReturnConnection()
{
return new DatabaseConnection();
}
class TestClass
{
public function __construct()
{
new DatabaseConnection();
}
}
function query($sql=false)
{
return ReturnConnection();
}
// The connection class wrapped in a function
$a = ReturnConnection();
// The function nested inside a class
$b = new TestClass();
// The function nested inside another function
$c = query();
上述 singleton
的使用将产生:
NEW Object
SAME Object
SAME Object
我试着做一个简单的SQLclass。 只有一个问题:
function __classDBREAD($table, $where, $value, $back)
{
$link = mysql_connect('127.0.0.1','XXXX','XXXXXX');
mysql_select_db('XXXX', $link);
mysql_set_charset('utf8');
$sql = "SELECT * FROM $table WHERE $where = '$value' LIMIT 1";
$result = mysql_query($sql, $link) or die(mysql_error());
$row = mysql_fetch_assoc($result);
return $row[$back];
mysql_close($link);
}
现在,我怎样才能只连接到 SQL 一次并添加诸如“dbUpdate”、“dbInsert”和“dbRead”之类的函数而不是每次都连接到数据库?
teamspeak 连接也是如此。
举个例子:
require_once ("lib/TeamSpeak3/TeamSpeak3.php");
$ts3_VirtualServer = TeamSpeak3::factory("serverquery://XXXXX:XXXX@127.0.0.1:10011/?server_port=XXXX");
$__varTeamspeakClients = $ts3_VirtualServer->clientList();
$__intTeamspeakClientsOnline = $ts3_VirtualServer["virtualserver_clientsonline"] - 1;
$ts3_VirtualServer->request('clientupdate client_nickname='.$this->__classRndString(8));
同样的问题。当我在页面中包含 Class 时,如何只定义一次连接?
首先,您根本不应该使用 mysql_* 函数。它们已被弃用并且使用起来很危险。但是假设地,你可以使用全局变量。
在函数外部(在全局范围内)定义您的连接,然后使用 global
为您的函数提供访问权限。现在您所要做的就是在所有需要它的函数中包含这一 "global" 行。
$link = mysql_connect('127.0.0.1','XXXX','XXXXXX');
function __classDBREAD($table, $where, $value, $back)
{
global $link;
mysql_select_db('XXXX', $link);
mysql_set_charset('utf8');
$sql = "SELECT * FROM $table WHERE $where = '$value' LIMIT 1";
$result = mysql_query($sql, $link) or die(mysql_error());
$row = mysql_fetch_assoc($result);
return $row[$back];
mysqli_close($link);
}
编辑...
我没有仔细阅读。我看到您正在处理 class,因此全局变量不是最佳选择。考虑这个..
class mydbclassthing {
private $conn;
public function __construct(){
$this->conn = mysql_connect('127.0.0.1','XXXX','XXXXXX');
}
function __classDBREAD($table, $where, $value, $back)
{
$link = $this->con;
mysql_select_db('XXXX', $link);
mysql_set_charset('utf8');
$sql = "SELECT * FROM $table WHERE $where = '$value' LIMIT 1";
$result = mysql_query($sql, $link) or die(mysql_error());
$row = mysql_fetch_assoc($result);
return $row[$back];
mysql_close($link);
}
}
正如 PHP 文档所说的有关持久数据库连接 (http://php.net/manual/en/features.persistent-connections.php) 的内容:
an instance of the PHP interpreter is created and destroyed for every page request (for a PHP page) to your web server. Because it is destroyed after every request, any resources that it acquires (such as a link to an SQL database server) are closed when it is destroyed. In this case, you do not gain anything from trying to use persistent connections -- they simply don't persist.
如果您想要更有效地重用代码,那么以 OOP 方式进行是关键。
我以后可能会想到更好的解决方案,但我会做的是使用class成员将link存储到SQL,所以他们没有每次创建:
class MySQL {
protected $mysql_link;
protected $server = '127.0.0.1'; //and so on...
public function __construct() {
$this->link = mysql_connect($this->server,$this->user,$this->password);
mysql_select_db($this->selected_db, $this->link);
mysql_set_charset('utf8');
}
public function link() {
return $this->link;
}
public function close() {
return mysql_close($this->link);
}
}
现在,在您的应用程序的其余部分使用 OOP(类似于依赖注入)会很棒,但如果不是,无论如何,您总是可以实例化您正在创建的 class 甚至存储该对象在 $_SESSION 变量中。
使用 $object->link() 将始终 return 该实例的 link,而不是每次需要执行任何查询时都创建新实例,
既然大家都在往环里扔自己的OOP(注意:我准备做PDO因为我比较懂,不过原理是一样的,只是代入连接):
<?php
class DatabaseConnection
{
# Create a singleton to store the connection for reuse
private static $singleton,
$con;
# save connection to singleton and return itself (the full object)
public function __construct()
{
# If your singleton is not set
if(!isset(self::$singleton))
# assign it this class
self::$singleton = $this;
# return this class
return self::$singleton;
}
# This is a connection method because your __construct
# is not able to return the $pdo connection
public function connection($host='hostname',$username='username',$password='password',$database='database')
{
# In the connection, you can assign the PDO to a static
# variable to send it back if it's already set
if(self::$con instanceof \PDO)
return self::$con;
# If not already a PDO connection, try and make one
try {
# PDO settings you can apply at connection time
$opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_EMULATE_PREPARES => false);
# Assign your PDO Conneciton here.
self::$con = new PDO("mysql:host={$host};dbname={$database}",$username,$password,$opts);
# Return the connection
return self::$con;
}
catch (PDOException $e){
exit('Database error');
}
}
}
您可以在函数内外的任何地方使用它,类,随您便。每次都会 return 相同的连接。如果您将 spl_autoload_register()
与自动加载功能一起使用,您将万事俱备,甚至不必每次都显式使用 require_once()
!
<?php
require_once('class.DatabaseConnection.php');
// Instantiate connection class
$pdo = new DatabaseConnection();
// Assign the connection to $con (or whatever variable you like)
$con = $pdo->connection();
请注意,singleton
模式通常很少使用。通常使用 new Objects()
而不分配 singleton
会更好。不过,我个人喜欢 singleton
用于此用途。
简单演示 - 考虑这种情况:
<?php
// Here is an example of the singlton with an echo
// which shows that the class is returning itself
// like a global
class DatabaseConnection
{
private static $singleton;
public function __construct()
{
// If your singleton is not set
if(!isset(self::$singleton)) {
echo 'NEW Object'.PHP_EOL;
// assign it this class
self::$singleton = $this;
}
else
echo 'SAME Object'.PHP_EOL;
// return this class
return self::$singleton;
}
}
function ReturnConnection()
{
return new DatabaseConnection();
}
class TestClass
{
public function __construct()
{
new DatabaseConnection();
}
}
function query($sql=false)
{
return ReturnConnection();
}
// The connection class wrapped in a function
$a = ReturnConnection();
// The function nested inside a class
$b = new TestClass();
// The function nested inside another function
$c = query();
上述 singleton
的使用将产生:
NEW Object
SAME Object
SAME Object