Как загрузить данные в реляционную базу данных на php pdo

Есть 3 таблицы со связью 1 ко многим.

(Project)-> там находятся все проекты.

CREATE TABLE `project` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `description` varchar(255) NOT NULL DEFAULT 'Нет описания',
  `image` text,
  `link` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

(Tags)-> там находятся теги.

CREATE TABLE `tags` (
  `id` int(11) NOT NULL,
  `tag_name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

(P_tags)-> там находятся id проекта и id тега.

CREATE TABLE `p_tags` (
  `project_id` int(11) NOT NULL,
  `tag_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Индексы таблицы `project`
--
ALTER TABLE `project`
  ADD PRIMARY KEY (`id`);

--
-- Индексы таблицы `p_tags`
--
ALTER TABLE `p_tags`
  ADD PRIMARY KEY (`project_id`,`tag_id`),
  ADD KEY `tag_id` (`tag_id`);

--
-- Индексы таблицы `tags`
--
ALTER TABLE `tags`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT для сохранённых таблиц
--

--
-- AUTO_INCREMENT для таблицы `project`
--
ALTER TABLE `project`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=75;

--
-- AUTO_INCREMENT для таблицы `tags`
--
ALTER TABLE `tags`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12;

--
-- Ограничения внешнего ключа сохраненных таблиц
--

--
-- Ограничения внешнего ключа таблицы `p_tags`
--
ALTER TABLE `p_tags`
  ADD CONSTRAINT `p_tags_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`),
  ADD CONSTRAINT `p_tags_ibfk_2` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`);
COMMIT;

Нужно вставить в базу данных новый проект с определёнными тегами.` Для реализации я попробовал сделать такую схему

После этого, нужно сравнить id тега который мы вписали с id тега который находится в базе и уже на основе этих данный делать вставку в таблицу p_tags.

По отдельности циклы работают, как их соединить вместе я не знаю.

Если есть какой-то лёгкий способ это сделать, буду рад ему научится.

        //Берём макс число. В $idcount[0][0] находится число, которое будет являться id проекта
        $sth = $dbh->prepare("SELECT MAX(id) FROM project");
        $sth->execute();
        $idcount = $sth->fetchAll(PDO::FETCH_NUM);

        // берём все теги (id,name)
        $sth = $dbh->prepare('SELECT * FROM tags');
        $sth->execute();
        $tags = $sth->fetchAll(PDO::FETCH_ASSOC);

        // Делаем цикл, узнаём что у нас 11 тегов
        for ($i=0; $i < count($tags); $i++) { 
        echo $tags[$i]['id'].' | '.$tags[$i]['tag_name'].'<br>';
        }
        // Делаем цикл, узнаём что мы вписали 3 тега +
        $proj_tags = $_GET["tags"];
        $proj_tags = explode(",", $proj_tags);

        for ($i=0; $i < count($proj_tags); $i++) { 
        $proj_tags[$i];
}

Ответы (2 шт):

Автор решения: KordDEM

Ну как-то так мб?

$stmt = $pdo->prepare("insert into project() values()");
$stmt->execute();
$pid = $pdo->lastInsertId(); // Получили id нового проекта

$proj_tags = explode(",", $_GET["tags"]);

$stmt = $pdo->prepare("insert into P_tags(pid, tid) select :pid, tag_id from tags where tag_name = :tname");
for($i=0; $i<count($proj_tags); $i++){
    $stmt->bindParam(':pid', $pid);
    $stmt->bindParam(':tname', $proj_tags[$i]);
    $stmt->execute();
}
→ Ссылка
Автор решения: Ипатьев

В данном коде три крупных ошибки, причем очень распространённых, так что будет полезно их рассмотреть.

  • Первая и самая главная, "следующий id" никогда не получают заранее. Это приведёт к ошибкам и порче данных. id ВСЕГДА получают только после того как строка была добавлена в БД.
  • Вторая - данные никогда не выгружают из базы целиком, если надо проверить только несколько строк. Надо составить запрос, который запрашивает только конкретные строки
  • Третья - очень желательно добавить транзакцию, чтобы в БД е болтались ошметки данных, не привязанных ни к какому проекту.

Соответственно, и пишем код, который помогает избежать всех этих ошибок

$pdo->beginTransaction();

// сначала добавляем проект
$stmt = $pdo->prepare("insert into project(поля) values(маркеры)");
$stmt->execute([данные]);
$pid = $pdo->lastInsertId(); // Получили id нового проекта

//ищем id тегов
$proj_tags = explode(",", $_GET["tags"]);
$in  = str_repeat('?,', count($proj_tags) - 1) . '?';
$sql = "SELECT id FROM tags WHERE tag_name IN ($in)";
$stm = $db->prepare($sql);
$stm->execute($proj_tags);
$tag_ids = $stm->fetchAll(PDO::FETCH_COLUMN);// получаем id тегов в массив

// Добавляем теги к проекту
$stmt = $pdo->prepare("insert into P_tags(pid, tid) VALUES (:pid, :tid)");
$stmt->bindParam(':pid', $pid);
$stmt->bindParam(':tid', $tid);
foreach($tag_ids as $tid){
    $stmt->execute();
}
$pdo->commit();
→ Ссылка