Php 准备好的语句总是返回false
当尝试使用prepared语句将数据插入数据库时,prepared语句总是返回false,并且不会完成连接 我正在cpanel上使用此连接(不确定是否相关)尝试更改顺序尝试更改数据类型Php 准备好的语句总是返回false,php,mysqli,Php,Mysqli,当尝试使用prepared语句将数据插入数据库时,prepared语句总是返回false,并且不会完成连接 我正在cpanel上使用此连接(不确定是否相关)尝试更改顺序尝试更改数据类型 $conn = mysqli_connect($servername,$username,$password,$database); // $sql=$conn->prepare("insert into asset 'assetName'=?, 'grp' ='?' ,'Descrip' = '?'
$conn = mysqli_connect($servername,$username,$password,$database);
// $sql=$conn->prepare("insert into asset 'assetName'=?, 'grp' ='?' ,'Descrip' = '?' , 'enteredValue' = '?', 'depreciationRate' = '?','entrydate'='?' 'availability'= '?' ,'enteredBy' = '?' , 'updatedOn' = '?' , 'isPeriodic' = '?' , 'assetType' = '?','Frequency'='?','ExitDate'='?'");
if($sql = $conn->prepare("INSERT INTO `asset`(`id`, `assetName`, `grp`, `Descrip`, `enteredValue`, `depreciationRate`, `entrydate`, `availability`, `enteredBy`, `updatedOn`, `isPeriodic`, `assetType`, `Frequency`, `ExitDate`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)")){
$sql->bind_param("sssssssssss",$name,$group,$value,$depreciation,$entryDate,$availability,$enteredBy,$updatedOn,$isPeriodic,$type,$frequency,$exitDate);
$sql->execute();
始终返回false,并且数据库中未插入任何内容。绑定数据后,必须对语句进行修改
$sql->execute();
正如注释所指出的,参数的数量也不一致。我认为您没有调用execute方法执行查询:
$conn = mysqli_connect($servername,$username,$password,$database);
// $sql=$conn->prepare("insert into asset 'assetName'=?, 'grp' ='?' ,'Descrip' = '?' , 'enteredValue' = '?', 'depreciationRate' = '?','entrydate'='?' 'availability'= '?' ,'enteredBy' = '?' , 'updatedOn' = '?' , 'isPeriodic' = '?' , 'assetType' = '?','Frequency'='?','ExitDate'='?'");
if($sql = $conn->prepare("INSERT INTO `asset`(`id`, `assetName`, `grp`, `Descrip`, `enteredValue`, `depreciationRate`, `entrydate`, `availability`, `enteredBy`, `updatedOn`, `isPeriodic`, `assetType`, `Frequency`, `ExitDate`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)")){
$sql->bind_param("sssssssssss",$name,$group,$value,$depreciation,$entryDate,$availability,$enteredBy,$updatedOn,$isPeriodic,$type,$frequency,$exitDate);
sql->execute();
sql->close(); // close connection
正如我在评论中所说: 嗯,据我计算,你有14个和11个。或者
ssssss
和?????
,我们大多数人都知道,这会抛出一个错误,因为占位符计数与值不匹配
如果可以将数据放入一个数组中,则可以使用该数组构建查询
if($sql = $conn->prepare("INSERT INTO `asset`(`id`, `assetName`, `grp`, `Descrip`, `enteredValue`, `depreciationRate`, `entrydate`, `availability`, `enteredBy`, `updatedOn`, `isPeriodic`, `assetType`, `Frequency`, `ExitDate`) VALUES (".implode(',', array_fill(0,count($data), '?')).")")){
$sql->bind_param(str_repeat('s', count($data)),...$data);
让我们走吧,我想这有点
基本上,您可以使用以下两段代码创建与$data
长度相同的参数:
implode(',', array_fill(0,count($data), '?')) //implode "?" with "," equal to the length of data
str_repeat('s', count($data)) //create 's' equal to the length of data
然后真正的神奇发生在这里,…
“variadic”(可变长度参数):
在PHPV5.6+
中,您可以使用..
插入数据,它将为您解开数据。或者换句话说,将每个数组项作为新参数放入
用于字段(列) 如果你也想做字段,那就有点棘手了。如果将数据直接放入SQL中,则必须小心其中的内容。例如,用户可以编辑
$\u POST
请求中使用的键,如果您只是将POST键连接到SQL中,就可以执行SQLInjection
解决此问题的最简单方法之一是创建一个这样的字段白名单(与列名匹配):
您可以使用array\u intersect\u key
仅保留查询所需的数据(假设数据具有匹配的键)。现在可以安全地在查询中使用这些键,因为它们必须与$whitelist
中的内容匹配
//remove unknown keys form input data (~ retain only known ones)
//array_flip($whitelist) = ["id"=>0, "assetName"=>1, ...];
$data = array_intersect_key($_POST, array_flip($whitelist));
if($sql = $conn->prepare("INSERT INTO `asset`(`".implode("`,`", array_keys($data))."`)VALUES(".implode(',', array_fill(0,count($data), '?')).")".)){
$sql->bind_param(str_repeat('s', count($data)),...$data);
其他事项
唯一没有涉及的是,如果您希望始终存在$whitelist
中的所有字段,则此选项不适用。您可以通过验证传入数据来解决这个问题,也可以在一些空字段中合并,以确保所有数据都存在
$default = array_fill_keys($whitelist, ''); //["id"=>"", "assetName"=>"", ...] ~ create empty "default" row
//$default['updatedOn'] = date('Y-m-d'); //you can also manually set a value
$data = array_intersect_key(
array_merge(
$default,
$_POST //["id"=>"1", ...] ~ missing assetName
), array_flip($whitelist)); //-> ["id"=>"1","assetName"=>""]
数组填充键(类似于前面的数组填充)获取一个键列表,并为每个键添加一个值。这给了我们一个数组,其中的键是$whitelist
的值,每个items值都有一个空字符串。我称之为默认行
然后我们将其与原始数据合并。第一个数组中的数据将被第二个数组中具有匹配键的任何数据覆盖(在我的示例中为$\u POST
)。因此,如果在上面的示例中出现一个键,如id
,它将覆盖空键
任何未被覆盖的内容都会保留我们创建的默认行中的空值。然后,数组的intersect键会像以前一样删除任何额外的内容
*PS我没有测试这些,因此请原谅任何语法错误
享受吧 您应该检查以找出失败的原因。这是您的脚本的完整版本吗?我想你没有提到execute方法?你现在还没有执行任何东西。据我统计,你有14个
?
和11个s
。或者ssssss
和??????????
,正如我们大多数人所知,这将抛出一个错误,因为占位符计数与您的值不匹配。stru repeat('s',count($data))
@Quasimodo'sclone-Doah,好建议我应该看到这一点。我只是在偷懒。我更新了它。我确实执行了它,但忘了附加它。我确实执行了
-从来没有说过你没有。占位符的数量是错误的。谢谢所有人,但我确实执行了。谢谢所有人,但我确实执行了它。
//remove unknown keys form input data (~ retain only known ones)
//array_flip($whitelist) = ["id"=>0, "assetName"=>1, ...];
$data = array_intersect_key($_POST, array_flip($whitelist));
if($sql = $conn->prepare("INSERT INTO `asset`(`".implode("`,`", array_keys($data))."`)VALUES(".implode(',', array_fill(0,count($data), '?')).")".)){
$sql->bind_param(str_repeat('s', count($data)),...$data);
$default = array_fill_keys($whitelist, ''); //["id"=>"", "assetName"=>"", ...] ~ create empty "default" row
//$default['updatedOn'] = date('Y-m-d'); //you can also manually set a value
$data = array_intersect_key(
array_merge(
$default,
$_POST //["id"=>"1", ...] ~ missing assetName
), array_flip($whitelist)); //-> ["id"=>"1","assetName"=>""]