Я хочу предотвратить дублирование значений в таблице базы данных из формы с помощью PHP.
Я создал следующее:
База данных с таблицей с именами клиентов :
CREATE TABLE clients( firstName varchar(20), lastName varchar(20), primary key(firstName, lastName));
Простая форма с именем form.html
<h2>Enter your First and Last Name</h2> <form action="frm_script.php" method="post"> <p><strong>First Name:</strong><br /> <input type="text" name="firstName" /></p> <p><strong>Last Name:</strong><br /> <input type="text" name="lastName"/></p> <input type="submit" name="submit" value="Add Customer" /> </form>
Сценарий обработки формы с именем frm_script.php
<?php if(isset($_POST['submit'])) { //get the name and comment entered by user $firstName = $_POST['firstName']; $lastName = $_POST['lastName']; //connect to the database $dbc = mysqli_connect('host', 'username', 'password', 'dbname') or die('Error connecting to MySQL server'); //insert results from the form input $query = "INSERT IGNORE INTO clients(firstName, lastName) VALUES('$firstName', '$lastName')"; $result = mysqli_query($dbc, $query) or die('Error querying database.'); mysqli_close($dbc); } echo "Customer Added"; ?>
До сих пор с файлом frm_script.php выше работает, и для уникальной записи отображается клиент. Тем не менее, для дублированной записи он выбрасывает «Error Querying Database».
Как я могу обновить скрипт frm_script.php для следующего?
Если при вводе комбинации First / Last name будет найдена повторяющаяся строка, она должна отображать сообщение «Клиент, уже указанный» вместе с этой записью.
Если при вводе комбинаций First / Last name в форме не будет найдена повторяющаяся строка, она должна вставить запись в базу данных и отобразить сообщение «добавленный клиентом»,
Я прочитал, что SELECT следует запускать сначала, а затем INSERT, но я не уверен, как реализовать это в моем существующем коде.
<?php if(isset($_POST['submit'])) { //get the name and comment entered by user $firstName = $_POST['firstName']; $lastName = $_POST['lastName']; //connect to the database $dbc = mysqli_connect('host', 'username', 'password', 'dbname') or die('Error connecting to MySQL server'); $check=mysqli_query($dbc,"select * from clients where firstname='$firstname' and lastname='$lastname'"); $checkrows=mysqli_num_rows($check); if($checkrows>0) { echo "customer exists"; } else { //insert results from the form input $query = "INSERT IGNORE INTO clients(firstName, lastName) VALUES('$firstName', '$lastName')"; $result = mysqli_query($dbc, $query) or die('Error querying database.'); mysqli_close($dbc); } echo "Customer Added"; }; ?>
просто проверьте для строк в своем db для firstname и lastname, если существует echo- ваше сообщение else insert
Поскольку ваш первичный ключ (firstName, lastName), вам не нужен php, чтобы предотвратить вставку повторяющихся значений. Mysql делает это для вас, потому что первичные ключи должны быть уникальными.
(если бы это был не ваш первичный ключ, вы могли бы использовать уникальное ограничение)
Чтобы отобразить сообщение об ошибке «Клиент уже указан» в двух экземплярах, вы можете использовать mysqli_errno($dbc)
и проверить код ошибки 1062
.
Быстрое исправление, которое должно делать то, что вы хотите: заменить or die('Error querying database.');
с
or die(mysqli_errno($dbc) == 1062 ? "Client already listed" : 'Error querying database.');
После обработки данных $_POST
используйте запрос SELECT
за которым следует оператор if
чтобы проверить, есть ли какие-либо строки в таблице с тем же именем и фамилией, что и имя и фамилия $_POST
.
Если есть, отобразите сообщение о том, что эти данные уже вставлены.
Если этого не происходит, используйте запрос INSERT
чтобы добавить эти данные в таблицу базы данных, и отобразите сообщение о том, что эти данные были добавлены в таблицу.
У меня эта проблема все время. Я больше не использовал автоинкрементный первичный код для использования хеша md5 большую часть времени. Поэтому, пока я еще не реализовал это, пока нет возможности / необходимости – вы можете создать первичный ключ (VARCHAR 32), который является хешем md5 первого и последнего имени. Как это:
$key = md5(strtolower($firstName . $lastName));
Сделайте столбец этой клавишей в первичный ключ. Затем вы используете INSERT IGNORE
и вы можете игнорировать любые ошибки.
Затем вы запускаете SELECT
в ключе $, чтобы вернуть все, что связано с $key
и отображать любую информацию, имеющуюся у пользователя в дружественном формате. Вам не нужно показывать пользователю ошибку в этот момент, просто предоставить им уже захваченную информацию. Если вас беспокоит то, что пользователи с тем же именем видят данные друг друга, данные могут быть запутаны. Например, вместо того, чтобы показывать номер телефона (333) 444-5555, вы показываете (333) 444-5 * 5 или (333) * * -5555. Что-то, что дает пользователю достаточно информации, чтобы знать, являются ли они им или кем-то другим с тем же именем.
Как правило, я использовал метод SELECT
, если пустой метод INSERT
и SELECT
снова. И он работает, но он значительно медленнее, чем простой INSERT IGNORE
а затем SELECT
. Я использую DAO, который я построил поверх PDO, и INSERT IGNORE
отлично работает, когда единственным столбцом является первичный ключ. Я не пробовал это на первичный ключ, основанный на более чем 1 столбце, и я не пробовал его с помощью функции mysqli_ *.