Hướng dẫn dùng postgres bytea trong PHP

TL; DR:

Xóa addslashes($data). Nó thừa ở đây.

Thoát kép .. hai lần

$data=fread($p,filesize($fi));
$data=addslashes($data);
$dat= pg_escape_bytea($data); 

Bạn đọc dữ liệu trong, thoát nó như thể nó là một chuỗi ký tự, sau đó chuyển đổi nó thành bytea octal hoặc hex Escape. Nó không bao giờ có thể hoạt động theo cách đó ngay cả khi pg_escape_byteađã lành mạnh, mà nó không phải là.

PHP's pg_escape_byteadường như thoát kép đầu ra để nó có thể được chèn vào một chuỗi ký tự. Điều này cực kỳ xấu xí, nhưng dường như không có giải pháp thay thế nào không thực hiện thoát kép này, vì vậy bạn dường như không thể sử dụng các câu lệnh được tham số hóa cho bytea trong PHP. Bạn vẫn nên làm như vậy cho mọi thứ khác.

Trong trường hợp này, chỉ cần xóa addslashesdòng cho dữ liệu được đọc trong tệp là đủ.

Trường hợp thử nghiệm cho thấy rằng pg_escape_byteacác thoát kép (và luôn sử dụng các thoát bát phân cũ, không hiệu quả):


Chạy:

php oh-the-horror.php

Kết quả:

Blah binary\\000\\001\\002\\003\\004 blah

Xem các dấu gạch chéo ngược kép? Đó là bởi vì giả sử bạn sẽ nội suy nó vào SQL dưới dạng một chuỗi, điều này cực kỳ kém hiệu quả về bộ nhớ, xấu xí và là một thói quen rất xấu. Tuy nhiên, bạn dường như không nhận được bất kỳ sự thay thế nào.

Trong số những điều khác, điều này có nghĩa là:

pg_unescape_bytea(pg_escape_bytea("\x01\x02\x03"));

... tạo ra kết quả sai , vì pg_unescape_byteathực sự không phải là đảo ngược của pg_escape_bytea. Nó cũng làm cho nó không thể cung cấp đầu ra của pg_escape_byteathành pg_query_paramsnhư một tham số, bạn phải nội suy nó trong.

Giải mã

Nếu bạn đang sử dụng PostgreSQL hiện đại, nó có thể được đặt bytea_outputthành hexmặc định. Điều đó có nghĩa là nếu tôi ghi dữ liệu của mình vào một byteatrường sau đó tìm nạp nó trở lại, nó sẽ trông giống như sau:

craig=> CREATE TABLE byteademo(x bytea);
CREATE TABLE
craig=> INSERT INTO byteademo(x) VALUES ('Blah binary\\000\\001\\002\\003\\004 blah');
INSERT 0 1
craig=> SELECT * FROM byteademo ;
                                     x                                      
----------------------------------------------------------------------------
 \x426c61682062696e6172795c3030305c3030315c3030325c3030335c30303420626c6168
(1 row)

"Ừm, cái gì", bạn có thể nói? Nó ổn, nó chỉ là biểu diễn hex nhỏ gọn hơn một chút của PostgreSQL bytea. pg_unescape_byteasẽ xử lý nó tốt và tạo ra các byte thô giống như đầu ra ... nếu bạn có PHP hiện đại và libpq. Trên các phiên bản cũ hơn, bạn sẽ nhận được rác và cần đặt bytea_outputthành escapefor pg_unescape_byteađể xử lý.

Thay vào đó bạn nên làm gì

Sử dụng PDO.

Nó có hỗ trợ lành mạnh (ish) cho bytea.

$sth = $pdo->prepare('INSERT INTO mytable(somecol, byteacol) VALUES (:somecol, :byteacol)');
$sth->bindParam(':somecol', 'bork bork bork');
$sth->bindParam(':byteacol', $thebytes, PDO::PARAM_LOB);
$sth->execute();

Xem:

  • PHP: Đối tượng lớn , có ví dụ về chính xác những gì bạn muốn;
  • PDOStatement :: bindParam
  • cách lưu trữ đối tượng tuần tự hóa với không gian tên trong cơ sở dữ liệu bằng pdo php
  • Ràng buộc BYTEA với Tuyên bố chuẩn bị sẵn PGSQL PDO bằng PHP5

Bạn cũng có thể muốn xem xét hỗ trợ lob (đối tượng lớn) của PostgreSQL, cung cấp giao diện trực tuyến, có thể tìm kiếm mà vẫn hoàn toàn có thể giao dịch.

Bây giờ, đến hộp xà phòng của tôi

Nếu PHP có sự phân biệt thực sự giữa các loại "chuỗi byte" và "chuỗi văn bản", bạn thậm chí sẽ không cần pg_escape_byteavì trình điều khiển cơ sở dữ liệu có thể làm điều đó cho bạn. Không có sự xấu xí nào được yêu cầu. Thật không may, không có kiểu chuỗi và byte riêng biệt trong PHP.

Vui lòng sử dụng PDO với các câu lệnh được tham số hóa càng nhiều càng tốt.

Trường hợp bạn không thể, ít nhất hãy sử dụng pg_query_paramsvà các câu lệnh được tham số hóa. PHP addslasheskhông phải là một giải pháp thay thế, nó không hiệu quả, xấu xí và không hiểu các quy tắc thoát dành riêng cho cơ sở dữ liệu. Bạn vẫn phải thoát theo cách thủ công byteanếu bạn không sử dụng PDO vì lý do lịch sử khó khăn, nhưng mọi thứ khác phải thông qua các câu lệnh được tham số hóa.

Để được hướng dẫn về pg_query_params:

  • Bảng Bobby , phần PHP.
  • Hướng dẫn sử dụng PHP trên pg_query_params

15 hữu ích 2 bình luận chia sẻ