PHP OOP 数据库连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20732897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP OOP database connect
提问by PiraTa
I have just started learning the concept of Object oriented programming and I've written this class with functions.
我刚刚开始学习面向对象编程的概念,我已经用函数编写了这个类。
It works fine, but I'm interested in knowing if I have done this correctly...
它工作正常,但我有兴趣知道我是否正确完成了此操作...
Here is my code:
这是我的代码:
class Database{
const DB_HOSTNAME = 'localhost';
const DB_USERNAME = 'root';
const DB_PASSWORD = 'password';
const DB_NAME = 'shop';
protected $_db_connect;
protected $_sql;
protected $_result;
protected $_row;
function db_connect(){
$this->_db_connect = mysql_connect(self::DB_HOSTNAME,self::DB_USERNAME,self::DB_PASSWORD) or die(mysql_error());
}
function slect_db(){
mysql_select_db(self::DB_NAME) or die(mysql_error());
}
function sql(){
$this->_sql = 'SELECT * FROM users';
}
function query(){
$this->_result = mysql_query($this->_sql);
}
function fetch_array(){
while($this->_row = mysql_fetch_array($this->_result)){
$username = $this->_row['user_USERNAME'];
echo "<ul>";
echo "<li>".$username."</li>";
echo "</ul>";
}
}
function db_close(){
mysql_close($this->_db_connect);
}
}
$database = new Database();
$database->db_connect();
$database->slect_db();
$database->sql();
$database->query();
$database->fetch_array();
$database->db_close();
回答by ZZPLKF
Please use PDO or MySQLi as it's more secure and mysql_* functions are deprecated as stated above, I've provided some generic code using PDO to help you with that new venture. As stated in the comments, you really shouldn't be echoing out the data if you're looking for an object oriented design, what you should be doing is after you do the query, return the rows that you fetched and from there use something such as a foreach loop to then display your data. Doing your database class this way will also make sure that multiple database connections aren't open at once! Note, this code is just for you to reference, and should be tested before use in production or anything live.
请使用 PDO 或 MySQLi,因为它更安全,并且如上所述不推荐使用 mysql_* 函数,我提供了一些使用 PDO 的通用代码来帮助您进行新的冒险。正如评论中所述,如果您正在寻找面向对象的设计,您真的不应该回显数据,您应该做的是在执行查询之后,返回您获取的行并从那里使用一些东西例如 foreach 循环,然后显示您的数据。以这种方式执行数据库类还可以确保不会同时打开多个数据库连接!请注意,此代码仅供您参考,在用于生产或任何活动之前应进行测试。
config.php:
配置文件:
<?php
//Enter your database connection details here.
$host = 'localhost'; //HOST NAME.
$db_name = 'databasename'; //Database Name
$db_username = 'root'; //Database Username
$db_password = ''; //Database Password
try
{
$pdo = new PDO('mysql:host='. $host .';dbname='.$db_name, $db_username, $db_password);
}
catch (PDOException $e)
{
exit('Error Connecting To DataBase');
}
?>
database.class.php:
数据库.class.php:
<?php
class database
{
function __construct($pdo)
{
$this->pdo = $pdo;
}
function getData()
{
$query = $this->pdo->prepare('SELECT * FROM database');
$query->execute();
return $query->fetchAll();
}
}
?>
index.php:
索引.php:
<?php
require_once 'config.php';
require_once 'database.class.php';
$db = new database($pdo);
$rows = $db->getData();
?>
回答by Félix Gagnon-Grenier
It is possible to improve the way you connect to databases using autoloading and dependency injection containers. Here is a way of using Aurynto connect to your database while being sure there is only one connection opened and not having to manually require files throughout your application.
可以使用自动加载和依赖注入容器来改进连接到数据库的方式。这是一种使用Auryn连接到数据库的方法,同时确保只打开一个连接并且不必在整个应用程序中手动请求文件。
I will cover only PDO and Auryn here. There are other dependency injection containers and notably the mysqliextension to connect to database, but the content should help you using another container if you wish to do so.
我将在这里只介绍 PDO 和 Auryn。还有其他依赖注入容器,特别是连接到数据库的mysqli扩展,但如果您愿意,内容应该可以帮助您使用另一个容器。
The database class
数据库类
Having a database class is superfluous. The \PDOclass is already providing all necessary methods to query the database. Having a database class makes you repeat the functions it provides and limits your actions (or makes you create many functions) when you want to for example use multiple different fetch styles depending on your needs in a specific method.
拥有一个数据库类是多余的。该\PDO班已经提供了所有必要的方法来查询数据库。拥有一个数据库类可以让您重复它提供的功能并限制您的操作(或让您创建许多功能),例如,当您想要根据您在特定方法中的需要使用多种不同的提取样式时。
Dependency Injection
依赖注入
If you haven't already, have a read on dependency injection. The point is that when a class needs to access the database, it should not have to bother constructing the \PDOobject, it should be constructed with it:
如果您还没有,请阅读依赖注入。重点是当一个类需要访问数据库时,它不应该费心构造\PDO对象,应该用它来构造:
class Mapper {
private $pdo;
public function __construct(\PDO $pdo) {
$this->pdo = $pdo;
}
public function createFromId($id) {
$stmt = $this->pdo->prepare("SELECT name FROM foo WHERE id=:id");
$stmt->execute([
":id" => $id,
]);
return $stmt->fetchObject();
}
}
Notice that I directly pass the \PDOobject, not a wrapper class. That way, I always have access to all of its capabilities, not only a subset of user-defined functions.
请注意,我直接传递\PDO对象,而不是包装类。这样,我始终可以访问它的所有功能,而不仅仅是用户定义函数的子集。
Dependency Injection Container
依赖注入容器
A dependency injection container helps build your classes, giving them the objects they need, and giving you great flexibility on how to actually build those objects. Here I'll only focus on configuring and sharinga \PDOobject through the use of Auryn.
依赖注入容器有助于构建您的类,为它们提供所需的对象,并在如何实际构建这些对象方面为您提供极大的灵活性。在这里我只专注于配置和共享一个\PDO通过使用Auryn的对象。
I assume you have installed the required Auryn class, the easier way is using composer. This is out of the scope of this answer, there are multiple resources on how to use it.
我假设您已经安装了所需的 Auryn 类,更简单的方法是使用composer。这超出了本答案的范围,关于如何使用它有多种资源。
Create the injector
$injector = new \Auryn\Injector();Define the
\PDOclass parameters$injector->define("PDO", [ ":dsn" => "mysql:host=localhost;charset=utf8;dbname=dbname", ":username" => "user", ":passwd" => "passwd", ":options" => [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ], ]);You can either write the configuration parameters directly here, or get them from a config file. I like having a config.ini file and using
parse_ini_file()to get my configuration options, as I can easily switch databases by editing a config file.Share the
\PDOobject$injector->share("PDO");This part is reallyimportant. This lines makes the injector give the same
\PDOobject every time it is tasked with constructing a class that needs a connection. Note that the order of the lines is not important, you can share the class before defining it, only make sure to create you database needing classes after writing both those lines.Create your objects
$mapper = $injector->make("Mapper");That's it. The injector will create your mapper object, creating the
\PDOobject if it haven't already been, passing the existing instance if it has.
创建注入器
$injector = new \Auryn\Injector();定义
\PDO类参数$injector->define("PDO", [ ":dsn" => "mysql:host=localhost;charset=utf8;dbname=dbname", ":username" => "user", ":passwd" => "passwd", ":options" => [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ], ]);您可以直接在此处编写配置参数,也可以从配置文件中获取它们。我喜欢有一个 config.ini 文件并使用它
parse_ini_file()来获取我的配置选项,因为我可以通过编辑配置文件轻松切换数据库。共享
\PDO对象$injector->share("PDO");这部分真的很重要。这行代码使得注入器
\PDO每次被分配到构造一个需要连接的类的任务时都会给出相同的对象。请注意,行的顺序并不重要,您可以在定义类之前共享该类,只需确保在编写这两行后创建需要类的数据库。创建你的对象
$mapper = $injector->make("Mapper");就是这样。注入器将创建您的映射器对象,
\PDO如果尚未创建该对象,则创建该对象,如果已存在则传递现有实例。
Autoloading
自动加载
Assuming you have used composer, you can make use of its great autoloader. Otherwise you can also roll you own autoloader.
假设您使用过 Composer,您可以使用其出色的自动加载器。否则你也可以滚动你自己的autoloader。
The point here is to stop having require()everywhere in your code, especially if you have complex class hierarchies, which you should have in a single responsibilitycompliant class system.
这里的重点是停止require()在您的代码中随处可见,特别是如果您有复杂的类层次结构,您应该在单一责任兼容的类系统中拥有这些层次结构。
Wrapping up
包起来
With this set up, you now can use the \PDOobject in your classes while being assured there will only be one instance per request, without the need to require files everywhere, and without using a singleton anti-pattern.
通过这种设置,您现在可以\PDO在类中使用该对象,同时确保每个请求只有一个实例,无需到处都需要文件,也无需使用单例反模式。
回答by Amit HJ Dimensions
$database = new Connection();
class Connection
{
function __construct()
{
switch($_SERVER['DOCUMENT_ROOT'])
{
case 'path':
$this->host = 'hostname';
$this->user = 'username';
$this->passwd = 'password';
$this->database = 'dbname';
break;
default :
$this->host = 'localhost';
$this->user = 'root';
$this->passwd = 'root';
$this->database = 'dbname';
break;
}
$this->clink = @mysql_connect($this->host,$this->user,$this->passwd);
@mysql_select_db($this->database,$this->clink);
}
}
回答by morteza
class Database{
var $last_query; //Saved result of the last query made
var $last_result; //Results of the last query made
var $func_call; //A textual description of the last query/get_row/get_var call
var $link; //database link
var $lastquery; //last query
var $result; //query result
// Connect to MySQL database
function database() {
$this->link=mysql_connect(DB_HOST, DB_USER, DB_PASS) or die('Server connexion not possible.');
//Set All Charsets to UTF8
mysql_query("SET character_set_results=utf8 , character_set_client=utf8 , character_set_connection=utf8 , character_set_database=utf8 , character_set_server=utf8");
mysql_select_db(DB_NAME) or die('Database connection not possible.');
}
/** Query the database.
* @param $query The query.
* @return The result of the query into $lastquery, to use with fetchNextObject().
*/
function query( $query ){
$this->lastquery=$query;
$this->result=@mysql_query( $query, $this->link );
return $this->result;
}
/** Do the same as query() but do not return nor store result.
* Should be used for INSERT, UPDATE, DELETE...
* @param $query The query.
* @param $debug If true, it output the query and the resulting table.
*/
function execute($query)
{
@mysql_query($query);
}
/** Convenient method for mysql_fetch_object().
* @param $result The ressource returned by query().
* @return An ARRAY representing a data row.
*/
function fetchArray($result){
if ($result == NULL)
$result = $this->result;
if ($result == NULL || mysql_num_rows($result) < 1)
return NULL;
else
return mysql_fetch_assoc($result);
}
/** Close the connecion with the database server.
* It's usually unneeded since PHP do it automatically at script end.
*/
function close()
{
mysql_close($this->link);
}
/** Get the number of rows of a query.
* @param $result The ressource returned by query(). If NULL, the last result returned by query() will be used.
* @return The number of rows of the query (0 or more).
*/
function numRows($result = NULL)
{
if ($result == NULL)
return @mysql_num_rows($this->result);
else
return mysql_num_rows($result);
}
}
回答by Siwakorn Takeaw
$objConn = new mysqlconnect(); $Conn = $objConn->setobjConnect("localhost","root","P@ssw0rd");
$objConn = new mysqlconnect(); $Conn = $objConn->setobjConnect("localhost","root","P@ssw0rd");
回答by Siwakorn Takeaw
![<?php
class mysqlconnect{
private $server=null;private $user=null;private $password=null;private $objConnect=null;
function setobjConnect($s,$u,$p){
$this->server = $s;
$this->user = $u;
$this->password = $p;
return $this->objConnect = mysql_connect($this->server,$this->user,$this->password);
}
}
$objConn = new mysqlconnect();
$Conn = $objConn->setobjConnect("localhost","root","P@ssw0rd");
if($Conn)
{
echo "Database Connect";
}
else
{
echo "Database Connect Failed.";
}
mysql_close($Conn);
?>]

