Всем привет крутил вертел таблицы разным способом и не получается составить правильный запрос, чтобы он вытягивал все значения из них которые мне нужны. 1. есть 2 таблицы из которых я хочу вытащить данные: таблица predmet_info выводим комменты инфу всякую PHP: CREATE TABLE `predmet_info` ( `id` int(11) NOT NULL, `uid` int(11) NOT NULL COMMENT 'пользователя id', `rid` int(11) NOT NULL COMMENT 'предмет id', `title` varchar(255) NOT NULL COMMENT 'описание', `description` varchar(255) NOT NULL COMMENT 'Комментарий' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; таблица user_predmet общая таблица связь предмета и пользователя, только сразу говорю, эта таблица связывает не верхнюю таблицу, а таблицу users и predmet PHP: CREATE TABLE `user_predmet` ( `id` int(11) NOT NULL, `uid` int(11) NOT NULL COMMENT 'юзер id', `rid` int(11) NOT NULL COMMENT 'предмет id' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 2. составил такой запрос: PHP: if(isset($_SESSION['uid'])) { # сохраняем сессию в переменную $uid = $_SESSION['uid']; # глобальная переменная подключения к БД global $pdo; $predmet = get_predmet(); # функция возвращает выбранный предмет $query = $pdo->prepare(' SELECT `tb1`.`id`, `tb1`.`uid`, `tb1`.`rid`, `tb1`.`title`, `tb1`.`description`, `tb2`.`uid`, `tb2`.`rid` FROM `user_predmet` `tb2` JOIN `predmet_info` `tb1` ON `tb1`.`rid` = `tb2`.`rid` WHERE `tb1`.`uid` = ?'); $query->execute([$uid]); $query->fetchAll(PDO::FETCH_ASSOC); } И что получаем таким запросом, пытаюсь вытащить данные из первой таблицы для пользователя с выбранным предметом. То есть пользователь выбирает предмет, и ему должны погрузиться комменты которые он писал ранее для этого предмета в разные дни. Данный запрос подгружает только один коммент, а мне нужно чтобы он подгружал все комменты для одного предмета определенного пользователя id которого находится в сессии. 3. Что будет предпочтительней выбрать INNER JOIN, LEFT JOIN, RIGHT JOIN или просто JOIN? 4. Жду ваших предложений или поправок в лучшую сторону, спасибо.
Вообще-то, такой запрос скорее может подтянуть больше, чем вы того ожидаете. Вы отфильтровали из таблицы "predmet_info" записи для определенного пользователя, связь со второй таблицей у вас по ID предмета. Но этот ID предмета может быть и у текущего пользователя, и у еще надцать других. Из поставленной задачи, я в принципе не вижу смысла в таблице "user_predmet", т.к. у вас в таблице "predmet_info" есть всё необходимое: "uid", "rid". PHP: SELECT * FROM `predmet_info` WHERE `uid` = 1 AND `rid` = 2
@Deonis Думаю может ты прав может нет, потому что у меня эта таблица соединяет 2 других, users и predmet: users: PHP: CREATE TABLE `users` ( `id` int(11) NOT NULL, `name` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; predmet: PHP: CREATE TABLE `predmet` ( `id` int(11) NOT NULL, `naimenovanie` varchar(255) NOT NULL COMMENT 'название предмет' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `predmet` (`id`, `naimenovanie`) VALUES (1, 'Физика'), (2, 'Химия'), (3, 'Математика'); Опишу дальнейшие действия: пользователь в форме выбирает предмет и нажимает кнопочку отправить, ему должна выпасть на экран инфа комментарии ранее добавленную в таблицах в первом посте. А в эту таблицу о которой ты пишешь что там все есть, я не знал как ее объединить с пользователем и комментарием, подумал добавлю uid и rid. Сейчас попробую вашу версию потом если будет желание обговорим данный ваш пост) --- Добавлено --- @Fell-x27 Один раз читал чем они отличаются, нужно еще раз перечитать. --- Добавлено --- Протестировал запрос действует так же выводит 1 комментарий, а мне нужно вытащить все.
@Deonis Перепроверил запрос вроде срабатывает правильно, такой легкий запрос нужно было сделать) Только в чем сахар я не могу вернуть json массив после перебора его в foreach(); пробую вернуть return json_encode($mass); он возвращает json данные только одного комментария из таблицы, а если комментов несколько как вернуть json нескольких данных?
@Dimon2x я его просто передаю в js: Код (Javascript): <script> $(function(){ var data = <?php echo $json; ?>; $('#eventCalendar').eventCalendar({ jsonData: data, startWeekOnMonday: true, openEventInNewWindow: true, dateFormat: 'dddd DD-MM-YYYY', showDescription: false, locales: { locale: "ru", txt_noEvents: "Нет запланированных событий", txt_SpecificEvents_prev: "", txt_SpecificEvents_after: "события:", txt_NextEvents: "Следующие события:", txt_GoToEventUrl: "", /*url адрес*/ moment: { "months" : [ "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь" ], "monthsShort" : [ "Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек" ], "weekdays" : [ "Воскресенье", "Понедельник","Вторник", "Среда","Четверг","Пятница","Суббота" ], "weekdaysShort" : [ "Вс","Пн","Вт", "Ср","Чт","Пт","Сб" ], "weekdaysMin" : [ "Вс","Пн","Вт", "Ср","Чт","Пт","Сб" ] } } }); }); </script> И дальше работаю с ним. Или можно без него как то обойтись?
Это у вас ответ на Ajax-запрос? Может на клиенте что-то не так делаете. В любом случае, я бы проверил перед отправкой данных переменную $mass. PHP: <?php file_put_contents('test.txt', var_export($mass, 1)); --- Добавлено --- На первый свой вопрос, я ответ получил ))
Код (Javascript): var data = <?php echo $json; ?>; console.log(JSON.parse(data)); // что в консоли видите?
Кавычки... Сразу не обратил внимание. Код (Javascript): var data = '<?php echo $json; ?>'; console.log(JSON.parse(data));
И так по порядку, таблицы может позже покажу хотя в принципе все показал: Файл function.php: PHP: <?php # вытягиваем наш предмет для определенного пользователя function get_predmet() { # если в сессии ID if(isset($_SESSION['uid'])) { # сохраняем сессию в переменную $uid = $_SESSION['uid']; # глобальная переменная подключения global $pdo; # выбираем наши предметы из базы $checkUser = $pdo->prepare(' SELECT `tb1`.`id`, `tb1`.`naimenovanie`, `tb2`.`uid`, `tb2`.`rid` FROM `predmet` `tb1` LEFT JOIN `user_predmet` `tb2` ON `tb1`.`id` = `tb2`.`rid` WHERE `tb2`.`uid` = ?'); $checkUser->execute([$uid]); $result = $checkUser->fetchAll(PDO::FETCH_ASSOC); echo '<form action="" method="POST" id="predm">'; echo '<select name="predmet">'; echo '<option>Выберие предмет</option>'; # через массив перебираем наши предметы которые приходят из базы foreach ($result as $key => $value) { $s = ($value['id'] == $key) ? 'selected': ''; printf('<option value="%s" %s>%s</option>', $value['id'], $s, $value['naimenovanie']); } echo '</select>'; echo '<input type="submit" value="Выбрать"/>'; echo '</form>'; } return $_POST['predmet']; } # функция для календаря function get_events($predmet) { # если в сессии есть ID юзера if(isset($_SESSION['uid'])) { # сохраняем сессию в переменную $uid = $_SESSION['uid']; # глобальная переменная подключения global $pdo; # вытягиваем данные из таблицы календарь $query = $pdo->prepare(' SELECT `id`, `uid`, `rid`, `color`, (unix_timestamp(`date`) * 1000) as `date`, `time`, `title`, `description` FROM `predmet_info` WHERE `uid` = ? AND `rid` = ?'); $query->execute([$uid, $predmet]); return $query->fetchAll(PDO::FETCH_ASSOC); } } # формирую json данные из массива function get_json($arr) { $data = []; # формируем массив foreach($arr as $key => $item){ $data = [$key=>$item]; } return json_encode($data); } И вот файл в котором выводится сам календарь: PHP: <?php session_start(); require_once 'config/db.php'; # подключаем базу require_once 'functions.php'; # подключаем функции для календаря $predmet = get_predmet(); # Выводим список предметов $events = get_events($predmet); # Вывод календаря $json = get_json($events); # Информация для дат если она есть комментарии и т.д. ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Календарь событий</title> <link rel="stylesheet" href="css/eventCalendar.css"> <link rel="stylesheet" href="css/eventCalendar_theme_responsive.css"> <script src="http://code.jquery.com/jquery.min.js"></script> <script src="js/moment.js"></script> <script src="js/jquery.eventCalendar.js"></script> </head> <body> <div id="eventCalendar" style="width: 300px; margin: 100px auto;"></div> <script> $(function(){ var data = '<?php echo $json; ?>'; console.log(JSON.parse(data)); // что в консоли видите? $('#eventCalendar').eventCalendar({ jsonData: data, startWeekOnMonday: true, /*если труе будет правильно дни недели*/ openEventInNewWindow: true, dateFormat: 'dddd DD-MM-YYYY', showDescription: false, locales: { locale: "ru", txt_noEvents: "Нет запланированных событий", txt_SpecificEvents_prev: "", txt_SpecificEvents_after: "события:", txt_NextEvents: "Следующие события:", txt_GoToEventUrl: "", /*url адрес*/ moment: { "months" : [ "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь" ], "monthsShort" : [ "Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек" ], "weekdays" : [ "Воскресенье", "Понедельник","Вторник", "Среда","Четверг","Пятница","Суббота" ], "weekdaysShort" : [ "Вс","Пн","Вт", "Ср","Чт","Пт","Сб" ], "weekdaysMin" : [ "Вс","Пн","Вт", "Ср","Чт","Пт","Сб" ] } } }); }); </script> </body> </html> Вот по сути у меня есть 2 файла, я сейчас работаю только с ними. При выборе предмета, мы передаем наш пост в функцию get_events($predmet) дальше мы выбираем в этой функции для пользователя с выбранным предметов есть ли у него какие комменты для каких либо дней. Ну и дальше я передаю результат в третью функцию get_json($arr) в которой уже создаю json формат который передаю в js календаря.
@_ne_scaju_, вы предыдущий комментарий прочитали? --- Добавлено --- Вот блин... Ничего, что на каждой итерации, у вас просто перезаписывается значение $data? )) PHP: <?php foreach($arr as $key => $item){ $data = [$key=>$item]; // А должно быть, скорее всего, что так: $data[] = [$key=>$item]; }
Да конечно читал, исправил, сейчас ответил за предыдущий комментарий ваш. На счет массива сейчас попробую, если была в этом затычка я просто фигею. Действительно, теперь выдает то что надо на выходе. --- Добавлено --- @Deonis js смотрим на скриншот что выдает, а вот календарь не выводит не каких комментов, кажется что зациклился. Эта строка же не цыклит console.log(JSON.parse(data)); думаю нет, она просто выводит инфу в консоль браузера.
Данные теперь выводятся корректно, а вот структура для вашего календаря, похоже, что хромает. Беглый взгляд на этот плагин и формат данных, говорит, что цикл тут вообще лишний. Т.е. ваша функция get_json, если нет каких-то подводных камней, сводится всего к одной строке: PHP: <?php function get_json($arr) { return json_encode($arr); }
По поводу этого я согласен, можно сразу в функции вывести после запроса PHP: $result = $query->fetchall() return json_encode($result); Структура чего хромает, запросов таблиц, где истина? К стати теперь получается убрал одну функцию сделал все в одной там где выполняю запрос, и а js убрал кавычки: PHP: var data = <?php echo $events; ?>; таким образом комментарии выводятся, а если поставлю кавычки то то комменты не выводятся, только в лог уходят, а в первом случает если кавычек нет то в лог не доходят они.
Структура массива. Всё остальное не важно, т.к. вывод в консоль - это только проверки/дебага. В общем, я так понимаю, что теперь всё работает?
Вроде разобрался, выводиться теперь как надо @Deonis спасибо за помощь. Теперь задача такова моя, чтобы при выборе предмета выводились данные без перезагрузки страницы, может кто поможет. Я знаю что нужно использовать ajax но если я использую функции как их обрабатывать когда я буду указывать скрипт? --- Добавлено --- Да все работает правильно, просто у этого плагина, была такая структура в ручную написан json формат я начал думать как обойти эту ерунду, и вспомнил про json_encode()
Да, можно. Код инициализации плагина, вам нужно поместить в какую-нибудь функцию, куда передавать json-строку. Код (Javascript): function initCalendar (data) { $('#eventCalendar').eventCalendar({ jsonData: data, /* прочие опции */ }); } С Ajax-ом знакомы?
С Ajax если честно на вы, но пару примеров в ручную переписывал, и старался разобрать их. Инициализировать для чего, помоги разобраться))) --- Добавлено --- @Deonis Я думал что мне всего лишь нужно будет ajax запрос сделать типа: Код (Javascript): <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <script> $( document ).ready(function() { $("#btn").click( function(){ sendAjaxForm('result_form', 'ajax_form', 'function.php'); return false; } ); }); function sendAjaxForm(result_form, ajax_form, url) { jQuery.ajax({ url: url, //url страницы (action_ajax_form.php) type: "POST", //метод отправки dataType: "html", //формат данных data: jQuery("#"+ajax_form).serialize(), // Сеарилизуем объект success: function(response) { //Данные отправлены успешно result = jQuery.parseJSON(response); document.getElementById(result_form).innerHTML = ""; }, error: function(response) { // Данные не отправлены document.getElementById(result_form).innerHTML = "Ошибка. Данные не отправленны."; } }); } </script>
Типа да. Вот только после выполнения запроса, нужно еще об этом сообщить плагину. Код (Javascript): $.ajax({ // путь к обработчику на стороне сервера url: 'path/to/handler.php', // метод передачи: GET, POST, etc type: 'GET', // важно указать тип, чтобы JSON-строка не преобразовывалась в объект dataType: 'text', // или html // если нужно в запросе передавать какие-то данные data: { some_key_1: 'some_value_1', some_key_2: 'some_value_2', }, // в случае успешного завершения запроса, вызываем функцию инициализации календаря success: initCalendar }); function initCalendar (data) { $('#eventCalendar').eventCalendar({ jsonData: data, /* прочие опции */ }); } --- Добавлено --- Кстати, в самом плагине вроде бы реализовано получение данных Ajax-ом. Правда, этот запрос будет выполняться единожды, при первой инициализации плагина.
Путь обработчика, по сути у меня это как раз файл function.php но сама обработка находится в функции пример выше посмотрите)
@Deonis PHP: $.ajax({ url: 'function.php', type: 'POST', dataType: 'text', data: { some_key_1: <?php echo $predmet; ?>, }, success: initCalendar }); function initCalendar (data) { $('#eventCalendar').eventCalendar({ jsonData: data, /* прочие опции */ }); } После такого перезагрузка страницы происходит, одно не понял от куда ты взял some_key_1 и еще не понял после прочие опции ты имел введу чтобы повторил те же самые опции?