|
|
|
| Ответ 001 на задачу N 21.
С условиями задачи можно ознакомится по ссылке.
Для подключения базы данных использовал конфигурационный файл от softtime.ru
guest_config.php
<?php
///////////////////////////////////////////////////
// 2006 (C) IT-студия SoftTime (http://www.softtime.ru)
///////////////////////////////////////////////////
// Cейчас выставлен сервер локальной машины
$dblocation = "localhost";
// Имя базы данных, на хостинге или локальной машине
$dbname = "test";
// Имя пользователя базы данных
$dbuser = "root";
// и его пароль
$dbpasswd = "";
// Устанавливаем соединение с базой данных
$dbcnx = @mysql_connect($dblocation,$dbuser,$dbpasswd);
if (!$dbcnx) {
exit( "<P>В настоящий момент сервер базы данных не доступен, поэтому корректное отображение страницы невозможно.</P>" );
}
// Выбираем базу данных
if (! @mysql_select_db($dbname,$dbcnx) ) {
exit( "<P>В настоящий момент база данных не доступна, поэтому корректное отображение страницы невозможно.</P>" );
}
// Определяем версию сервера
$query = "SELECT VERSION()";
$ver = mysql_query($query);
if(!$ver) exit("Ошибка при определении версии MySQL-сервера");
$version = mysql_result($ver, 0);
list($major, $minor) = explode(".", $version);
// Если версия выше 4.1 сообщаем серверу, что будем работать с
// кодировкой cp1251
if($major >= 4 && $minor >= 1)
{
mysql_query ("set character_set_client='cp1251'");
mysql_query ("set character_set_results='cp1251'");
mysql_query ("set collation_connection='cp1251_general_ci'");
}
?>
|
guest.php
<?php
session_start();
include "guest_config.php";
$do = $_GET['do'];
if ($do == "add")
{
$name = trim($_POST['name']);
if (!$name or strlen($name) > 255)
{
echo "Вы не ввели свое имя! Либо, оно длинее 255 символов!";
}
else
{
$_SESSION['name'] = $name;
$name = mysql_escape_string($name);
$result = mysql_query("SELECT * FROM guests WHERE guestname = '".$name."'");
$row = mysql_fetch_assoc($result);
if ($row)
{
mysql_query("UPDATE guests SET visits = '".($row['visits'] + 1)."' WHERE guestname = '".$name."'");
}
else
{
mysql_query("INSERT INTO guests (guestname, visits) VALUES ('".$name."', 1)");
}
header("Location: ".$_SERVER['PHP_SELF']."?do=show");
}
}
elseif ($do == "del")
{
$id = (int)$_GET['id'];
if ($id)
{
mysql_query("DELETE FROM guests WHERE id = '".$id."'");
header("Location: ".$_SERVER['PHP_SELF']."?do=show");
}
else echo "Запись не найдена";
}
elseif ($do == "show")
{
$name = stripslashes($_SESSION['name']);
$i = 0;
$str = "<script>
function delstr (name, id)
{
if (confirm(name + '! Вы действительно хотите вычеркнуть этого гостя?'))
window.location='".$_SERVER['PHP_SELF']."?do=del&id=' + id;
else return false;
}
</script>
Привет, ".htmlspecialchars($name, ENT_QUOTES)."! Вы знаете, что в Вашем имени ".strlen($name)." символов?<br><br>
".($_GET['searchname'] ? "Вы искали посетителя" : "Нас уже посетили").":<br>
<table border='1'>
<tr>
<td>N</td>
<td>Гость</td>
<td>визит</td>
<td>X</td>
</tr>";
$addquery = $_GET['searchname'] ? "WHERE guestname = '".mysql_escape_string(urldecode($_GET['searchname']))."'" : "";
$result = mysql_query("SELECT * FROM guests " . $addquery);
while ($row = mysql_fetch_assoc($result))
{
$str .= "<tr>
<td>".(++$i)."</td>
<td><a href='".$_SERVER['PHP_SELF']."?do=show&searchname=".urlencode($row['guestname'])."'>".htmlspecialchars($row['guestname'], ENT_QUOTES)."</a></td>
<td>".$row['visits']."</td>
<td><a href='#' onclick='delstr(\"".htmlspecialchars($name, ENT_QUOTES)."\", ".$row['id'].")'>del</a></td>
</tr>";
}
if ($i == 0) $str .= "<tr><td colspan='4'>Такой пользователь не появлялся</td></tr>";
$str .= "</table><br><br>
<form action='".$_SERVER['PHP_SELF']."' method='get'>
<input type='hidden' name='do' value='show'>
Найти гостя: <input type='text' name='searchname'>
<input type='submit' value='Найти'>
</form>";
echo $str;
}
else
{
echo "<form action='".$_SERVER['PHP_SELF']."?do=add' method='post'>
<b>Ваше имя:</b> <input type='text' name='name' maxlength='255'>
<input type='submit' value='Войти'><br>
(макс. 255 сим.)</form>";
}
?>
|
http://www.softtime.ru/info/task.php?id_article=110 | |
|
|
|
|
|
|
|
для: SoftTime
(23.05.2007 в 22:58)
| | 1) 134 строк в двух файлах, средняя читабельность, комментарии отсуствуют.
2) Не правильно обрабатывается ввод пользователя при помощи функции mysql_escape_string(). Если включён режим магических кавычек, то войти под пользователем "I don't know" уже не получится - будет создано новый пользователь "I don\'t know". Конструкцию
<?php
$name = mysql_escape_string($name);
?>
|
следует заменить на
<?php
if (!get_magic_quotes_gpc())
{
$name = mysql_escape_string($name);
}
?>
|
А собственно одна из главных особенностей этого задания - корректная вставка текста в СУБД.
3) Лучше не использовать два запроса
<?php
$result = mysql_query("SELECT * FROM guests WHERE guestname = '".$name."'");
$row = mysql_fetch_assoc($result);
if ($row)
{
mysql_query("UPDATE guests SET visits = '".($row['visits'] + 1)."' WHERE guestname = '".$name."'");
?>
|
Тут можно обойтись одним
<?php
"UPDATE guests SET visits = visits + 1 WHERE guestname = '$name'"
?>
|
4) Нет обработки ошибок SQL-запросов, запросы являются динамическими и ошибки могут возникать.
5) Нет привязки к названию файла - хорошо.
6) Перед удалением пользователя спрашивает подтверждение - хорошо. | |
|
|
|
|
|
|
|
для: cheops
(01.06.2007 в 12:06)
| | 1) Все никак не искореню в себе лень, чтобы писать комментарии. А ведь надо! Иногда сам путаюсь в своих же скриптах. :)
2) Вот про магические ковычки я забыл. Просто стараюсь с ними не связываться, поэтому и не учитываю обычно. Исправлюсь.
3) А вот здесь, суть первого запроса в том, чтобы проверить присутствует ли введенное имя в базе. И далее, если да - обновить счетчик, нет - внести в базу. Разве это можно сделать одним запросом?
Собственно, писал скрипт на скорую руку, еще до продления срока. А переделать, времени так и не нашел. Знаю - не оправдание, но все же :) | |
|
|
|
|
|
|
|
для: SoftTime
(23.05.2007 в 22:58)
| | Я так и не понял, схитрил автор или не понял пункта задания про удаление посетителя.
Алерт-сообщение обращается к тому, кто последний раз ввел имя, а не к тому, чью строку пытаются удалить. Проверить правильность передачи параметров в JS-код невозможно. Точнее, для этого придется строить дополнительный скрипт. Если автору интересно, я построю.
На символе процента поиск срезается. (это не зависит от магических кавычек и экранирования)
Удалить посетителя & мне не удалось.
Немного скриншотов процесса проверки см. в аттаче | |
|
|
|
|
|
|
|
для: Trianon
(01.06.2007 в 18:02)
| | То ли я плохо тестировал, то ли не я :)
Сейчас проверил еще раз. На Localhost'е.
>Я так и не понял, схитрил автор или не понял пункта задания про удаление посетителя.
>Алерт-сообщение обращается к тому, кто последний раз ввел имя, а не к тому, чью строку пытаются удалить. Проверить правильность передачи параметров в JS-код невозможно. Точнее, для этого придется строить дополнительный скрипт. Если автору интересно, я построю.
Алерт-сообщение обращается именно к тому, кто последний раз ввел имя.
>На символе процента поиск срезается. (это не зависит от магических кавычек и экранирования)
Что значит "поиск срезается"? Использовал для проверки имя dr@g%. При поиске выводит запись с этим именем.
>Удалить посетителя & мне не удалось.
Опять таки, у меня все прекрасно удаляется.
>Немного скриншотов процесса проверки см. в аттаче
Вот аттача, не нашел. :( | |
|
|
|
|
|
|
|
для: Drago
(01.06.2007 в 18:25)
| | >То ли я плохо тестировал, то ли не я :)
>Сейчас проверил еще раз. На Localhost'е.
>>Я так и не понял, схитрил автор или не понял пункта задания про удаление посетителя.
>>Алерт-сообщение обращается к тому, кто последний раз ввел имя, а не к тому, чью строку пытаются удалить. Проверить правильность передачи параметров в JS-код невозможно. Точнее, для этого придется строить дополнительный скрипт. Если автору интересно, я построю.
>
>Алерт-сообщение обращается именно к тому, кто последний раз ввел имя.
А по условию обращение должно следовать к имени в таблице:
в) По ссылке удаления должно всплывать alert-окно подтверждения с вопросом
Name! Вы действительно хотите вычеркнуть себя?
где Name - поле из столбика таблицы: | 2 | Name2 | 1 | del | >
>>На символе процента поиск срезается. (это не зависит от магических кавычек и экранирования)
>
>Что значит "поиск срезается"? Использовал для проверки имя dr@g%. При поиске выводит запись с этим именем.
>
Это значит, что поиск одного из тестовых имен, внесенных в таблицу заранее, результата не дал:
см скриншот.
>>Удалить посетителя & мне не удалось.
>
>Опять таки, у меня все прекрасно удаляется.
У Вас добавляется и удаляется &amp; - а это не одно и то же.
>>Немного скриншотов процесса проверки см. в аттаче
>Вот аттача, не нашел. :(
Не берут у меня архивы.
Глядите здесь. | |
|
|
|
|
|
|
|
для: Trianon
(01.06.2007 в 20:51)
| | А по условию обращение должно следовать к имени в таблице:
в) По ссылке удаления должно всплывать alert-окно подтверждения с вопросом
Name! Вы действительно хотите вычеркнуть себя?
где Name - поле из столбика таблицы: | 2 | Name2 | 1 | del | >
В условии задачи не было сказано:
где Name - поле из столбика таблицы: | 2 | Name2 | 1 | del |
|
А сказано было:
в) По ссылке удаления должно всплывать alert-окно подтверждения с вопросом
Name! Вы действительно хотите вычеркнуть себя?
при утвердительном ответе строка уходит из таблицы.
|
Да, я согласен, слово "себя", должно наводить на мысль о том, что обращение должно идти и тому имени, которое удаляем. Но фраза в теме обсуждения:
удалять можно кому угодно кого угодно.
|
сбила меня с толку.
>У Вас добавляется и удаляется &amp; - а это не одно и то же.
&amp; только выводится на странице, так как используется функция htmlspecialchars(). В базу же, добавляется просто &, без преобразований.
С остальным согласен. | |
|
|
|
|
|
|
|
для: Drago
(01.06.2007 в 22:07)
| | >В условии задачи не было сказано:
Я с удовольствием выслушаю Вашу формулировку равнозначного смысла.
>Но фраза в теме обсуждения:
>удалять можно кому угодно кого угодно.
>сбила меня с толку.
Она родилась позже. Когда меня стали спрашивать
А что будет если один посетитель захочет удалить другого?
Я дал понять, что процесс авторизации мне в этой задаче неинтересен.
>У Вас добавляется и удаляется &amp; - а это не одно и то же.
&amp; только выводится на странице, так как используется функция htmlspecialchars(). В базу же, добавляется просто &, без преобразований.
Возможно... но последний скриншот возник неспроста.
Попытка удалить имя & успеха не имела, даже когда я "зашел с него".
Так что этот пункт я не засчитал. | |
|
|
|