Как я могу исправить свой код PHP для этого запроса SQL?

0

Я некоторое время занимался этим, и я почти там. Просто нужно пройти мимо этой стены, которую я ударил.

У меня есть следующие таблицы:

tracks (trackid, tracktitle, albumid, composerid)
albums (albumid, albumname)
composers (composerid, composername)

Я могу вставить новую запись через вкладку PhpMyAdmin SQL с помощью

INSERT INTO tracks (tracktitle, albumid, composerid) VALUES ('New Song', 1, 1);

и он отлично работает.

Моя PHP-форма, хотя и не делает то же самое, и я, должно быть, что-то пропустил. Пожалуйста, кто-нибудь может проверить код моей страницы addtrack и рассказать мне, что не так?

 if (isset($_POST['tracktitle'])): 
 // A new track has been entered
 // using the form.

 $cid= $_POST['cid'];
 $tracktitle = $_POST['tracktitle'];
 $albs = $_POST['albs'];

 if ($cid == '') {
 exit('<p>You must choose an composer for this track. 
 Click "Back" and try again.</p>');
  }

  $sql = "INSERT INTO tracks SET
  tracks.tracktitle='$tracktitle'" ;
  if (@mysql_query($sql)) {
  echo '<p>New track added</p>';
  } else {
  exit('<p>Error adding new track' . mysql_error() . '</p>');
  }

  $trackid = mysql_insert_id();

  if (isset($_POST['albs'])) {
   $albs = $_POST['albs'];
   } else {
   $albs = array();
   }

  $numAlbs = 0;
  foreach ($albs as $albID) {
  $sql = "INSERT IGNORE INTO tracks (trackid, albumid, 
  composerid) VALUES " . 
"($trackid, $albs, $cid)";

if ($ok) {
  $numAlbs = $numAlbs + 1;
} else {
  echo "<p>Error inserting track into album $albID: " .
      mysql_error() . '</p>';
}
}
 ?>

<p>Track was added to <?php echo $numAlbs; ?> albums.</p>

 <p><a href="<?php echo $_SERVER['PHP_SELF']; ?>">Add another 
 track</a></p>
 <p><a href="tracks.php">Return to track search</a></p>

 <?php
 else: // Allow the user to enter a new track

 $composers = @mysql_query('SELECT composerid, composername 
 FROM composers');
  if (!$composers) {
 exit('<p>Unable to obtain composer list from the 
database.</p>');
 }

$albs = @mysql_query('SELECT albumid, albumname FROM albums');
 if (!$albs) {
 exit('<p>Unable to obtain album list from the 
 database.</p>');
 }
 ?>

 <form action="<?php echo $_SERVER['PHP_SELF']; ?>" 
 method="post">
 <p>Enter the new track:<br />
 <textarea name="tracktitle" rows="1" cols="20">
 </textarea></p>
 <p>Composer:
 <select name="cid" size="1">
  <option selected value="">Select One</option>
  <option value="">---------</option> 
  <?php
   while ($composer= mysql_fetch_array($composers)) {
    $cid = $composer['composerid'];
    $cname = htmlspecialchars($composer['composername']);
    echo "<option value='$cid'>$cname</option>\n";
     }
    ?>
    </select></p>
    <p>Place in albums:<br />
   <?php
   while ($alb = mysql_fetch_array($albs)) {
    $aid = $alb['albumid'];
    $aname = htmlspecialchars($alb['albumname']);
     echo "<label><input type='checkbox' name='albs[]'
    value='$aid' />$aname</label><br />\n";
    }
   ?>

Как только я это отсортировал, я могу перейти к его расширению, а также решить проблемы безопасности. Кто-то здесь рекомендовал мне заглянуть в PDO, что для меня новое. Но одно препятствие за раз.

Спасибо

  • 0
    Получаете ли вы сообщение об ошибке, и если да, что оно говорит? - РЕДАКТИРОВАТЬ: На самом деле, я вижу проблему сейчас.
  • 0
    Вам также не хватает endif; в самом конце (открытие if: никогда не закрывается).
Показать ещё 3 комментария
Теги:
phpmyadmin

3 ответа

1
Лучший ответ

Синтаксис INSERT неверен. Вы пытаетесь вставить INSERT с помощью синтаксиса UPDATE.

Вы пытаетесь:

INSERT INTO table_name SET field_name = '$value', another_field_name = '$another_value'

Но вы должны делать:

INSERT INTO table_name (
    field_name,
    another_field_name
)
VALUES (
    '$value',
    '$another_value'
)

Кроме того, вы действительно должны использовать addlahes(), например:

INSERT INTO table_name (
    field_name,
    another_field_name
)
VALUES (
    '".addslashes($value)."',
    '".addslashes($another_value)."'
)

В противном случае ваш код легче взломать, чем отварной картофель.:)

EDIT: Чад Берч (ниже) предлагает скорее использовать параметризованные значения, которые, по общему признанию, лучше, чем addslashes(). Я, честно говоря, не знал, что PHP уже есть.

  • 1
    INSERT INTO table_name SET field_name = 'foo', another_field_name = 'bar' совершенно допустимо в MySQL.
  • 0
    Ну, я буду проклят! Это работает на моей установке MySQL, но не MS-SQL. Конечно, это не стандартный SQL, хотя?
Показать ещё 4 комментария
0

Мой предыдущий ответ был неправильным (и удален). Теперь я узнал, что синтаксис Insert действительно действителен.

Но то, что вы не делаете, это избежать значения, которое вы указали в запросе. Если $tracktitle содержит любые недопустимые символы, такие как одиночная цитата, это может сломать ваш запрос.

Вы должны добавить эту строку перед созданием запроса на вставку:

$tracktitle = mysql_real_escape_string($tracktitle);

Текущий код очень денгиру. Если бы я должен был вставить песню, и в названии песни я бы напечатал YourF... ed, oh, кстати '; drop database YourDataBaseName; вы должны попытаться представить, что произойдет.

Это называется SQL-инъекцией. Поскольку вы не правильно избегаете значения, кто-то еще может закрыть statment en, запустив новый оператор, просто вставив его в поле формы html.

Я не знаю, является ли это причиной того, что ваш запрос не работает прямо сейчас (он только ломается, если вы вводите недопустимый символ), но это серьезная проблема на данный момент.

Чтобы узнать вашу точную ошибку, вы должны отобразить результаты mysql_error(), когда mysql_query() возвращает false. Это, вероятно, поможет вам больше, чем любые случайные догадки, которые мы можем сделать здесь.

  • 0
    Спасибо. Я буду углубляться дальше и читать о PDO и прочее.
0

Проблемы в ваших запросах. Попробуйте использовать функцию mysql_error, чтобы получить дополнительную информацию о том, что вы делаете неправильно.

В качестве примера ваш оператор INSERT неверен.

У вас есть:

$sql="INSERT INTO tracks SET tracks.tracktitle='$tracktitle'"

Это должно быть что-то вроде:

$sql="INSERT INTO tracks (tracktitle) VALUES ('$tracktitle')";
  • 0
    Благодаря Wi-Fi, я уже исправил это в другом разделе кода, но, очевидно, пропустил это за этот бит. Очевидно, не осознавал разницу. Учимся все время ....
  • 0
    Нет проблем, Падж, мы здесь, чтобы помочь друг другу: D Ура
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню