Правильного ответа нет. Любой выбор приводит к жертвам, любое решение требует платы. | Лишь навык имеет значение.
Здравствуйте.
Прошу помочь, если кто-нибудь вообще возьмётся разбираться в моём дурдоме)
читать дальше
Не знаю что я там изменил, но вот глючить стало.
Если кто может - посмотрите, может вы увидите в чём проблема.
К сожалению ссылку на работающий проект дать не могу, ибо он закрытый и меня за это покарают маленько ^^"
Прошу помочь, если кто-нибудь вообще возьмётся разбираться в моём дурдоме)
читать дальше
Не знаю что я там изменил, но вот глючить стало.
Если кто может - посмотрите, может вы увидите в чём проблема.
К сожалению ссылку на работающий проект дать не могу, ибо он закрытый и меня за это покарают маленько ^^"
-
-
07.06.2012 в 21:37Поэтому просто несколько комментов:
Проще говоря, поле в ячейке на третьей строке в седьмом столбце имеет id="p37"
А каждая строка это отдельный юзер? Просто, например, 11-я строка, 1-й столбец и 1-я строка, 11-й столбец — будут иметь один id. Впрочем, если столбцы никогда не будут иметь номер больше 9, то не важно.
for (var i = "0"; i < ku; i++)
Зачем инициализировано строкой 0, а не числом 0?
$ku = mysql_escape_string($ku);
mysql_escape_string() не будет работать с многобайтовыми кодировками, нужно использовать mysql_real_escape_string(). В свою очередь, для последней требуется установленное соединение с базой, т.к. невозможно правильно экранировать данные, если неизвестна кодировка соединения.
-
-
07.06.2012 в 22:23Про это кстати не подумал. Но у меня 9 столбцов, так что я на это не нарвался. А вообще - спасибо, я где-то в августе буду весь проект пелелопачивать, как раз и подправлю индексацию)))
Зачем инициализировано строкой 0, а не числом 0?
Оу. Видимо я был не в себе.))) Плавающий дедлайн - страшная штука)))
mysql_escape_string() не будет работать с многобайтовыми кодировками, нужно использовать mysql_real_escape_string().
Не, тут как раз всё правильно. Я специально тестил. Не помню в чём там дело было, но как раз-таки _real_ мне на выходе давало не то что нужно. А кодировка - utf8 у меня. Такое же соединение и кодировка таблиц.
Возможно дело в том, что _real_ надо после соединения делать, а у меня все данные и запросы до соединения подготавливаются. Ибо после соединения там и так ветвлений хватает, и запихивать туда ещё "дерево" формирвания запроса как-то напряжно. Хотя может в будущем так и сделаю, всё равно буду проект переделывать.
Ну я лично не заметил явного косяка в коде. Вероятно, он где-то в другом месте.
Да вот непонятка. Всё работало уже полтора месяца как. А тут мне сегодня падает письмо с описанием. Пошёл, посмотрел - действительно. Хотя, говорю же, проект активно используется уже больше месяца. Это что-то недавнее.
Очень надеюсь, что это из-за ошибки в клиентской части. Сейчас прогоняю каждую функцию через www.javascriptlint.com. Кое-что уже подправил. Дойду до конца скрипта, буду смотреть как оно.
А то получается "отпусти меня чудо-трава". Вроде уже всё оттестил, запустил, народ пользуется, все частливы. И тут вылезает такая вот хрень. Причём ВНЕЗАПНО. Ладно, потом отпишусь, если найду в чём дело было.
-
-
07.06.2012 в 23:33-
-
08.06.2012 в 01:20Роль INSERT IGNORE'ов так же могут выполнять UPDATE ... ON DUPLICATE KEY INSERT IGNORE. Ну и в браузере (в отладчике) последить за запросами к серверу. Обычно там есть опция «не очищать список запросов при переходе на другую страницу».
Не, тут как раз всё правильно. Я специально тестил. Не помню в чём там дело было, но как раз-таки _real_ мне на выходе давало не то что нужно. А кодировка - utf8 у меня. Такое же соединение и кодировка таблиц.
Возможно дело в том, что _real_ надо после соединения делать, а у меня все данные и запросы до соединения подготавливаются. Ибо после соединения там и так ветвлений хватает, и запихивать туда ещё "дерево" формирвания запроса как-то напряжно. Хотя может в будущем так и сделаю, всё равно буду проект переделывать.
Да, именно так. Потому что правильно проэкранировать возможно только зная кодировку соединения с базой. А её можно узнать только с базой соединившись.
Но вообще, конечно, всё не так страшно. ) В случае однобайтовых кодировок и UTF-8 обмануть обычный mysql_escape_string() не получится, т.к. в UTF-8 обратная косая черта не может быть частью другого символа. Впрочем, можно вспомнить классический случай с Simple Machines Forum, где существовала ещё одна уязвимость, позволявшая назначить соединению с базой произвольную кодировку.
А по поводу того, что можно переделать…
url = "z.php?f=2&login=" + encodeURIComponent(login) + "&ku=" + encodeURIComponent(ku) + "&zay=" + encodeURIComponent(t2) + "&num=" + encodeURIComponent(c1) + "&fio=" + encodeURIComponent(c2) + "&nick=" + encodeURIComponent(c3) + "&pers=" + encodeURIComponent(c4) + "&email=" + encodeURIComponent(c5) + "&tel=" + encodeURIComponent(c6) + "&contact=" + encodeURIComponent(c7) + "&age=" + encodeURIComponent(c8) + "&city=" + encodeURIComponent(c9);
getAjax (url, nof);
В таких местах просто напрашивается функция. А учитывая, что это AJAX-запрос, было бы логично, чтобы вызов был, например, таким:
Оу. Видимо я был не в себе.))) Плавающий дедлайн - страшная штука)))
Да бывает. ) Просто это потенциальная ошибка, т.к. в JS «+» это ещё и конкатенация.
Поэтому i++ — всё равно будет инкремент на 1, а вот i += 1 — получатся строки «01», «011» и т.д.
-
-
08.06.2012 в 01:39Или если самому кодировку соединения указывать. Не?
Надо поискать по всем файлам проекта все INSERT IGNORE'ы в эту таблицу и перед каждым поставить вывод в лог: имя файла, время и т.п. Чудес-то не бывает.
Роль INSERT IGNORE'ов так же могут выполнять UPDATE ... ON DUPLICATE KEY INSERT IGNORE. Ну и в браузере (в отладчике) последить за запросами к серверу. Обычно там есть опция «не очищать список запросов при переходе на другую страницу».
Пока решил принудительной проверкой на наличие в базе пользователя с заданным номером. То бишь, если пользователь с таким номером уже есть, то итерация пропускается и начинается новая.
Вообще, надо какой-нибудь отладчик, который будет и с js и с php работать, наверное.
А по поводу того, что можно переделать…
url = "z.php?f=2&login=" + encodeURIComponent(login) + "&ku=" + encodeURIComponent(ku) + "&zay=" + encodeURIComponent(t2) + "&num=" + encodeURIComponent(c1) + "&fio=" + encodeURIComponent(c2) + "&nick=" + encodeURIComponent(c3) + "&pers=" + encodeURIComponent(c4) + "&email=" + encodeURIComponent(c5) + "&tel=" + encodeURIComponent(c6) + "&contact=" + encodeURIComponent(c7) + "&age=" + encodeURIComponent(c8) + "&city=" + encodeURIComponent(c9);
getAjax (url, nof);
В таких местах просто напрашивается функция. А учитывая, что это AJAX-запрос, было бы логично, чтобы вызов был, например, таким:
getAjax(
'z.php',
{
f: 2,
login: login,
ku: ku,
zay: t2,
num: c1,
...
},
nof
);
Да я просто в данном случае не вижу в этом смысла. Ибо только в одном месте используется. На редактировании - там юрл иначе строится. Просто не вижу смысла делать функцию для чего-то, что выполняется меньше трёх раз. К тому же тут ничего особо сложного нет, чтобы упрощать за счёт функции.
Хотя... в принципе можно будет подумать, может в слегка другом срезе можно будет действительно сделать функцией.
Пока в плане есть, как минимум переписание всё на POST-запросы аяксовские. А то у меня почти везде аякс GET-ом, что не есть хорошо, т.к. у пользователей ручки шаловливые.)) Хотя некоторые вещи надо будет в гете оставить. Например номер ресурса. Ибо очень удобно, когда с одним ресурсом закончил, вбить в адресную строку номер следующего нужного и сразу на него попасть. А не возвращаться каждый раз к списку и искать там. Даже с фильтрами это порой долго.
Вообще, многое надо будет переделать - от сss и обработки форм, до работы с базой. Но это не раньше чем июль пройдёт. Сейчас пик активности и без надобности лучше ничего не делать. Ибо главная заповедь - "работает - не трожь"))) А августе будет затишье и можно будет системку переписать по уму, без спешки.
Спасибо за помощь.
-
-
08.06.2012 в 02:05Так дело не в том, что сложное, дело в том, что это длинная копипастная портянка. Малейшая опечатка — и придётся внимательно просматривать каждый символ, а их много и большая часть — повторяются. Ну и потом — это просто как пример. )
если пользователь с таким номером уже есть
А эти айдишники уникальны? Просто может быть на них стоит уникальный индекс повесить в базе. Особенно, если по этому полю потом будут запросы.
Или если самому кодировку соединения указывать. Не?
Где? В mysql_escape_string() только один аргумент — сама строка.
-
-
08.06.2012 в 02:26Ну, в принципе да. Верно всё.
А эти айдишники уникальны? Просто может быть на них стоит уникальный индекс повесить в базе. Особенно, если по этому полю потом будут запросы.
Ну, таблица строится так:
1) id - уникален, первичный ключ с автоинкрементом.
2) zay - к какому ресурсу принадлежит пользователь.
3) num - номер пользователя.
Ну и дальше всякая инфа о пользователе - контакты, фио и т.д. В пределах одного ресурса номера не могут повторяться (проблема как раз и была, что один пользователь дублировался несколько раз).
Номера пользователей никто поменять не может. Они соответствуют строкам. То бишь, пользователь в пятой строке имеет num=4 (с нуля ж считается). А при выводе в таблицу, в инпуты/поля, просто делается запрос к таблице, где запрашиваются пользователи с zay=номеру ресурса. Ну и сортируются по номерам пользователей, чтобы были выведены в том же порядке, в каком их заносили в таблицу.
Где? В mysql_escape_string() только один аргумент — сама строка.
Ну... допустим так:
"MySQL не всегда возвращает данные в той кодировке, которая необходима. Решение проблемы вопросиков, квадратиков при выдаче запросов из MySQL довольно простое. После соединения с базой данных нужно отправить запросы на установку кодировки соединения.
mysql_query("set character_set_client='cp1251'");
mysql_query("set character_set_results='cp1251'");
mysql_query("set collation_connection='cp1251_general_ci'");
relaxart.ru/archives/340"
Я про то, что кодировку соединения можно указать после соединения. Тогда данные можно преобразовывать простым mysql_escape_string. Хотя в моём случае нет необходимости устанавливать кодировку соединения, ибо всё под utf8 настроено. И таблицы, и соединение, и скрипты, и сами странички))) Я просто решил что правильнее и проще будет использовать одну кодировку везде)
-
-
08.06.2012 в 03:393) num - номер пользователя.
Можно индекс повесить на два поля: alter table `table` add unique index(`zay`, `num`). В таком случае база гарантирует, что связка ресурс—пользователь будет всегда уникальна (при попытке вставки ещё одной записи — выдаст ошибку). Заодно это может ускорить выборку по ресурсу и сортировку по пользователям в пределах одного ресурса.
-
-
08.06.2012 в 03:43-
-
08.06.2012 в 11:53Если принципиально важно, чтобы остальные ошибки при запросе всё же выводили пользователю предупреждение, то можно пойти другим путём: делать insert ignore, а затем выполнить mysql_affected_rows(). Если вставлено 0 записей, но запрос выполнился успешно (без ошибок), значит была коллизия с уже существующим значением.