在尝试使用Prepared语句将数据插入数据库时,Prepared语句始终返回false并没有完成连接。
我正在cpanel上使用此连接(不确定是否相关)试图更改顺序,尝试更改数据类型。
$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,并且数据库中未插入任何内容。
答案 0 :(得分:1)
正如我在评论中所说的:
根据我的计算,您有
14 ?
和11 s
。或sssssssssss
和??????????????
,正如我们大多数人所知道的那样,由于您的占位符计数与您的值不匹配,会抛出错误
如果您可以将数据放入数组中,则可以使用该数组来构建查询。
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”(可变长度参数):
$sql->bind_param(str_repeat('s', count($data)),...$data);
在PHP v5.6+
中,您可以使用...
插入数据,它将为您展开数据。或者换句话说,将每个数组项作为新参数。
用于字段(列)
如果您也想做这些字段,那会比较棘手。如果将数据直接放入SQL,则必须小心其中的内容。例如,如果您仅将Post键连接到SQL中,则用户可以以执行SQLInjection的方式编辑$_POST
请求中使用的键。
解决此问题的最简单方法之一是拥有类似这样的字段白名单(与列名匹配):
//all allowed column names for this query (case sensitive)
$whitelist = ["id", "assetName", ...];
您可以使用array_intersect_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
的值,以及每个项目值的空字符串。我将此称为默认行。
然后将其与原始数据合并。第一个数组中的数据将被第二个数组(在我的示例中为$_POST
)具有匹配键的任何数据覆盖。因此,如果在上面的示例中存在像id
这样的密钥,它将覆盖空密钥。
任何未覆盖的内容都会保留我们创建的默认行中的空值。然后,数组相交键会删除之前的所有多余内容。
* PS 我没有对此进行任何测试,因此请原谅任何语法错误。
享受!
答案 1 :(得分:0)
答案 2 :(得分:0)
我认为您不执行调用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