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à không phải.
pg_escape_bytea
của PHP dườ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 addslashes
dòng cho dữ liệu được đọc từ tệp là đủ.
Trường hợp kiểm tra cho thấy rằng pg_escape_bytea
thoát kép (và luôn sử dụng các thoát bát phân cũ, không hiệu quả):
<?php
# oh-the-horror.php
print pg_escape_bytea("Blah binary\x00\x01\x02\x03\x04 blah");
?>
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, dường như bạn không có bất kỳ giải pháp 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 , kể từ pg_unescape_bytea
thực ra không phải là mặt trái của pg_escape_bytea
. Nó cũng làm cho không thể cấp dữ liệu đầu ra của pg_escape_bytea
thành pg_query_params
là 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ể đặt bytea_output
thành hex
theo mặc định. Điều đó có nghĩa là nếu tôi ghi dữ liệu của mình vào bytea
sau đó tìm nạp nó trở lại, nó sẽ giống như thế này:
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? Không sao cả, nó chỉ là biểu diễn hex nhỏ gọn hơn một chút của PostgreSQL về bytea
. pg_unescape_bytea
sẽ 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à sẽ cần đặt bytea_output
để escape
cho pg_unescape_bytea
để xử lý nó.
Thay vào đó, bạn nên làm gì
Sử dụng PDO.
Nó có hỗ trợ sane (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
- Liên kết 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 được.
Bây giờ, chuyển sang 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_bytea
vì 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ày sẽ đượ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 nhiều nhất có thể.
Nếu bạn không thể, ít nhất hãy sử dụng pg_query_params
và các câu lệnh được tham số hóa. Dấu gạch ngang addslashes
khô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 bytea
theo cách thủ công nếu bạn không sử dụng PDO vì những 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 về
pg_query_params