Подготовленное утверждение всегда возвращает false - PullRequest
0 голосов
/ 01 апреля 2019

При попытке вставить данные в базу данных, используя подготовленный оператор, подготовленный оператор всегда возвращает 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 и ничего не было вставлено в базу данных.

Ответы [ 3 ]

1 голос
/ 01 апреля 2019

Как я уже сказал в комментариях:

Ну, у вас есть 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+ вы можете просто ввести данные, используя ... in, и это раскрутит их для вас. Или, другими словами, поместите каждый элемент массива в качестве нового аргумента.


Для полей (столбцов)

Если вы тоже хотите заполнить поля, это немного сложнее. Вы должны быть осторожны с тем, что в них, если вы помещаете эти данные непосредственно в SQL. Например, пользователь может редактировать ключи, используемые в запросе $_POST, таким образом, чтобы сделать SQLInjection, если вы просто объедините ключи Post в SQL.

Один из самых простых способов решить эту проблему - создать белый список полей, таких как (сопоставленных с именами столбцов):

 //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 Я не проверял ничего из этого, поэтому прошу прощения за любые синтаксические ошибки.

Наслаждайтесь!

0 голосов
/ 01 апреля 2019

Я думаю, что вы не выполняете свой запрос, вызывая метод 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 
0 голосов
/ 01 апреля 2019

Вы должны выполнить инструкцию, как только вы связали данные.

$sql->execute();

Количество параметров также не соответствует, как указано в комментариях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...