Скрипт для сопоставления имен, отправленных через форму, с разрывом базы данных MySQL, когда имя содержит апостроф - PullRequest
0 голосов
/ 01 ноября 2011

У меня есть скрипт, который вводит имена в базу данных MySQL, используя mysql_real_escape_string, чтобы апострофы обрабатывались правильно.Проблема, с которой я сталкиваюсь, заключается в следующем сценарии, который проверяет, соответствуют ли имена, введенные с помощью другой формы, именам, уже находящимся в моей базе данных, и, если имена найдены, обновляет строку.апостроф в форму, обработанную этим сценарием, я получаю сообщение об ошибке, в котором говорится, что имя не найдено, а имя в сообщении об ошибке содержит обратную косую черту перед апострофом, что, очевидно, является проблемой.Итак, вопрос в том, как я могу изменить скрипт ниже, чтобы он работал с именами с апострофами?

Спасибо,

Ник

$row_count = count($_POST['name']);
if ($row_count > 0) {

    mysql_select_db($database, $connection);
    $name = array();
    $workshop = array(); 
    $not_found = array();

    for($i = 0; $i < $row_count; $i++) {
        // variable sanitation...
        $name[$i] = mysql_real_escape_string(ucwords($_POST['name'][$i]));
        $workshop[$i] = mysql_real_escape_string($_POST['workshop'][$i]);
    }
    $names = "('".implode("','",$name)."')";

    $not_in = Array();

    // lets say all names doesn't exist in `conference`
    foreach($name as $value) {
        // names in array are keys, not values
        $not_in[$value] = true;
    }


    $query = mysql_query("SELECT Name FROM conference WHERE Name IN $names"); 
    while(list($dbname) = @mysql_fetch_row($query)) {
        // delete those name from $not_in who exists
        unset($not_in[$dbname]);
    }

    // names in $not_in array are keys, not values
    $not_in = array_keys($not_in);

    if(empty($not_in)) {
        // its ok, all names have been found. do the magic.
        for($i = 0; $i < $row_count; $i++) {
            $sql = "UPDATE conference SET Workshop = '$workshop[$i]' WHERE Name LIKE '$name[$i]'";
            mysql_query($sql);
            $body .= "Name: " . $name[$i] . "    Workshop: " . $workshop[$i] . "\n\n";
        }

1 Ответ

1 голос
/ 01 ноября 2011

Ммм!Я думаю, я мог бы найти проблему.Проблема может быть не в запросе, а в коде PHP.Ниже я попытаюсь объяснить, используя ваш пример John O'Shea.

for($i = 0; $i < $row_count; $i++) {
    // variable sanitation...
    $name[$i] = mysql_real_escape_string(ucwords($_POST['name'][$i]));
    $workshop[$i] = mysql_real_escape_string($_POST['workshop'][$i]);
}
$names = "('".implode("','",$name)."')";

$not_in = Array();

// lets say all names doesn't exist in `conference`
foreach($name as $value) {
    // names in array are keys, not values
    $not_in[$value] = true;
}

После кода выше, массив $ not_in будет содержать экранированные ключи, потому что $ name уже содержит значения, экранированные с помощью mysql_real_escape_string ().Следовательно, например:

$ not_in [John] = true;$ not_in [John O \ 'Shea] = true;

$query = mysql_query("SELECT Name FROM conference WHERE Name IN $names"); 
while(list($dbname) = @mysql_fetch_row($query)) {
    // delete those name from $not_in who exists
    unset($not_in[$dbname]);
}

Теперь $ dbname в приведенном выше коде содержит неэкранированные значения, полученные из БД, например, John O'Shea без обратной косой черты.Поскольку это не то, что содержит $ not_in, unset () не будет работать.Это означает, что все значения апострофов остаются в массиве $ not_in.

Поэтому исправление заключается в том, чтобы сохранить неэкранированные значения в $ not_in.

Надеюсь, что это имеет смысл!

========== РЕДАКТИРОВАТЬ: В ответ на то, как сохранить неэкранированные значения в $ not_in:

Идея состоит в том, чтобы экранировать именно там, где это необходимо.Вот изменения, которые вы можете внести в свой код:

Перепишите первый for (), как показано ниже:

for($i = 0; $i < $row_count; $i++) {
    // variable sanitation...
    //$name[$i] = mysql_real_escape_string(ucwords($_POST['name'][$i]));
    $name[$i] = ucwords($_POST['name'][$i]);
    $workshop[$i] = mysql_real_escape_string($_POST['workshop'][$i]);
}
$names = "('" . mysql_real_escape_string(implode("','",$name)) . "')";

И переписайте оператор UPDATE следующим образом:

$sql = "UPDATE conference SET Workshop = '$workshop[$i]' WHERE Name LIKE '" . mysql_real_escape_string($name[$i]) . "'";

Кстати, согласно вашему коду, ОБНОВЛЕНИЕ не запустится, если в базе данных есть одно имя, которого не существует.Обязательно ли запускать UPDATE, только если все $ _POST ['name'] найдены в базе данных?Если нет, то вы можете значительно сократить объем кода.

Я не проверял вышеуказанные изменения, но думаю, что они должны работать.Сообщите мне, если возникнут какие-либо проблемы.

========== РЕДАКТИРОВАТЬ 2: Фрагмент кода для обновления существующих записей и создания ошибок для записей, которые не

ПриветНик, я думаю, что только написание приведенного ниже кода должно помочь:

$row_count = count($_POST['name']);
if ($row_count > 0) {
    mysql_select_db($database, $connection);
    for ($i = 0; $i < $row_count; $i++) {
        mysql_query("UPDATE conference SET Workshop = '" . mysql_real_escape_string($_POST['workshop'][$i]) . "' WHERE Name LIKE '" . mysql_real_escape_string($_POST['name'][$i]) . "'");
        $affectedRows = mysql_affected_rows();
        if ($affectedRows == 0) {
            echo '<br>Name did not exist - ' . $_POST['name'][$i];
        }
    }
}

Надеюсь, это поможет!

...