это делается одним столбцом с начальным значением - 0 и двумя кнопками [+][-], нажатие одной делает значению этого столбца инкремент, второй - декремент, всё
@Вероломство, ну все с вами понятно: не читатель ТС хотел, как на этом форуме, т.е. ему нужны имена/ники проставивших лайки (всех или по крайней мере нескольких человек, чтобы можно было дописать «и еще N человек»). --- Добавлено --- Лайки выбираешь с небольшим лимитом, например 5, а потом по положительной разнице значения счетчика и кол-ва выбранных лайков дописываешь к списку выбранных «и еще N человек».
То есть я сейчас напишу вопрос: Как мне написать такой-то сайт один в один и ты мне ответишь? Я в комментарии дал правильный ответ, видимо забыл json указать --- Добавлено --- И где мы тут видим что я ИМЕННО уже лайкнул какой-то пост?
Нет я так как на форуме не хочу, принцип такой хотел, без имён кто подставил лайк, просто подсчет количества лайков и все, но при этом можно лайкнуть если понравилось, если разнравилось отлайкнуть. Я написал выше код, который делает в принципе то что мне нужно, теперь с помощью вашей и форумчан буду поправлять скрипты.
Если даже не увидим, алгоритм не позволит поставить одному человеку несколько лайков одному посту. В вашем варианте один чел может накликивать одному посту столько лайков, сколько захочет --- Добавлено --- В любом случае нужна таблица лайков, чтобы контролировать «накликивание», о чем я выше написал.
Думаю такое мне не пойдет, должно быть для всех постов ставится лайк, если юзер поставил лайк, я в базу заношу данные uid, pid чтобы в последующий раз он мог только отлайкнуть при этом запись из бд удалится. --- Добавлено --- Да что такое, сейчас гляну. Ок под рукой нет инструмента, буду лишь догадываться, или аж вечером отпишусь если получится обойти эту ошибку.
В доках написано, что может некорректно работать на SELECT'е. Т.е. это скорее аналог $affected_rows, чем $num_rows в нативном расширении для мускула --- Добавлено --- P.S. Я тебе выше написал, что в обработчике SELECT на таблице лайков вообще не нужен.
ок понял, тогда что делать с запросом, убрал его, а как же проверка на что мне нужно проверять чтобы вставить запись? Проверку перед вставкой нужно делать?
Естественно, второе. Первое – это группировка записей в запросе. --- Добавлено --- После вставки. Я же написал, что нужно отлавливать ошибку дублирующего ключа. Если произошла именно такая ошибка при вставке, то делаете дислайк (удаление записи из таблицы лайков).
Спойлер: БД PHP: CREATE TABLE `likes` ( `id_user` int(11) NOT NULL COMMENT 'id пользователя', `id_post` int(11) NOT NULL COMMENT 'id поста' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -- Индексы таблицы `likes` -- ALTER TABLE `likes` ADD UNIQUE KEY `id_user_id_post` (`id_user`,`id_post`) USING BTREE; COMMIT; Обработчик лайков Спойлер: Обработчик PHP: <?php # подключаем файл для работы с базой данных include 'db.php'; $uid = 2; # это id пользователя, пока мы в ручную делаем а так это id будем из сессии вытаскивать $count = 0; # начальное значение подсчета лайков # проверяем какой метод используется на веб странице if ($_SERVER['REQUEST_METHOD'] == 'POST') { # массив данных, для проверки полей $rulles = [ 'id' => FILTER_DEFAULT, ]; # фильтруем данные при необходимости $filter = filter_input_array(INPUT_POST, $rulles); $sql = $pdo->prepare("INSERT INTO `likes` (`id_user`, `id_post`) VALUES (?,?)"); # если запрос вернул true обновляем количество лайков if ($sql -> execute([$uid, $filter['id']])) { $post = $pdo->prepare("UPDATE `posts` SET `count_like` = `count_like`+1 WHERE `id` = ?"); $post->execute([$filter['id']]); $isActive = 1; }else{ $sql = $pdo->prepare("DELETE FROM `likes` WHERE `id_user` = ? AND `id_post` = ?"); $sql -> execute([$uid, $filter['id']]); $post = $pdo->prepare("UPDATE `posts` SET `count_like` = `count_like`-1 WHERE `id` = ?"); $post->execute([$filter['id']]); $isActive = 0; } # запрос для вывода количества лайков для конкретного поста $post = $pdo->prepare("SELECT `count_like` FROM `posts` WHERE `id` = ?"); $post->execute([$filter['id']]); $res = $post->fetch(); $count = isset($res['count_like']) ? $res['count_like'] : 0; # формируем массив данных для отправки json exit(json_encode(['count' => $count, 'isActive' => $isActive], JSON_UNESCAPED_UNICODE)); } Прошу прокоментировать, спасибо. если все гуд, перейду на ООП.
Еще протестировал и добавил запрос на проверку поста, перед insertom делаю проверку и уже после этого делаю вставку, ибо могут подменить id поста в форме, и в базу добавится не существующий пост. PHP: # запрос для проверки существования поста по записи id $post = $pdo->prepare("SELECT `id` FROM `posts` WHERE `id` = ?"); $post->execute([$filter['id']]); $res = $post->fetch(); if ($res['id'] == 0) { header('location: /'); exit('досвидос'); }
не ну rowCount() хорошо использовать когда upd, ins, del а не когда sel покажи как правильно, тогда научусь)
Первичный ключ всегда указывайте явно. Раз вы отказались от поля lid, сделайте uid/pid первичным ключом. Первичный ключ – юник по определению. И что не понятно в словах, что нужно отлавливать именно ошибку дублирующегося ключа? https://stackoverflow.com/questions/10774943/check-for-duplicate-entry-vs-use-pdo-errorinfo-result Возможно, в PDO можно использовать собственные коды ошибок, чтобы не привязываться к конкретной СУБД. У меня в распоряжении только код, в котором используются нативные расширения. --- Добавлено --- В смысле другие ошибки вы оформляете, как ошибки, а при ошибке дублирующегося ключа пытаетесь выполнить удаление. --- Добавлено --- Он все верно написал. В доках так написано.
я показал таблицу правильно сделать с юником? если что то не так тыкну в муАдмин для uid/pid первичный ключи разве мы не так договорились, удалить запись, если возникла ошибка (дублирования ключей)?
Да там все так и написано, если еще поковыряться в носу для счастья и ничего не выяснить что мы используем.
ты подстраховался плейсхолдером в запросе, но в execute данные массива передаются строками надо тогда уже биндить айдишник к int или проверить его на int перед вбросом в массив для execute может это и шиза, но аккуратность и ещё через execute ты не сможешь делать пагинацию - limit ?, ?, так как строки не будут обработаны для limit, лимиту в запросе стопудово нужны int, надо в любом случае биндить к int либо отключать эмуляцию, но в этом случае все значения должны иметь свой плейсхолдер, при отключении эмуляции PDO будет сама всё биндить, но один именованный плейсхолдер нельзя будет несколько раз использовать в запросе - я так делаю, потому то у меня нет повторов заранее, нет заморочек тупо вот с той же пагинацией
Ты на произвольную ошибку пытаешься удалять. А вдруг эта ошибка не является ошибкой дублирующегося ключа. Все ответы по ссылке просмотри. Там разные способы обработки ошибок показаны, в том числе и при помощи исключений. --- Добавлено --- PDO вы используете прежде всего для универсальности. Вон я выше писал ТСу по поводу собственных кодов ошибок PDO, чтобы не привязываться к мускулу.