使用PHP7 MySQLi Prepared语句将位(M)列值插入MySQL5.7
尝试使用MySQLi prepared语句将值插入位(64)列时,我收到错误(在执行时): 第1行“bits64”列的数据太长 这是我的密码:使用PHP7 MySQLi Prepared语句将位(M)列值插入MySQL5.7,php,mysql,mysqli,bindparam,Php,Mysql,Mysqli,Bindparam,尝试使用MySQLi prepared语句将值插入位(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] == 'ye
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类型是integer、string、double和blob。我假设它分别发送了'101010'
(代码示例)、101010
(作为整数)、'b'101010'
和'0b101010'
等值;然而,需要的是b'101010'
出于速度和安全原因(其他领域),我必须使用预先准备好的语句
我最初使用BIGINT来实现这一点,但似乎在设置大多数标志时都会出现舍入错误
我想我禁用了MySQL严格模式
我的退路是大量的TINYINT列或CHAR(64),但我更喜欢更高效的存储
这个网站上有一些相关的问题,但大多数都与单位字段有关,其中整数0或1更容易与单位关联。我非常感激任何建议或解决方案
编辑
我意识到我的SQL模式不是完全空白的。一旦SQL模式为空字符串,就不会有错误,但无论我尝试什么,都会得到01111111111111111111111111111111111111111
编辑2
在设置了所有1个标志的情况下通过phpMyAdmin插入也会产生01111111111111111111111111111111111111111
,因此我配置此列的方式肯定存在其他问题。我正在使用Ubuntu 16.04,服务器版本:5.7.19,PHP版本:7.0.22。也许可以试试
$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.'\')');
我向您保证,对性能的影响将是绝对最小的,对其进行基准测试。这是绑定类型很重要的示例之一……但对您的情况并没有真正的帮助 您需要了解实际使用的数据类型。您已经在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中使用值(cast(?as UNSIGNED))
或简单地添加0,例如值(?+0)
要避免使用
bindec()
,可以在PHP中使用位操作。然后该值将始终为整数。Hanshenrik。。。谢谢你的快速回答。我忘了提及,我最初尝试过,但在bind_param上出现了一个致命错误(即准备行错误)。然而,我可能做错了什么。