簡體   English   中英

使用 PHP7 MySQLi 准備語句將 BIT(M) 列值插入 MySQL5.7

[英]Inserting BIT(M) Column Values to MySQL5.7 with PHP7 MySQLi Prepared Statements

嘗試使用 MySQLi 准備好的語句將值插入 BIT(64) 列時,我收到錯誤(執行時):

第 1 行“bits64”列的數據太長

這是我的代碼:

if ($Segments[0] == 'yes') {$bitmask = '1';}else{$bitmask = '0';}
if ($Segments[1] == 'yes') {$bitmask = $bitmask.'1';}else{$bitmask = $bitmask.'0';}
...
if ($Segments[63] == 'yes') {$bitmask = $bitmask.'1';}else{$bitmask = $bitmask.'0';}

$Upload = $conn->prepare("INSERT INTO `testtable` (`bits64`) VALUES (?)");
$Upload->bind_param("s", $bitmask);
$Upload->execute();

該代碼提供了一個 64 個字符的字符串。 如果我使用 PHPMyAdmin 插入相同的輸出,它會成功運行,如下所示:

INSERT INTO `testtable` (`bits64`) VALUES (b'0000000000000000000000000000000000000000000000000000000000000000');
INSERT INTO `testtable` (`bits64`) VALUES (b'1111111111111111111111111111111111111111111111111111111111111111');

唯一顯示出任何“成功”(* 不是真的)的是將綁定類型更改為整數。 但它似乎被視為一個應該轉換為二進制的整數,因為它在位標志設置為1情況下給出了相同的錯誤。

我嘗試過的其他事情包括將$bitmask格式化為:

$bitmask = "b'".$bitmask."'";
$bitmask = "0b".$bitmask;
// And others 

據我所知,唯一的 bind_param 類型是整數、字符串、雙精度和 blob。 我假設它分別發送諸如'101010' (代碼示例)、 101010 (作為整數)、 'b'101010'''0b101010' 然而,需要的是b'101010'

出於速度和安全原因(其他領域的),我必須使用准備好的語句。

我最初為此使用 BIGINT,但似乎在設置大多數標志時發生了舍入錯誤。

我想我禁用了 MySQL 嚴格模式。

我的后備是很多 TINYINT 列或 CHAR(64),但我更喜歡更高效的存儲。

本網站上有一些相關問題,但大多數與單個位字段有關,其中整數 0 或 1 更容易與單個位相關聯。 我應該非常感謝任何建議或解決方案。

編輯

我意識到我沒有完全空白的 SQL 模式。 一旦 SQL 模式為空字符串,就沒有錯誤,但無論我嘗試什么,我都會得到0111111111111111111111111111111111111111111111111111111111111111

編輯 2

通過設置所有 1 個標志的 phpMyAdmin 插入也會給出0111111111111111111111111111111111111111111111111111111111111111 ,所以我配置這個列的方式肯定有其他問題。 我使用的是 Ubuntu 16.04,服務器版本:5.7.19,PHP 版本:7.0.22。

這是綁定類型很重要的示例之一……但對您的情況沒有真正幫助。

您需要了解您真正使用的數據類型。 您已經在 PHP 中創建了一串數字。 不是二進制數! 它只是一個字符串。 PHP 可以處理它並轉換它,但是您需要對 PHP 明確表示您想要的是一個數字,而不是一個字符串。

一種方法是:

$bitmask = bindec($bitmask); // convert binary string to decimal number

$Upload = $conn->prepare("INSERT INTO `testtable` (`bits64`) VALUES (?)");
$Upload->bind_param("i", $bitmask); // bind as integer
$Upload->execute();

如果你想避免綁定為整數,你可以在 SQL 中使用VALUES(CAST(? AS UNSIGNED))或簡單地添加 0 例如VALUES(? + 0)

為了避免使用bindec()您可以在 PHP 中使用按位運算。 該值將始終是一個整數。

也許試試

$Upload = $conn->prepare("INSERT INTO `testtable` (`bits64`) VALUES (b?)");

但如果准備好的語句根本不支持位域,我也不會感到驚訝。

出於速度和安全原因(其他領域的),我必須使用准備好的語句。

不,你沒有。 這將同樣安全:

if(strlen(rtrim($bitmask,'01'))!==0){throw new \RuntimeException('illegal characters found in bitmask!');}
$conn->query('INSERT INTO `testtable` (`bits64`) VALUES (b\''.$bitmask.'\')');

我向你保證性能影響絕對是最小的,對它進行基准測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM