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_bytea
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 trong tệp là đủ.
Trường hợp thử nghiệm cho thấy rằng pg_escape_bytea
cá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_bytea
thự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_bytea
thành pg_query_params
như 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_output
thành hex
mặc định. Điều đó có nghĩa là nếu tôi ghi dữ liệu của mình vào một bytea
trườ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_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à cần đặt bytea_output
thành escape
for
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_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à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_params
và
các câu lệnh được tham số hóa. PHP 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 theo cách thủ công bytea
nế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ẻ