問題描述
我在 PDO 中使用抽象類.我想知道是否有必要每次都將 $conn
變量置空,或者它是否在腳本結束時自行置空?
I am using abstract class with PDO. I want to know if it is necessary to null the $conn
variable every time, or if it does so itself when the scripts ends?
您能否也告訴我,對于這種結構,取消 $conn
的最佳方法是什么?
Can you also tell me, with this type of structure, what would be the best way to nullify $conn
?
abstract class DB_Connection
{
protected static $tbl_admin = "prof_admin";
//protected static $tbl_admin = "prof_admin";
protected static function obj_db()
{
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "salmanshahid";
$conn = null;
try
{
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
}
protected static function select($query)
{
try
{
$conn = self::obj_db();
$stmt = $conn->prepare($query);
$stmt->execute();
// set the resulting array to associative
$stmt->setFetchMode(PDO::FETCH_ASSOC);
return $stmt->fetchAll();
}
catch(PDOException $e)
{
throw new Exception("Error In SELECT STATMENT: " . $e->getMessage());
}
}
protected static function insert($query)
{
try
{
$conn = self::obj_db();
$stmt = $conn->prepare($query);
$stmt->execute();
}
catch(PDOException $e)
{
throw new Exception("Error In INSERT STATMENT: " . $e->getMessage());
}
}
}
推薦答案
或者如果腳本結束時它自己這樣做?
or if it does so itself when the scripts ends?
是的,當然,PHP 會自動關閉并清理腳本執行過程中打開的所有資源,因此,不必擔心手動關閉它.
Yes, sure, PHP automatically close and clean up all the resources that has been opened during script execution, so, don't worry to close it manually.
無論如何,要使 conn 無效,只需將其無效:$this->conn = NULL
;
Anyway, to nullify conn, just nullify it: $this->conn = NULL
;
但與您班級的其他問題相比,所有這些都完全可以忽略不計,這些問題不安全、效率低下且無法使用.
But all that stuff is utterly negligible compared to the other problems of your class, which is insecure, inefficient and unusable.
- 首先,我不知道你為什么要把這個類抽象化.抽象類是原型類,曾經是其他類的來源.但是數據庫包裝器是一個隨時可用的最終類.我認為將其抽象化沒有任何意義.
- 錯誤報告也是多余且不一致的.在錯誤消息中添加Error In SELECT STATMENT"是非常無用的.而連接錯誤處理顯然是錯誤的.相反,讓 PDO 拋出異常并讓它過去.它將以與您網站中的任何其他錯誤相同的方式處理.
- 下一個問題是安全性.出于某種原因,
select()
和insert()
函數都不支持 準備好的語句,這使得它們毫無用處:你可以使用 PDO::query() 相反,結果完全相同.但是你真正需要的是正確使用準備/執行,通過在查詢中使用占位符,同時將實際變量發送到execute()
; - 另一個問題是代碼重復:兩個函數幾乎相同.
- 同時這兩個函數都非常不可靠:
select()
函數僅限于一種類型的結果集,而insert()
不返回什么都沒有.相反,您可以只使用單個函數來運行所有查詢,并使其返回語句,這將非常有用.它可以讓您獲得 PDO 支持的幾十種不同格式的返回數據,甚至可以讓您從 DML 查詢中獲得受影響的行數.
- First of all, I have no idea why would you want to make this class abstract. Abstract classes are prototype classes, used to be source of other classes. But a database wrapper is rather a ready to use final class. I see no point in making it abstract.
- Error reporting is also superfluous and inconsistent. Adding "Error In SELECT STATMENT" to the error message is quite useless. While connection error handling is plainly wrong. Instead, let PDO to throw an exception and just let it go. It will be handled the same way as any other error in your site.
- Next problem is security. For some reason neither
select()
notinsert()
function supports prepared statements, which renders them quite useless: you can use PDO::query() instead, with exactly the same outcome. But what you really have to is to use prepare/execute properly, by using placeholders in the query while sending actual variables toexecute()
; - Another problem is duplicated code: both functions are pretty much the same.
- And at the same time both function are quite unreliable:
select()
function is limited to only one type of result set, whileinsert()
doesn't return anything at all. Instead, you can use just single function to run all your queries, and make it return the statement, which will be extremely useful. It will let you to get the returned data in dozens different formats supported by PDO, and even let you to get the number of affected rows from DML queries.
讓我向您推薦另一種方法,一個簡單的 PDO 包裝器,可以讓您以最簡單和安全的方式使用 PDO:
Let me suggest you another approach, a simple PDO wrapper that can let you to use PDO most simple and secure way:
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_CHAR', 'utf8');
class DB
{
protected static $instance = null;
public function __construct() {}
public function __clone() {}
public static function instance()
{
if (self::$instance === null)
{
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => TRUE,
);
$dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR;
self::$instance = new PDO($dsn, DB_USER, DB_PASS, $opt);
}
return self::$instance;
}
public static function __callStatic($method, $args)
{
return call_user_func_array(array(self::instance(), $method), $args);
}
public static function run($sql, $args = [])
{
$stmt = self::instance()->prepare($sql);
$stmt->execute($args);
return $stmt;
}
}
它非常強大、安全且易于使用.
It's extremely powerful, secure, and easy to use.
你可以使用任何 PDO 函數,只需在 DB::
前綴后添加它的調用:
You can use any PDO function by simply adding it's call after DB::
prefix:
$stmt = DB::query("SELECT * FROM table WHERE foo='bar'");
所以,首先,它是一個PDO 包裝器,它能夠通過使用神奇的__call()
方法來運行任何PDO 方法.我添加的唯一函數是 run()
.
So, in the first place, it's a PDO wrapper, which is able to run any PDO method by means of using magic __call()
method. The only function I added is run()
.
代替你自己不安全和不可靠的 select()
和 insert()
方法,讓我建議你使用一個通用的 run()
方法,無非是這三行的簡寫:
Instead of your own insecure and unreliable select()
and insert()
methods let me suggest you to use one universal run()
method, which is nothing more than a shorthand to these three lines:
$stmt = DB::prepare($query);
$stmt->execute($params);
$data = $stmt->fetch();
所以,你可以把它寫成一個簡潔的單行:
So, instead you can write it as a neat one-liner:
$data = DB::run($query, $params)->fetch();
請注意,它可以運行任何類型的查詢,并以 PDO 支持的任何格式返回結果.
Note that it can run a query of any kind and return the result in any format that PDO supports.
我寫了一篇關于這個簡單包裝器的文章,您可以在其中找到一些使用示例.所有示例代碼都可以按原樣運行,只需將其復制并粘貼到您的腳本中并設置憑據:http://phpdelusions.net/pdo/pdo_wrapper#samples
I wrote an article about this simple wrapper, where you can find some usage examples. All the example code can be run as is, just copy and paste it in your script and set up credentials: http://phpdelusions.net/pdo/pdo_wrapper#samples
這篇關于PDO 連接和抽象類的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!