10/10/2018, 11:02

[PHP] Hỏi về hàm addslashes

Chào mọi người, hiện mình đang có vấn đề với hàm addslashes, mình post lên đây hy vọng mọi người hỗ trợ và cùng mình nghiên cứu giải quyết vấn đề này.

Vấn đề đặt ra như sau:

Mọi người đều biết hàm addslashes có tác dụng thêm dấu ở trước dấu '. VD:
PHP Code:
<?php
$a 
"It's John's car!";
echo 
addslashes($a); // Kết quả in ra là: It's John's car!
?>
Trước khi insert chuỗi vào CSDL thì mình đều dùng hàm addslashes này (Tất cả chuỗi trong bài viết của mình đều có dấu ' bên trong). Nếu không dùng hàm này thì insert không được và cho dù được thì khi show ra web sẽ bị lỗi.

Câu hỏi đầu tiên của mình là: Mọi người có dùng hàm addslashes trước khi insert chuỗi vào CSDL giống như mình không? Ngoài cách này thì còn cách lưu trữ chuỗi nào tốt hơn không?

Tiếp theo nữa là vấn đề về "cách đối xử" của host đối với hàm addslashes này. Mình dùng qua nhiều host của nhiều nhà cung cấp khác nhau thì phát hiện ra có sự khác biệt khi dùng hàm này. Một số host khi insert không addslashes thì dữ liệu vẫn vào được, một số lại không (Cùng code, cùng chuỗi insert). Đối với các host bắt buộc addslashes khi insert chuỗi có dấu ' thì addslashes($a) theo VD ở trên khi vào CSDL vẫn sẽ là "It's John's car!" chứ không phải là "It's John's car!". Đối với các host không bắt buộc nhập addslashes thì ngược lại.

Như vậy cùng 1 mã nguồn và up lên 2 host khác nhau thì CSDL sẽ được insert vào khác nhau. 1 có dấu và 1 không có dấu .

Với bản thân mình, khi code web muốn chạy & hiển thị đúng trên mọi host, mình luôn dùng thêm hàm stripslashes mỗi khi select chuỗi từ CSDL ra. Hàm stripslashes sẽ giúp loại bỏ những dấu và kết quả hiển thị đúng.

Tuy đã có cách giải quyết nhưng mình nghĩ vẫn chưa tối ưu lắm. Cho nên câu hỏi thứ 2 của mình là: Có cách nào giải quyết để hàm addslashes luôn chạy đúng trên mọi host không? Có hàm nào check xem host đang sử dụng có bắt buộc phải addslashes khi insert chuỗi có dấu ' không?

Ok! Hy vọng mọi người tham gia thảo luận cùng mình để code ngày càng tối ưu hơn!

Thanks!
honnhienh viết 13:06 ngày 10/10/2018
thử nghiên cuu phần mysql_real_escape_string.... gì đó thử bác
dokhacluan viết 13:08 ngày 10/10/2018
@chu thớt : đọc 1 hồi , suy nghĩ chút , nghĩ ra 1 cách ko bít giúp dc cho chủ thớt không

<?php
$a = "It's John's car!";
$a=str_replace("'","&apos;",$a);
echo $a."<hr>";
?>
trước khi insert thì replace ký tự ' thành "&apos;" ( dạng ký tự đặc biệt trong html )
hoangcn02 viết 13:15 ngày 10/10/2018
Được gửi bởi ductinh2405
Chào mọi người, hiện mình đang có vấn đề với hàm addslashes, mình post lên đây hy vọng mọi người hỗ trợ và cùng mình nghiên cứu giải quyết vấn đề này.

Vấn đề đặt ra như sau:

Mọi người đều biết hàm addslashes có tác dụng thêm dấu \ ở trước dấu '. VD:
PHP Code:
<?php
$a 
"It's John's car!";
echo 
addslashes($a); // Kết quả in ra là: It\'s John\'s car!
?>
Trước khi insert chuỗi vào CSDL thì mình đều dùng hàm addslashes này (Tất cả chuỗi trong bài viết của mình đều có dấu ' bên trong). Nếu không dùng hàm này thì insert không được và cho dù được thì khi show ra web sẽ bị lỗi.

Câu hỏi đầu tiên của mình là: Mọi người có dùng hàm addslashes trước khi insert chuỗi vào CSDL giống như mình không? Ngoài cách này thì còn cách lưu trữ chuỗi nào tốt hơn không?

Tiếp theo nữa là vấn đề về "cách đối xử" của host đối với hàm addslashes này. Mình dùng qua nhiều host của nhiều nhà cung cấp khác nhau thì phát hiện ra có sự khác biệt khi dùng hàm này. Một số host khi insert không addslashes thì dữ liệu vẫn vào được, một số lại không (Cùng code, cùng chuỗi insert). Đối với các host bắt buộc addslashes khi insert chuỗi có dấu ' thì addslashes($a) theo VD ở trên khi vào CSDL vẫn sẽ là "It's John's car!" chứ không phải là "It\'s John\'s car!". Đối với các host không bắt buộc nhập addslashes thì ngược lại.

Như vậy cùng 1 mã nguồn và up lên 2 host khác nhau thì CSDL sẽ được insert vào khác nhau. 1 có dấu \ và 1 không có dấu \.

Với bản thân mình, khi code web muốn chạy & hiển thị đúng trên mọi host, mình luôn dùng thêm hàm stripslashes mỗi khi select chuỗi từ CSDL ra. Hàm stripslashes sẽ giúp loại bỏ những dấu \ và kết quả hiển thị đúng.

Tuy đã có cách giải quyết nhưng mình nghĩ vẫn chưa tối ưu lắm. Cho nên câu hỏi thứ 2 của mình là: Có cách nào giải quyết để hàm addslashes luôn chạy đúng trên mọi host không? Có hàm nào check xem host đang sử dụng có bắt buộc phải addslashes khi insert chuỗi có dấu ' không?

Ok! Hy vọng mọi người tham gia thảo luận cùng mình để code ngày càng tối ưu hơn!

Thanks!
Bạn có thể tham khảo hàm này get_magic_quotes_gpc để kết hợp với addslashes
ductinh2405 viết 13:06 ngày 10/10/2018
Được gửi bởi honnhienh
thử nghiên cuu phần mysql_real_escape_string.... gì đó thử bác
@honnhienh: Hi, theo mình biết thì mysql_real_escape_string cũng không khác mấy so với addslashes. Khác nhau cơ bản nhất của 2 hàm này là addslashes chạy trên apache còn mysql_real_escape_string thì đẩy câu lệnh xuống cho mysql xử lý. Dùng mysql_real_escape_string có thể tốc độ câu truy vấn sẽ nhanh hơn, nhưng lại không chống được sql injections bằng addslashes.

Được gửi bởi dokhacluan
trước khi insert thì replace ký tự ' thành "&apos;" ( dạng ký tự đặc biệt trong html )
@dokhacluan: Cách của bạn mình cũng từng dùng thử rồi, khá ổn nhưng hơi thủ công và khác lạ thì phải.
PHP Code:
<?php
$a 
"It's John's car!";
echo 
str_replace("'""&apos;",$a);
?>
@All: Mọi người có ai từng dùng cách như bạn dokhacluan không ạ?

Được gửi bởi hoangcn02
Bạn có thể tham khảo hàm này get_magic_quotes_gpc để kết hợp với addslashes
@hoangcn02: Tuyện lắm! Hàm này mình nghĩ khá tuyệt để giải quyết vấn đề này.

* get_magic_quotes_gpc() sẽ trả về 1 nếu source code nằm trên host không bắt buộc phải addslashes khi insert chuỗi có ', ngược lại trả về 0.


Cảm ơn mọi người đã tham gia cùng mình giải quyết các vấn đề. Thống kê lại kết quả của chủ đề này, ta có 2 phương pháp tốt nhất để giải quyết dấu ' trong chuỗi trước khi insert vào CSDL:
  1. Cách của bạn dokhacluan: Không dùng hàm addslashes mà đơn giản chỉ dùng hàm str_replace để đổi ' thành \'. Cách này có vẻ hơi thủ công nhưng thực tế kết quả tốt và tốc độ xử lý là nhanh nhất.
  2. Cách của bạn hoangcn02: Đây là cách thường dùng của hầu hết các PHP coder. Cách này giải quyết được vấn đề nhưng phải mắc công xét if và code cũng nhiều ký tự hơn nên thời gian thực thi sẽ lâu hơn so với cách của bạn dokhacluan.

Tóm lại:
PHP Code:
addslash($a) = str_replace("'""&apos;"$a
str_replace là cách thủ công đơn giản nhất nhưng lại là tối ưu nhất!
thuyduongcd viết 13:19 ngày 10/10/2018
str_replace là cách thủ công đơn giản nhất nhưng lại là tối ưu nhất!
Đơn giản nhất thì đúng nhưng tối ưu nhất thì chưa chắc vì trong chuỗi không chắc chỉ có ký tự ' thôi. Muốn encode như vậy thi dùng htmlspecialchars() vẫn tốt hơn.
Và nếu bạn muốn trở thành coder chuyên nghiệp thì cũng phải tuân thủ quy tắc của coder, vì một mình không thể ôm hết project được mà phải cần cả tập thể. Nếu ai cũng làm theo cách riêng thì làm thế nào nó vận hành được đây.
ductinh2405 viết 13:17 ngày 10/10/2018
Được gửi bởi thuyduongcd
Đơn giản nhất thì đúng nhưng tối ưu nhất thì chưa chắc vì trong chuỗi không chắc chỉ có ký tự ' thôi. Muốn encode như vậy thi dùng htmlspecialchars() vẫn tốt hơn.
Và nếu bạn muốn trở thành coder chuyên nghiệp thì cũng phải tuân thủ quy tắc của coder, vì một mình không thể ôm hết project được mà phải cần cả tập thể. Nếu ai cũng làm theo cách riêng thì làm thế nào nó vận hành được đây.
@thuyduongcd: Trong bài viết này mình chỉ đề cập đến việc giải quyết dấu ' thôi. Hàm htmlspecialchars(Có thêm tham số ENT_QUOTES) và cũng là một trong những cách để giải quyết vấn đề đã đặt ra.

Bản thân mình cũng đang code PHP để mưu sinh, nhưng mình thì luôn đề cao kết quả cho dù để đạt được kết quả đó có thể phải rời xa cách làm truyền thống. Ý kiến của bạn rất phù hợp để coder làm việc nhóm hiệu quả. Tuy nhiên, có lẽ mình sẽ tiếp tục đi theo hướng khác biệt này và hy vọng nó sẽ thành công. Nhóm của mình luôn họp mặt và công bố những gì cần thay đổi trong cách code để project đạt được kết quả như ý nhất mà! ^^
datgs viết 13:19 ngày 10/10/2018
Câu trả lời nằm ở đây http://i-php.net/2011/02/php-addslas...sql-injection/. mysql_real_escapse_string là tốt nhất cho các truy vấn với MySQL và tương tự mỗi một database PHP hỗ trợ các kiểu escapse riêng.

Thông điệp của mình là không có cái gì được tạo ra là không có mục đích, đặc biệt là để đối xử với các giải pháp chung. Sử dụng những cái có sẵn bao giờ cũng tốt hơn cái mà bạn tạo ra (nhiều cái đầu đã lao tâm khổ tứ cho vấn đề đó rồi).
ductinh2405 viết 13:07 ngày 10/10/2018
Dùng giải pháp chung thì sẽ rất đỡ đau đầu và tiết kiệm được nhiều thời gian. Tuy nhiên, với những project đặc biệt thì đôi khi phải chịu khó suy nghĩ và làm những điều "khác thường" chút xíu.
datgs viết 13:09 ngày 10/10/2018
Được gửi bởi ductinh2405
Dùng giải pháp chung thì sẽ rất đỡ đau đầu và tiết kiệm được nhiều thời gian. Tuy nhiên, với những project đặc biệt thì đôi khi phải chịu khó suy nghĩ và làm những điều "khác thường" chút xíu.
Chuẩn, As our cases are new we have to think and act anew . Tuy nhiên với các sản phẩm dành cho người dùng cuối. Việc đi vòng tiềm ẩn rất nhiều lỗi. Giả sử bạn có 10.000 dòng code đều không sử dụng các giải pháp chung. Trong 10000 dòng đó có khoảng 100 điểm cần giải pháp chung. Bạn sẽ có thể bị khách hàng phàn nàn khoảng 100 lần đấy

Lập trình viên làm việc sáng tạo, chỉ một phần nhỏ thôi. Phần quan trọng là ... sử dụng đúng giải pháp.

Còn sáng tạo nên để dành cho việc phát triển các tính năng.
Bài liên quan
0