|
|
|
สอบถามการใช้ mysql_real_escape_string ทีครับ มันไม่ยอมใส่ \ ให้ |
|
|
|
|
|
|
|
จากบทความนี้: เลิกใช้ฟังก์ชั่น mysql_xxxxx() ที่ล้าสมัย (deprecated) และเปลี่ยนมาใช้ MySQLi กันดีกว่า
Code (PHP)
// สร้างคลาสขึ้นมาใหม่โดยขยายคลาส MySQLi
class ExtendedMySQLi extends MySQLi
{
public function __construct($host, $username, $password, $dbname)
{
// เราจำเป็นต้องเรียก constructor ของคลาสแม่ทุกครั้ง เพื่อให้คลาสลูกทำงานได้อย่างถูกต้อง
parent::__construct($host, $username, $password, $dbname);
}
// ประกาศ method ใหม่ที่เราต้องการ
// โดยในที่นี่เราจะสร้าง method ที่สามารถแทนที่ตัวแปรที่ผ่านการ escape แล้วลงใน query
// และส่ง query ให้ MySQL Server ในคราวเดียว
public function queryf($query)
{
// ตัวแปรพิเศษที่จะทำให้การทำงานเร็วขึืน ใช้เพื่อเติมเต็ม array ที่จะส่งไปให้ vsprintf
// จะได้ไม่เกิด error ในกรณีที่ผู้ใช้กำหนดตัวแปรน้อยกว่าจำนวนตัวแทนที่ใน $query
static $fill = array(
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
);
// escape ตัวแปรทุกตัว
foreach (array_slice(func_get_args(), 1) as $arg) {
$args[] = $this->real_escape_string($arg);
}
return isset($args)
// หากมีตัวแปรส่งมา ก็ให้เรียกใช้ vsprintf() เพื่อแทนที่ค่าตัวแปรลงใน query
? $this->query(vsprintf($query, $args + $fill))
// นอกนั้นก็ query ตามปกติ
: $this->query($query);
}
}
$mysqli = new ExtendedMySQLi('localhost', 'root', '', 'testdb');
$result = $mysqli->queryf("SELECT '%s'", "Cookie's cat");
$row = $result->fetch_row();
echo $row[0];
พอดีว่าผมต้องกลับไปใช้ mysql เพราะเซิฟเวอร์เค้าปิด mysqli ผมเลยเอาฟังก์ชันนี้เข้าไปใช้ในคลาสแทน
แต่ติดปัญหาตรงที่การใช้ mysql_real_escape_string ครับ ผมเอาฟังก์ชันจากที่อื่นมาใช้อีกอันคือ
Code (PHP)
public function clean($str){
$str = @trim($str);
if(get_magic_quotes_gpc()){
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
แล้วตอนที่ escape ตัวแปร ผมก็ใช้แบบนี้
Code (PHP)
foreach (array_slice(func_get_args(), 1) as $arg) {
$args[] = $this->clean($arg);
}
แต่มันยังไม่ใส่ \ ให้นะครับ เป็นเพราะตอนที่ตัดพารามิเตอร์หรือปล่าวครับ
ตัวแปร $arg
ช่วยดูให้ทีครับ ขอบคุณครับ
Tag : PHP, MySQL
|
ประวัติการแก้ไข 2013-08-22 15:29:56
|
|
|
|
|
Date :
2013-08-22 15:27:31 |
By :
fogza |
View :
2585 |
Reply :
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
เดียวขอคุณแมวมาตอบให้ครับ
|
|
|
|
|
Date :
2013-08-22 16:59:00 |
By :
mr.win |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
เอาโค้ดที่คุณปรับเปลี่ยนมาดูทั้งคลาสเลยครับ เพราะว่าอาจจะผิดตรงอื่นผิดหรือเปล่า
|
|
|
|
|
Date :
2013-08-22 17:04:22 |
By :
phpinfo |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ตามนี้ครับ
คลาส db นี้ผมดูจากพี่ บัณฑิต แสนคำอีกทีครับ
class_db.inc.php
<?php
class clssDB {
private $rs;
private $_fetch_assoc = array();
public function __construct($host, $root, $password, $dbname)
{
$conn = mysql_connect($host,$root,$password) or die(mysql_error());
mysql_query("SET NAMES utf8",$conn);
mysql_select_db($dbname);
}
public function clean($str){
$str = @trim($str);
if(get_magic_quotes_gpc()){
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
public function query($query)
{
// ตัวแปรพิเศษที่จะทำให้การทำงานเร็วขึืน ใช้เพื่อเติมเต็ม array ที่จะส่งไปให้ vsprintf
// จะได้ไม่เกิด error ในกรณีที่ผู้ใช้กำหนดตัวแปรน้อยกว่าจำนวนตัวแทนที่ใน $query
static $fill = array(
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
);
// escape ตัวแปรทุกตัว
foreach (array_slice(func_get_args(), 1) as $arg) {
$args[] = $this->clean($arg);
}
return isset($args)
// หากมีตัวแปรส่งมา ก็ให้เรียกใช้ vsprintf() เพื่อแทนที่ค่าตัวแปรลงใน query
? $this->rs = mysql_query(vsprintf($query, $args + $fill))
// นอกนั้นก็ query ตามปกติ
: $this->rs = mysql_query($query);
}
public function num_rows()
{
if (empty($this->rs)) {
return false;
} else {
$data = mysql_num_rows($this->rs);
}
return $data;
//return mysql_num_rows($this->rs);
}
public function fetch_assoc()
{
if (empty($this->rs)) {
return false;
} else {
$data = mysql_fetch_assoc($this->rs);
}
return $data;
}
public function fetch_all_assoc()
{
if(count($this->_fetch_assoc)>0)
{
return $this->_fetch_assoc;
}
else
{
while($row = mysql_fetch_assoc($this->rs))
{
$this->_fetch_assoc[] = $row;
}
return $this->_fetch_assoc;
}
}
public function last_id() {
if ($id = mysql_insert_id()) {
return $id;
} else {
return false;
}
}
function __destruct()
{
mysql_close();
}
}
?>
ตรง
Code (PHP)
public function clean($str){
$str = @trim($str);
if(get_magic_quotes_gpc()){
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
มันไม่ยอมใส่ \ ให้นะครับ
|
|
|
|
|
Date :
2013-08-22 17:43:03 |
By :
fogza |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
เท่าที่ดูโค้ดก็ไม่ได้ผิดอะไร
แต่ที่มันไม่ยอมใส่ \ ให้เพราะยังไม่ได้ connect กับฐานข้อมูลหรือเปล่าครับ (แต่ดูจากโค้ด ก็น่าจะเชื่อมต่อแล้ว)
เพราะว่า mysql_real_escape_string() จะทำงานได้นั้น ต้องการการเชื่อมต่อกับฐานข้อมูลครับ
และขึ้นอยู่กับ setting ของ MySQL Server ด้วยว่าตั้งรูปแบบของการ escape ไว้อย่างไร
ซึ่งแม้จะไม่ใส่ \ แต่ก็อาจจะใส่ '' ให้ครับ ซึ่งเป็นการ escape เหมือนกัน
ตรงนี้แหละที่ทำให้ mysql_escape_string() กับ mysql_real_escape_string() นั้นต่างกัน
เพราะตัวแรกไม่สนใจ config ของเซิร์ฟเวอร์และจะใส่ \ ตลอด แต่ตัวหลังต้องเชื่อมต่อกับเซิร์ฟเวอร์เพื่อใช้รูปแบบการ escape ตามเซิร์ฟเวอร์
เสริมให้นิดนึงนะครับ ตรงฟังก์ชั่น clean() ไม่จำเป็นต้องใช้ @ operator กับ trim() ครับ ไม่มีประโยชน์เลย และทำให้ช้าลงเสียเปล่าๆ
$str = trim($str);
เฉยๆ ก็พอครับ
|
|
|
|
|
Date :
2013-08-22 17:55:57 |
By :
phpinfo |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
งงมากครับ มันก็ควรจะทำงานได้ปกติ ตอนนี้เหลือสาเหตุเดียวแล้ว
ตอนเรียกใช้ ได้แทนที่ %s ลงใน query หรือเปล่าครับ
// %s จะเปลี่ยนเป็น Cookie\'s cat
$db->query(" SELECT '%s' ", "Cookie's cat");
แบบนี้ไม่ได้นะครับ
$db->query(" SELECT '$a' ");
|
|
|
|
|
Date :
2013-08-23 13:44:33 |
By :
phpinfo() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
งั้นก็ไม่ทราบแล้วล่ะครับว่าเป็นเพราะอะไร เพราะดูแล้วมันไม่มีอะไรผิดน่ะครับ
|
|
|
|
|
Date :
2013-08-23 14:44:06 |
By :
phpinfo() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
หรือลองเปลี่ยนส่วน query() เป็นแบบนี้ดูครับ
public function query($query)
{
// ตัวแปรพิเศษที่จะทำให้การทำงานเร็วขึืน ใช้เพื่อเติมเต็ม array ที่จะส่งไปให้ vsprintf
// จะได้ไม่เกิด error ในกรณีที่ผู้ใช้กำหนดตัวแปรน้อยกว่าจำนวนตัวแทนที่ใน $query
static $fill = array(
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
);
$args = array($query);
// escape ตัวแปรทุกตัว
foreach (array_slice(func_get_args(), 1) as $arg) {
$args[] = $this->clean($arg);
}
return $this->rs = mysql_query(call_user_func_array('sprintf', $args + $fill));
}
|
|
|
|
|
Date :
2013-08-23 14:55:09 |
By :
phpinfo() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ผมพอจะนึกสาเหตุออกแล้ว คุณใช้ PHP เวอร์ชั่นไหนครับ 5.2 ต้นๆ หรือต่ำกว่าใช่หรือเปล่าครับ
|
|
|
|
|
Date :
2013-08-23 15:22:33 |
By :
phpinfo() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
สาเหตุคือ func_get_args() ครับ มันไม่สามารถใช้เป็น argument ของฟังก์ชั่นได้ใน PHP5.2 หรือต่ำกว่า
จะต้องให้ค่าลงในตัวแปรชั่วคราวก่อน แล้วค่อยนำไปใช้
ขอบคุณที่แจ้งมานะครับ จะได้เอาไปแก้ในบทความด้วย
แก้เป็นแบบนี้ครับ
public function query($query)
{
// ตัวแปรพิเศษที่จะทำให้การทำงานเร็วขึืน ใช้เพื่อเติมเต็ม array ที่จะส่งไปให้ vsprintf
// จะได้ไม่เกิด error ในกรณีที่ผู้ใช้กำหนดตัวแปรน้อยกว่าจำนวนตัวแทนที่ใน $query
static $fill = array(
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null,
);
// escape ตัวแปรทุกตัว
$tmp = func_get_args(); // ใส่ลงในตัวแปรชั่วคราวก่อน
foreach (array_slice($tmp, 1) as $arg) { // แล้วจึงนำไปใช้เป็น argument ของ array_slice()
$args[] = $this->clean($arg);
}
return isset($args)
// หากมีตัวแปรส่งมา ก็ให้เรียกใช้ vsprintf() เพื่อแทนที่ค่าตัวแปรลงใน query
? $this->rs = mysql_query(vsprintf($query, $args + $fill))
// นอกนั้นก็ query ตามปกติ
: $this->rs = mysql_query($query);
}
|
|
|
|
|
Date :
2013-08-23 15:29:10 |
By :
phpinfo() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
เอิ่ม ใช้ php5.5.1 มันใช้ mysql ธรรมดาได้เหรอครับ เพราะ 5.5 มันตัด mysql ธรรมดาทิ้งไปแล้วนะครับ
|
|
|
|
|
Date :
2013-08-23 16:05:48 |
By :
phpinfo() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Load balance : Server 04
|