Простая вещь: мой код просто не работает. Ни INSERT, ни SELECT не работают в моем PDO. Возможно, у меня что-то не так, но я не мастер кода, поэтому мне нужна ваша помощь.
if (isset($_POST['submit']))
{
try
{
$connection = new PDO('sqlite:../tracker.db');
$name = $_POST['name'];
$unitsize = $_POST['unitsize'];
$line = $_POST['line'];
$mmr = $_POST['mmr'];
$lifespan = $_POST['lifespan'];
$connection->exec("INSERT INTO unit (name, unitsize, line, mmr, lifespan)
VALUES ('$name', '$unitsize', '$line', '$mmr', '$lifespan')");
$new_unit = "SELECT unit_id
FROM unit
ORDER BY unit_id DESC
LIMIT 1";
foreach ($connection->query($new_unit) as $row) {
$id = $row['unit_id'];
};
}
catch(PDOException $error)
{
echo $error->getMessage();
}
}
Конечно, я знаю, что SELECT без записей не может работать … Но интуиция моего начинающего говорит, что это также может иметь ошибку.
PS: я знаю, что код может быть немного грязным … извините за ваши глаза кровоточат 🙁
РЕДАКТИРОВАТЬ:
ЧЕГО ХОЧУ ДОСТИГНУТЬ
form
, $id
(unit_id — AUTOINCREMENT и ПЕРВИЧНЫЙ КЛЮЧ)Ну, глядя на ваш код, я могу сказать, что ошибка (по крайней мере, одна) заключается в следующих частях:
PDO::exec()
и / или PDO::query()
, Вы правильно используете обе функции в отношении их определений, но, возможно, они вернули FALSE в случае неудачи. Ситуация, которую вы вообще не обработали и которая описана в разделах «Возвращенные значения» соответствующего документа на php.net.Итак, потому что проблема с вашим кодом была в том, что вы не знали, почему он не работал, например, вы не получили ни одной ошибки или признака ее, я подумал показать вам полный способ использования отчетов об ошибках + подготовленные операторы + проверки + обработка исключений. Обратите внимание, что все эти четыре элемента являются обязательными, если вы хотите закодировать безопасное и надежное решение PDO. Более того, когда вы применяете их надлежащим образом, вы всегда будете знать, где проблема (или больше) лежит. И у вас будет намного больше эффективности в написании кода, потому что вы не потеряете больше времени (иногда часов!) Для поиска ошибок.
Кроме того, как вы структурируете свой код, зависит от вас. Я представил вам здесь процедурную форму, в которой вы можете легко выполнить все шаги. Лучшая форма будет реализована объектно-ориентированным способом.
Рекомендации:
PDO::prepare()
+ PDOStatement::execute()
вместо PDO::exec
(прочитайте «Описание» от PDO :: exec на php.net).PDO::prepare()
:Если сервер базы данных не может успешно подготовить оператор,
PDO :: prepare () возвращает FALSE или генерирует PDOException (в зависимости от ошибки
обработка).
Не стесняйтесь спрашивать что-нибудь, если у вас есть неясности.
Удачи.
<?php
/*
* Try to include files using statements
* only on the top of the page.
*/
require "../config.php";
require "../common.php";
/*
* Set error reporting level and display errors on screen.
*
* =============================================================
* Put these two lines in a file to be included when you need to
* activate error reporting, e.g the display of potential errors
* on screen.
* =============================================================
* Use it ONLY ON A DEVELOPMENT SYSTEM, NEVER ON PRODUCTION !!!
* If you activate it on a live system, then the users will see
* all the errors of your system. And you don't want this !!!
* =============================================================
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
/*
* ===================================================
* Two functions used for automatically binding of the
* input parameters. They are of course not mandatory,
* e.g. you can also bind your input parameters one
* by one without using these functions. But then
* you'd have to validate the binding of each input
* parameter one by one as well.
*
* Put these two functions in a file to be included,
* if you wish.
* ===================================================
*/
/**
* Get the name of an input parameter by its key in the bindings array.
*
* @param int|string $key The key of the input parameter in the bindings array.
* @return int|string The name of the input parameter.
*/
function getInputParameterName($key) {
return is_int($key) ? ($key + 1) : (':' . ltrim($key, ':'));
}
/**
* Get the PDO::PARAM_* constant, e.g the data type of an input parameter, by its value.
*
* @param mixed $value Value of the input parameter.
* @return int The PDO::PARAM_* constant.
*/
function getInputParameterDataType($value) {
if (is_int($value)) {
$dataType = PDO::PARAM_INT;
} elseif (is_bool($value)) {
$dataType = PDO::PARAM_BOOL;
} else {
$dataType = PDO::PARAM_STR;
}
return $dataType;
}
/*
* ======================
* Hier begins your code.
* ======================
*/
try {
// Read from HTTP POST.
$name = $_POST['name'];
$unitsize = $_POST['unitsize'];
$line = $_POST['line'];
$mmr = $_POST['mmr'];
$lifespan = $_POST['lifespan'];
// Create a PDO instance as db connection to sqlite.
$connection = new PDO('sqlite:../tracker.db');
// The sql statement - it will be prepared.
$sql = 'INSERT INTO unit (
name,
unitsize,
line,
mmr,
lifespan
) VALUES (
:name,
:unitsize,
:line,
:mmr,
:lifespan
)';
// The input parameters list for the prepared sql statement.
$bindings = array(
':name' => $name,
':unitsize' => $unitsize,
':line' => $line,
':mmr' => $mmr,
':lifespan' => $lifespan,
);
// Prepare the sql statement.
$statement = $connection->prepare($sql);
// Validate the preparing of the sql statement.
if (!$statement) {
throw new UnexpectedValueException('The sql statement could not be prepared!');
}
/*
* Bind the input parameters to the prepared statement
* and validate the binding of the input parameters.
*
* =================================================================
* This part calls the two small functions from the top of the page:
* - getInputParameterName()
* - getInputParameterDataType()
* =================================================================
*/
foreach ($bindings as $key => $value) {
// Read the name of the input parameter.
$inputParameterName = getInputParameterName($key);
// Read the data type of the input parameter.
$inputParameterDataType = getInputParameterDataType($value);
// Bind the input parameter to the prepared statement.
$bound = $statement->bindValue($inputParameterName, $value, $inputParameterDataType);
// Validate the binding.
if (!$bound) {
throw new UnexpectedValueException('An input parameter could not be bound!');
}
}
// Execute the prepared statement.
$executed = $statement->execute();
// Validate the prepared statement execution.
if (!$executed) {
throw new UnexpectedValueException('The prepared statement could not be executed!');
}
/*
* Get the id of the last inserted row.
* You don't need to call a SELECT statement for it.
*/
$lastInsertId = $connection->lastInsertId();
/*
* Display results. Use it like this, instead of a simple "echo".
* In this form you can also print result arrays in an elegant
* manner (like a fetched records list).
*
* Theoretically, this statement, e.g. the presentation of results
* on screen, should happen outside this try-catch block (maybe in
* a HTML part). That way you achieve a relative "separation of
* concerns": separation of the fetching of results from the
* presentation of them on screen.
*/
echo '<pre>' . print_r($lastInsertId, TRUE) . '</pre>';
// Close the db connecion.
$connection = NULL;
} catch (PDOException $exc) {
echo '<pre>' . print_r($exc, TRUE) . '</pre>';
// echo $exc->getMessage();
// $logger->log($exc);
exit();
} catch (Exception $exc) {
echo '<pre>' . print_r($exc, TRUE) . '</pre>';
// echo $exc->getMessage();
// $logger->log($exc);
exit();
}
?>
Других решений пока нет …