Я буду стараться изо всех сил, но есть что покрыть.
comments.php
//add the target files URL as the form's action
<form method="POST" id="comment_form" action="add_comment.php" >
//add movie to the form, that way when we insert the comment we know what its for
<input type="hidden" name="movie_id" id="movie_id" value="<?php echo $movie_id; ?>" />
//.. in your JS, add the movie id to the fetch comment call
function load_comment()
{
$.ajax({
url:"fetch_comment.php",
method:"POST",
data: {movie_id : <?php echo $movie_id; ?>},
dataType: 'json',
success:function(data){
//...
})
}
//move this below the function definition
load_comment();
add_comment.php
//add movie id here to match what is in the form above
INSERT INTO tbl_comment
(parent_comment_id, comment, comment_sender_name, movie_id)
VALUES (:parent_comment_id, :comment, :comment_sender_name, :movie_id)
// add ':movie_id' => $_POST['movie_id'] to the array you have there for
// $statement->execute([ ....]). The arrays below go the same way
//add those to $statement->execute() for there respective DB calls,
У вас был фильм в части FIELDS вставки, но не VALUES, что, вероятно, является ошибкой синтаксиса SQL. Вы, возможно, не видели фактическую ошибку, потому что она вызывается с AJAX, поэтому она просто сломается на стороне клиента Вы можете посмотреть в окне отладки браузера> сетевые [XHR] запросы и посмотреть ответ. Там вы, вероятно, найдете его или просто получите 500-ю ошибку с сервера.
fetch_comment.php
//add movie id here to match what is in the AJAX fetch comment call
SELECT * FROM tbl_comment
WHERE parent_comment_id = :parent_comment_id AND movie_id = :movie_id
ORDER BY comment_id DESC
//for execute add
['parent_comment_id'=>0, 'movie_id'=>$_POST['movie_id']]
Важно правильно подготовить этот запрос
$query = "
SELECT * FROM tbl_comment WHERE parent_comment_id = '".$parent_id."'
";
Так и должно быть:
$query = "SELECT * FROM tbl_comment WHERE parent_comment_id = :parent_id";
//then add this to execute ['parent_id' => $parent_id]
mainpage.php (не уверен, что имя на этом)
В последнем неназванном фрагменте кода, который вы используете mysqli
, но вместо того, чтобы использовать PDO
, лучше использовать один или другой, лично я предпочитаю PDO, просто лучше API. Вы также не готовите их (поэтому конвертируйте их в PDO). Использование обоих просто добавляет ненужную сложность вашему приложению (я думаю, что там было 2 из этих тезисов):
$qry2=mysqli_query($con,"select * from tbl_movie where movie_id='".$_GET['id']."'");
$movie=mysqli_fetch_array($qry2);
Похоже, что вы включили comments.php
в эту последнюю страницу <?php include('comments.php'); ?>
Так что я бы сделал, когда запрос выше, который я сказал исправить:
require_once `db.php`; //- create a separate file to do the DB connection for you
//then you can add that to the top of all the pages you need the DB for
include 'header.php'; //no need for the ( ) for any of the include* or require* calls.
/*
require will issue an error if the included file is not found
include will fail silently, for things that are required for your
page to work and not produce errors use require (like the DB)
for things you only ever include once, also like the DB stuff use *_once
then no matter how many *_once calls are stacked from including
the other page you don't have to worry about it.
as above those simple rules give us require_once for the DB.
the other pages I am not sure which would be best.
*/
//localize the movie ID - change any use of `$_GET['id']
$movie_id = isset($_GET['id']) ? $movie_id : false;
if(!$movie_id){
//do something if someone goes to this page with no ?id= in the URL
//you could redirect the page
//you could have a default movie id etc...
}
$statement = $con->prepare('select * from tbl_movie where movie_id=:movie_id');
$statement->execute(['movie_id' => $movie_id]);
$movie = $statement->fetch();
//dont forget to fix the other DB call and remove the MySqli stuff.
Выше я предлагаю использовать один файл для БД, в вашем случае это может быть довольно просто,
db.php
<?php $con = new PDO('mysql:host=localhost;dbname=db_movie', 'root', '');
Это буквально все, что вам нужно, в самом верху каждой страницы, на которой вы используете БД, просто добавьте этот файл
require_once 'db.php';
Таким образом, если вам нужно изменить пароль или что-то в этом роде, вы можете перейти в одно место, названное так, чтобы его было легко запомнить и изменить. Как это сейчас, вам придется копать весь свой код, чтобы изменить его. На этой странице вы включаете файл с именем header.php
, и из вашего кода MySQLi похоже, что там могут быть какие-то соединения. Я бы тоже удалил все вещи MySQLi. Вы хотите сохранить файл БД отдельно, так как вам может потребоваться включить его в бэкэнд-части AJAX, и любой вывод из header.php приведет вас в замешательство.
Summery
То, что я показал выше, является простым примером того, что вам нужно сделать, в этом вызове AJAX. Это может быть не все, что вам нужно делать, это просто то, что было для меня очевидно.
Вам не нужно беспокоиться об идентификаторе фильма для дочернего комментария, поскольку они наследуют его от родительского комментария, который не существовал бы (на странице), если бы он имел неправильный идентификатор. В вашей текущей настройке я все равно сохраню это как часть данных. Просто вам это не нужно, чтобы получать комментарии детей, если вы знаете родителя (что вы должны знать). Я не добавил это в одну вещь, которая выглядела так, как будто это было для детского комментария Вы можете добавить его, но, как я уже сказал выше, это на самом деле не нужно.
На самом деле вопрос очень широкий, почему мой код не работает. Единственная причина, по которой я приложил усилия, заключалась в том, что вы также приложили усилия для обеспечения хорошо организованного кода, который является относительно минимальным.
Так что спасибо вам за это.
Последнее предложение, которое я хотел бы сделать, это очистить дополнительные строки, возвращаемые в некоторых SQL, и немного лучше отформатировать TAB. Но это всего лишь проблема читабельности, я очень требователен к форматированию своего кода, и некоторые из них могут быть связаны с созданием вопроса о SO, так как требуется некоторое время для использования уценки, которую они используют.
Надеюсь, это поможет вам!
Обновление
спасибо за ваш ответ, я действительно не знаю, что я должен публиковать здесь и что я не должен, и что я не понимаю, так это: у меня есть tbl_comment, в котором хранятся все комментарии пользователя, и эта таблица включает movie_id, и я иметь другой tbl_movie, у которого movie_id в качестве первичного ключа, как я могу связать _id фильма с tbl_comment, чтобы каждый комментарий сохранялся для определенного movie_id
Я попытаюсь объяснить пример вашего приложения на примере. Для примера рассмотрим идентификатор фильма 12
и нашу главную страницу www.example.com/movies?id=12
:
Вставка комментария
- Пользователь переходит на URL с
?id=12
- все, что после
?
называется строкой запроса
- PHP знает, что нужно взять строку запроса и заполнить глобальный ужин
$_GET
- так что на главной странице ваш идентификатор фильма теперь
$_GET['id']
- Мы локализуем это (создаем локальную переменную) в верхней части страницы с некоторыми базовыми проверками.
$movie_id = isset($_GET['id']) ? $movie_id : false;
- если идентификатор фильма установлен
?id=12
, тогда введите его в $movie_id
- , если не
www.example.com/movies
, тогда установить $movie_id
в false
- это позволяет избежать некоторых ошибок, если кто-то переходит на страницу без этого набора
- В нижней части страницы вы включаете этот файл
<?php include('comments.php'); ?>
думайте, что это как вставка этого кода в это место
В comments.php
, который работает, когда он включен выше,
- если кто-то вставляет новый комментарий (отправляет форму), мы добавляем тот же
$movie_id
в форму с этой строкой
<input type="hidden" name="movie_id" id="movie_id" value="<?php echo $movie_id; ?>" />
.
-Так что теперь, когда форма отправляется на add_comment.php
, который вам нужно вставить в действие формы.
<form method="POST" id="comment_form" action="add_comment.php" >
- Он будет содержать идентификатор как
$_POST['movie_id']
на этой странице. $_POST['movie_id']
в основном совпадает с $_GET['id']
, но форма method
говорит нам о post
вместо get
. Обычно Get
используется для получения ресурсов, Post
используется для их изменения.
- Когда PHP запускает вышеуказанный фрагмент HTML, он заменяет
<?php echo $movie_id; ?>
его значением 12
, поэтому вы получите
<input type="hidden" name="movie_id" id="movie_id" value="12" />
Теперь На add_comment.php
(куда нас ведет действие формы) мы можем взять это $_POST['movie_id']
и добавить его к вашему SQL, используемому для вставки комментария из формы в # 4. в базу данных.
INSERT INTO tbl_comment
(parent_comment_id, comment, comment_sender_name, movie_id)
VALUES (:parent_comment_id, :comment, :comment_sender_name, :movie_id)
- Поскольку это подготовленный оператор, в запросе SQL есть заполнитель
:movie_id
. В PDO мы можем передать это объекту PDOStatment ($statement
), который вы возвращаете из $statment=$conn->prepare($sql)
, вызывая его метод execute
или $statement->execute([..other stuff here..., 'movie_id'=>$_POST['movie_id']])
.
- Запрос, который запускается, выглядит так, как только PHP завершил работу с ним
INSERT INTO tbl_comment
(parent_comment_id, comment, comment_sender_name, movie_id)
VALUES (0, 'foo', 'ArtisticPhoenix', 12)
<- посмотри, что я там делал. </li>
Итак, вы видите, что мы взяли значение из исходного URL-запроса, добавили его в нашу форму, а затем ожидаем действий пользователя для отправки этой формы со встроенным в нее идентификатором фильма. Когда форма отправляется, она вызывает нашу страницу добавления комментариев, где мы извлекаем ее из опубликованных данных и передаем в БД вместе с остальными данными формы для этого комментария.
Остальные точно такие же, за исключением тех, которые мы используем AJAX для отправки данных, поэтому вместо формы мы просто добавляем их в вызов AJAX. Я дам вам пример того, как это выполняется.
Отображение комментария
То же самое до # 4 выше
- В
comments.php
вы вызываете load_comment();
«После», определяя функцию, поскольку она не существует, говорит вам, что вы делаете это, поэтому вы не можете вызвать ее раньше.
- Это запускает ваш AJAX-запрос
$.ajax
, для целей этого примера думайте о нем как о причудливом способе создания формы. url
- это форма action
, method
- это метод. data
- это данные формы, dataType
- это тип кодировки в данном случае JSON
или объектная нотация Javascript. Что является причудливым способом сказать структурированные данные, так как в PHP это в основном массив (или данные с вложенными элементами).
- URL (
action
) указывает нам на fetch_comment.php
, поэтому, когда он запускается, наш data: {movie_id : <?php echo $movie_id; ?>},
становится data: {movie_id : 12},
, который отправляется обратно на сервер, где PHP видит его как $_POST['movie_id']
- Как и в случае вставки, мы используем этот идентификатор в нашем запросе SQL, который извлекает комментарии родителей
SELECT * FROM tbl_comment
WHERE parent_comment_id = :parent_comment_id AND movie_id = :movie_id
ORDER BY comment_id DESC
- Это говорит: «Выберите все столбцы из таблицы tbl_comment, ГДЕ parent_comment_id равен 0, а идентификатор фильма равен 12», поэтому он будет возвращать только комментарии к фильму 12, которые также являются родителями.
- в вашем коде у вас просто
$statement->execute();
Но у вас parent_comment_id
жестко закодировано как 0
. Это было хорошо, пока нам не нужно было добавить movie_id
. После того, как мы это сделали, у него появляется больше смысла, чтобы сделать его частью подготовленного утверждения, чтобы оно читалось лучше. Но, как и во вставке, теперь у нас есть место вместо значений, поэтому нам нужно взять эти данные и добавить их к execute
для этого запроса.
- Таким образом,
$statement->execute();
становится $statement->execute(['parent_comment_id'=>0, 'movie_id' => $_POST['movie_id']]);
Или когда PHP завершает работу с ним $statement->execute(['parent_comment_id'=>0, 'movie_id' => 12]);
, который знает, что База данных использует ключи для соответствия местозаполнителям, и это завершает наш запрос.
SELECT * FROM tbl_comment
WHERE parent_comment_id = 0 AND movie_id = 12
ORDER BY comment_id DESC
- Затем мы берем результаты и отправляем их обратно обработчику
success
для AJAX с echo
и в этом случае добавляем его на страницу с этой строкой $('#display_comment').html(data);
Итак, в заключение
Ваш код:
load_comment();
function load_comment()
{
$.ajax({
url:"fetch_comment.php",
method:"POST",
success:function(data)
{
$('#display_comment').html(data);
}
})
}
Правильный код (что я сказал):
//.. in your JS, add the movie id to the fetch comment call
function load_comment()
{
$.ajax({
url:"fetch_comment.php",
method:"POST",
data: {movie_id : <?php echo $movie_id; ?>},
dataType: 'json',
success:function(data){
//...
})
}
load_comment();
Что нужно сделать
//$movie_id = $_GET['id'] in the main page that included this file.. #2 above
function load_comment()
{
$.ajax({
url:"fetch_comment.php",
method:"POST",
data: {movie_id : <?php echo $movie_id; ?>},
dataType: 'json',
success:function(data)
{
$('#display_comment').html(data);
}
});
}
load_comment();
Когда PHP завершает приведенный выше код, он отправляет его клиенту (используя 12
из нашего примера)
//$movie_id = $_GET['id'] in the main page that included this file.. #2 above
function load_comment()
{
$.ajax({
url:"fetch_comment.php",
method:"POST",
data: {movie_id : 12}, //PHP takes the value of $movie_id and puts it here
dataType: 'json',
success:function(data)
{
$('#display_comment').html(data);
}
});
}
load_comment();
Это то, что на самом деле работает в браузере
Это в значительной степени суть этого. Как я уже сказал, вам выгоднее узнать, как это работает. Конечно, я могу опубликовать полный код, но у меня нет возможности проверить его, нет способа узнать, все ли это ошибки или нет. Если вы узнаете, как это работает, вы будете лучше подготовлены к тому, чтобы справиться с этими проблемами самостоятельно. Я бы скорее потратил 3 или 4 раза усилия, чтобы научить вас, как все это работает, а затем опубликовать некоторый код, который вы не знаете, как он работает.
Надеюсь, что все имеет смысл.