Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Ответ 001 на задачу N 21
 
 автор: SoftTime   (23.05.2007 в 22:58)   письмо автору
 
 

Ответ 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($ver0);
  list(
$major$minor) = explode("."$version);
  
// Если версия выше 4.1 сообщаем серверу, что будем работать с
  // кодировкой cp1251
  
if($major >= && $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($nameENT_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($nameENT_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

   
 
 автор: cheops   (01.06.2007 в 12:06)   письмо автору
 
   для: 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) Перед удалением пользователя спрашивает подтверждение - хорошо.

   
 
 автор: Drago   (01.06.2007 в 18:17)   письмо автору
 
   для: cheops   (01.06.2007 в 12:06)
 

1) Все никак не искореню в себе лень, чтобы писать комментарии. А ведь надо! Иногда сам путаюсь в своих же скриптах. :)

2) Вот про магические ковычки я забыл. Просто стараюсь с ними не связываться, поэтому и не учитываю обычно. Исправлюсь.

3) А вот здесь, суть первого запроса в том, чтобы проверить присутствует ли введенное имя в базе. И далее, если да - обновить счетчик, нет - внести в базу. Разве это можно сделать одним запросом?

Собственно, писал скрипт на скорую руку, еще до продления срока. А переделать, времени так и не нашел. Знаю - не оправдание, но все же :)

   
 
 автор: Trianon   (01.06.2007 в 18:02)   письмо автору
 
   для: SoftTime   (23.05.2007 в 22:58)
 

Я так и не понял, схитрил автор или не понял пункта задания про удаление посетителя.
Алерт-сообщение обращается к тому, кто последний раз ввел имя, а не к тому, чью строку пытаются удалить. Проверить правильность передачи параметров в JS-код невозможно. Точнее, для этого придется строить дополнительный скрипт. Если автору интересно, я построю.

На символе процента поиск срезается. (это не зависит от магических кавычек и экранирования)

Удалить посетителя &amp; мне не удалось.

Немного скриншотов процесса проверки см. в аттаче

   
 
 автор: Drago   (01.06.2007 в 18:25)   письмо автору
 
   для: Trianon   (01.06.2007 в 18:02)
 

То ли я плохо тестировал, то ли не я :)

Сейчас проверил еще раз. На Localhost'е.

>Я так и не понял, схитрил автор или не понял пункта задания про удаление посетителя.
>Алерт-сообщение обращается к тому, кто последний раз ввел имя, а не к тому, чью строку пытаются удалить. Проверить правильность передачи параметров в JS-код невозможно. Точнее, для этого придется строить дополнительный скрипт. Если автору интересно, я построю.

Алерт-сообщение обращается именно к тому, кто последний раз ввел имя.

>На символе процента поиск срезается. (это не зависит от магических кавычек и экранирования)

Что значит "поиск срезается"? Использовал для проверки имя dr@g%. При поиске выводит запись с этим именем.

>Удалить посетителя &amp; мне не удалось.

Опять таки, у меня все прекрасно удаляется.

>Немного скриншотов процесса проверки см. в аттаче

Вот аттача, не нашел. :(

   
 
 автор: Trianon   (01.06.2007 в 20:51)   письмо автору
 
   для: Drago   (01.06.2007 в 18:25)
 

>То ли я плохо тестировал, то ли не я :)
>Сейчас проверил еще раз. На Localhost'е.


>>Я так и не понял, схитрил автор или не понял пункта задания про удаление посетителя.
>>Алерт-сообщение обращается к тому, кто последний раз ввел имя, а не к тому, чью строку пытаются удалить. Проверить правильность передачи параметров в JS-код невозможно. Точнее, для этого придется строить дополнительный скрипт. Если автору интересно, я построю.
>
>Алерт-сообщение обращается именно к тому, кто последний раз ввел имя.
А по условию обращение должно следовать к имени в таблице:
в) По ссылке удаления должно всплывать alert-окно подтверждения с вопросом
Name! Вы действительно хотите вычеркнуть себя?

где Name - поле из столбика таблицы: | 2 | Name2 | 1 | del | >
>>На символе процента поиск срезается. (это не зависит от магических кавычек и экранирования)
>
>Что значит "поиск срезается"? Использовал для проверки имя dr@g%. При поиске выводит запись с этим именем.
>
Это значит, что поиск одного из тестовых имен, внесенных в таблицу заранее, результата не дал:
total %25 of sales

см скриншот.

>>Удалить посетителя &amp; мне не удалось.
>
>Опять таки, у меня все прекрасно удаляется.
У Вас добавляется и удаляется &amp;amp; - а это не одно и то же.


>>Немного скриншотов процесса проверки см. в аттаче
>Вот аттача, не нашел. :(
Не берут у меня архивы.
Глядите здесь.

   
 
 автор: Drago   (01.06.2007 в 22:07)   письмо автору
 
   для: Trianon   (01.06.2007 в 20:51)
 

А по условию обращение должно следовать к имени в таблице:
в) По ссылке удаления должно всплывать alert-окно подтверждения с вопросом
Name! Вы действительно хотите вычеркнуть себя?
где Name - поле из столбика таблицы: | 2 | Name2 | 1 | del | >


В условии задачи не было сказано:

где Name - поле из столбика таблицы: | 2 | Name2 | 1 | del | 


А сказано было:

в) По ссылке удаления должно всплывать alert-окно подтверждения с вопросом

Name! Вы действительно хотите вычеркнуть себя?

при утвердительном ответе строка уходит из таблицы.


Да, я согласен, слово "себя", должно наводить на мысль о том, что обращение должно идти и тому имени, которое удаляем. Но фраза в теме обсуждения:

удалять можно кому угодно кого угодно.

сбила меня с толку.

>У Вас добавляется и удаляется &amp;amp; - а это не одно и то же.
&amp;amp; только выводится на странице, так как используется функция htmlspecialchars(). В базу же, добавляется просто &amp;, без преобразований.

С остальным согласен.

   
 
 автор: Trianon   (02.06.2007 в 00:22)   письмо автору
 
   для: Drago   (01.06.2007 в 22:07)
 

>В условии задачи не было сказано:
Я с удовольствием выслушаю Вашу формулировку равнозначного смысла.

>Но фраза в теме обсуждения:
>удалять можно кому угодно кого угодно.
>сбила меня с толку.

Она родилась позже. Когда меня стали спрашивать
А что будет если один посетитель захочет удалить другого?
Я дал понять, что процесс авторизации мне в этой задаче неинтересен.

>У Вас добавляется и удаляется &amp;amp; - а это не одно и то же.
&amp;amp; только выводится на странице, так как используется функция htmlspecialchars(). В базу же, добавляется просто &amp;, без преобразований.

Возможно... но последний скриншот возник неспроста.
Попытка удалить имя &amp; успеха не имела, даже когда я "зашел с него".
Так что этот пункт я не засчитал.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования