[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Решение задачи Twin'а на корректную обработку данн
kovaldm
Условия задачи [URL=http://phpforum.ru/index.php?act=ST&f=125&t=19168&st=0#entry134769'>здесь</a>.

Результат здесь.

Приветствую всех форумчан. Вот мое решение. Чужие коды не смотрел - так не интересно.

index.php


<?[SPAN=darling]php[/SPAN]
//Устанавливаем кодировку и уровень ошибок
header("Content-Type: text/html; charset=utf-8");
error_reporting(E_ALL);

//Отправляем вывод в буфер
ob_start();

//Определяем константу "key" для доступа к остальным файлам
define("Key",1);

//Подключаем конфигурационный файл
include "config.php";

//Устанавливаем соединение с БД

$connect=mysql_connect(HostName, UserName, Password);

if(!$connect)
{

ob_end_clean();

echo 'Не удалось установить установить соединение с MySQL<br>'.mysql_error();

exit;

}

$select=mysql_select_db("names");

if(!$select)
{

ob_end_clean();

echo 'Не удалось установить соединение с БД'.mysql_error();

exit;

}

//Если нажата кнопка добавить запись - добавляем:
if(isset($_POST['add_button']))
{

//Проверяем наличие записи в форме

if(trim($_POST['add'])=='')
{

echo'<font color=\'red\'>Пустое имя недопустимо</font><br>';

}
else
{

//Проверяем включены-ли "магические кавычки"
if(!get_magic_quotes_gpc())
{

$_POST['add']=addslashes($_POST['add']);

}

//Обрабатываем спецсиволы
$_POST['add']=htmlentities($_POST['add']);

//Записываем данные в БД
mysql_query('INSERT INTO `names` (`id` ,`date` ,`name` )VALUES (NULL , CURRENT_TIMESTAMP , \''.trim($_POST['add']).'\')');

//Перенаправление к списку зарегистрированных "пользователей"(защита от F5)
HEADER('location: index.php');
}
}


//Поиск-ищем
if(isset($_GET['find_button']))
{

//Проверяем строку поиска
if(!empty($_GET['find']))
{

//Проверяем включены-ли "магические кавычки"
if(get_magic_quotes_gpc())
{

$_GET['find']=stripslashes($_GET['find']);

}

//Эта переменная для возврата текста в форму поиска
$findtext=$_GET['find'];

//Извлекаем все записи из БД
$result=mysql_query('SELECT name FROM names');

//Если есть совпадения - добавляем имя в массив
while($findrow=mysql_fetch_assoc($result))
{

if(stristr(html_entity_decode($findrow['name']), $_GET['find']))
{

$findlist[]=$findrow['name'];

}
else
{

continue;

}
}


//Если что-то нашлось
if(isset($findlist))
{

echo'По запросу "'.htmlentities($_GET['find']).'" найдено записей: '.count($findlist).'<br>';

//Выводим найденные записи
foreach($findlist as $v)
{

echo'•'.$v.'<br>';

}

echo'<hr>';
}
else
{

echo'Ничего не нашлося.<br>';

}
}

else
{

echo'Что ищем?<br>';

}

}


//Вывод общего списка

$result=mysql_query('SELECT * FROM `names`');

//Вывод даты регистрации пользователя по ссылке

if(isset($_GET['link']))
{

$user=mysql_fetch_assoc($result);

echo '<h3>Пользователь "'.$user['name'].'" зарегистрирован '.$user['date'].'</h3><br>';

}

//Выводим список всех пользователей

while($row=mysql_fetch_assoc($result))
{

$list[$row['id']]=$row['name'];

}

//Сортируем полученный массив по дате регистрации
krsort($list);

//Выводим список пользователей
foreach($list as $k=>$v)
{

echo '•<a href=\'index.php?link='.$k.'\'>'.$v.'</a><br>';

}

//Закрываем соединение с БД
mysql_close();

//Извлекаем содержимое буфера
$content=ob_get_contents();
ob_end_clean();

//Переменная для возврата текста в форму поиска
if(empty($findtext)) $findtext='';

//Подключаем файл с формой
include 'form.html';

?>




config.php


<?[SPAN=darling]php[/SPAN]
//Устанавливаем кодировку и уровень ошибок
header("Content-Type: text/html; charset=utf-8");
error_reporting(E_ALL);

//Проверяем наличие индексного файла

defined("Key")?:header("location: 404.html");

//Устанавливаем константы для работы с БД

define("HostName","localhost");
define("UserName","root");
define("Password","");


?>




form.html


<html>
<head>
<title></title>
</head>
<body>
<form
action method='POST'>
<input
type='text' name='add'>
<input
type='submit' name='add_button' value='Добавить запись'>
</form>
<form
action method='GET'>
<input
type='text' name='find' value="<?[SPAN=darling]php[/SPAN] echo $findtext; ?>">
<input
type='submit' name='find_button' value='Искать'>
</form>
<?
[SPAN=darling]php[/SPAN]

echo $content;

?>
</body>
</html>





404.html


<html>
<head>
<title>
404</title>
</head>
<body>
<h2>
404</h2>
На нашем зайте запрашиваемой страницы нет.
</body>
</html>





.htaccess


AddDefaultCharset UTF-8
php_flag magic_quotes_gpc On





Спустя 15 минут, 10 секунд (3.10.2010 - 00:58) Админ написал(а):
довольно грамотно не тестил - но визуально очень гут

Спустя 6 часов, 26 минут, 13 секунд (3.10.2010 - 07:24) ApuktaChehov написал(а):
Привет.
Вывод ошибок при подключениях к БД можно было сделать проще:
$connect = mysql_connect(HostName, UserName, Password) or die ('Не удалось установить установить соединение с MySQL<br>'.mysql_error());

В этом случае не требуется exit и лишние условия.
Так же с выбором БД

if(trim($_POST['add'])=='')

Что значит "пустое или недопустимое"? Я вижу только не лучшую проверку на пустоту. Почему не сделать так: empty( $_POST['add'] );? Вроде бы empty пробелы тоже не пропускает. А если пропускает то, можно еще добавить trim. Что так же будет лучше.

Теперь странная обработка волшебных кавычек. Не стоит полагаться на эти кавычки, все нужно делать самому:
 if(get_magic_quotes_gpc())
{
//Если "волшебные кавычки" включены,
//Мы вырезаем результат их "работы".

$_POST['add'] = stripslashes($_POST['add']);

}

//А тут мы снова экранируем.
$_POST['add'] = mysql_real_escape_string($_POST['add']);


Так будет лучше. А то у вас, теоретически, возможна инъекция.

Я вот только не понял, зачем для поиска извлекать все записи, когда можно произвести этот поиск средствами SQL?
$result = mysql_query("SELECT `name` FROM `names` WHERE name LIKE '%". $_GET['find'] ."%'");

$_GET['find'] - обязательно нужно экранировать.
В итоге возвращается результат поиска. А все что после вашего запроса не нужно вообще.

Честно говоря не понял что за "вывод даты регистрации пользователя по ссылке". В поток выдается только первая запись, которую вернул запрос выше. Но вот только зачем тогда $_GET['link'], не знаю.

Вывод списка пользователей, тоже непонятно сделан. Все это можно реализовать в одном цикле и без создания каких-либо дополнительных массивов.

А после этого:
//Проверяем наличие индексного файла

defined("Key")?:header("location: 404.html");

Не плохо было бы поставить exit(); Если уже ключ не был установлен, то делает переадресацию, и останавливаем все что дальше.

Еще неясно, зачем принудительно включать волшебные кавычки?
php_flag magic_quotes_gpc On


Ну, вот собственно все.
Работа не плохая. Мысли мыслят в нужную сторону - это хорошо.
Нужно поднатаскаться в теории и все будет отличненько.

P.S. Совет: уже с "раннего детства" пытайтесь отделять php и HTML кода.
И еще было бы очень хорошо, если бы все сообщения для юзера, вынеслись в массив, который можно положить в конфиге. Там будет крайне удобно wink.gif

Спустя 1 час, 58 минут, 37 секунд (3.10.2010 - 09:23) twin написал(а):
Привет. Тут уже посмотрели... Я добавлю немного.

Сначала по стилю. Просто с некоторых пор я не могу читать код, пока не приведу в порядок.

1.
    define("Key",1); 

тут сразу три недочета. Вопервых, константы желательно писать в верхнем регистре, иначе они в коде смтрятся как недописанные переменные. Это сбивает. Штатные (предопределенные) константы принято писать именно так: __FILE__, а не так __File__. Хотя работать конечно будет.
Дальше - кавычки. В таких местах, где не нужно использовать подстановки, лучше пользоваться апострофами. С ними код получается чище. Ну и пробелом нужно отделять операторы
    define('KEY', 1); 


2. Вот и смотри, как похоже на переменные...
//Устанавливаем соединение с БД

$connect=mysql_connect(HostName, UserName, Password);

Причем HostName в одном (верблюжьем) стиле, а Password иначе.
Вообще мой совет, делай константам префиксы. Это красивее, а главное убережет от конфликтов имен, если скрипт будет интегрирован в другую среду:
//Устанавливаем соединение с БД

$connect = mysql_connect(KVD_MYSQL_HOST, KVD_MYSQL_USER, KVD_MYSQL_PASSWORD);

Никаких конфликтов, никакой неоднозначности, предельно ясно содержание константы.

3. Слишком много пустых строк. Приходится скролить лишнего и соответственно меньше кода входит на экран. И про сдвиги не забывай.
//Если нажата кнопка добавить запись - добавляем:
if(isset($_POST['add_button']))
{

//Проверяем наличие записи в форме

if(trim($_POST['add']) == '')
{

echo '<font color=\'red\'>Пустое имя недопустимо</font><br>';

}
else
{


В таких местах не то что пустые строки, скобки ставить и то излишество:
//Если нажата кнопка добавить запись - добавляем:
if(isset($_POST['add_button']))
{
//Проверяем наличие записи в форме
if(trim($_POST['add']) == '')
echo '<font color="red">Пустое имя недопустимо</font><br>';
}
else
{

Обрати внимание на кавычки. У тебя зачем то экранированные апострофы, это невалидно.

4.
        HEADER('location: index.php');
зачем тут функция в верхнем регистре...

5. Конкатенацию тоже желательно выделять пробелами.
    //Если что-то нашлось
if(isset($findlist))
{

echo'По запросу "'.htmlentities($_GET['find']).'" найдено записей: '.count($findlist).'<br>';

//Выводим найденные записи
foreach($findlist as $v)
{

echo'•'.$v.'<br>';


Я делаю это со значимой строны. И экономно и читабельно.
    //Если что-то нашлось
if(isset($findlist))
{
echo 'По запросу "'. htmlentities($_GET['find']) .'" найдено записей: '. count($findlist) .'<br>';

foreach($findlist as $v)
echo '•'. $v .'<br>';


6. Ну и табуляторы. Не пользуйся табуляторами, смотри какая каша получилась из-за них:
        if(isset($findlist))
{

echo'По запросу "'.htmlentities($_GET['find']).'" найдено записей: '.count($findlist).'<br>';

//Выводим найденные записи
foreach($findlist as $v)
{

echo'•'.$v.'<br>';

}

echo'<hr>';
}
else
{

echo'Ничего не нашлося.<br>';

}
}

else
{

echo'Что ищем?<br>';

}

Где чья скобка... Черт ногу сломит.

По функционалу ApuktaChehov написал уже, правда не все.
Я попозже допишу. Можешь пока исправить в рамках этих замечаний.



Спустя 11 часов, 51 минута, 17 секунд (3.10.2010 - 21:14) kovaldm написал(а):
Уже работаю над ошибками.

Спустя 3 часа, 55 минут, 22 секунды (4.10.2010 - 01:10) inpost написал(а):
"Причем HostName в одном (верблюжьем) стиле, а Password иначе" - потому что host name - 2 слова, а password - одно целое слово =)

Спустя 7 часов, 16 минут, 34 секунды (4.10.2010 - 08:26) twin написал(а):
Цитата
host name - 2 слова, а password - одно целое слово =)

Да что Вы... biggrin.gif PassWord
Pass - англ. "пропуск",
Word - англ "слово".


Спустя 12 часов, 8 минут, 21 секунда (4.10.2010 - 20:35) kovaldm написал(а):
Можно подсказку?
Вот с таким запросом
Цитата

$result = mysql_query("SELECT `name` FROM `names` WHERE name LIKE '%". $_GET['find'] ."%'");


Поиск выполняется не совсем корректно, так как данные записаны в таблицу без слэшей, а поиск выполняется с ними, поэтому приходится фильтровать результат поиска, а это почти тоже самое что у меня было изначально.
Данные записываю в БД не обработав спецсимволы HTML, они обрабатываются при выводе(иначе поиск находит много лишнего).
Возможно ли вообще осуществить корректный поиск средствами MySQL?, а то я уже второй вечер голову ломаю и ничего не получается, а может я чего-то не понимаю?

Спустя 23 минуты, 58 секунд (4.10.2010 - 20:59) ApuktaChehov написал(а):
Правильно, данные в бд хранятся без слешей и поиск так же проводиться без слешей. А если у вас в запрос попадают слеши, это значит что вы некорректно обрабатываете данные. Показывайте ваш последний код.

Спустя 15 минут, 38 секунд (4.10.2010 - 21:14) kovaldm написал(а):


//Проверяем строку поиска
if(!empty($_GET['find']))
{

//Проверяем включены-ли "магические кавычки"
if(get_magic_quotes_gpc())
{

$_GET['find']=stripslashes($_GET['find']);

}

//Переменная для возврата текста в форму поиска
$findtext=$_GET['find'];

//Ищем в БД записи удовлетворяющие условию поиска (здесь наверно подвох)
$result=mysql_query("SELECT `name` FROM `names` WHERE name LIKE '%". mysql_real_escape_string($_GET['find']) ."%'");

//Если что-то нашлось
if(mysql_num_rows($result))
{

echo 'По запросу: '. $_GET['find'] .' найдено записей: '. mysql_num_rows($result) .'<br>';

while($findrow=mysql_fetch_assoc($result))
{

echo'• '. htmlentities($findrow['name']) .'<br>';

}

echo '<hr>';

}else
{

echo'Ничего не найдено<br>';

}
}




Подозреваю, что подвох в mysql_real_escape_string(). Если ей обрабатывать искомый текст два раза, то все работает, но насколько это правильно?


"SELECT `name` FROM `names` WHERE name LIKE '%". mysql_real_escape_string(mysql_real_escape_string($_GET['find'])) ."%'"


Спустя 12 минут, 6 секунд (4.10.2010 - 21:26) twin написал(а):
Никто не запрещает рыться в решениях. Задачу решили почти все, кто пытался.
Это же не конкурс, тут главное разобраться. И лучше самостоятельно - крепче запомнится.

Спустя 2 часа, 29 минут, 22 секунды (4.10.2010 - 23:56) kovaldm написал(а):
Листинг номер 2.

index.php


<?php
//Устанавливаем кодировку и уровень ошибок
header("Content-Type: text/html; charset=utf-8");
error_reporting(E_ALL);

//Отправляем вывод в буфер
ob_start();

//Определяем константу "KVD_KEY" для доступа к остальным файлам
define("KVD_KEY",1);

//Подключаем конфигурационный файл
include "config.php";

//Устанавливаем соединение с БД

$connect=mysql_connect(KVD_MYSQL_HOST, KVD_MYSQL_USER_NAME, KVD_MYSQL_PASSWORD) or die('Не удалось установить установить соединение с MySQL<br>'.mysql_error());

$select=mysql_select_db("names") or die('Не удалось установить соединение с БД'.mysql_error());

//Если нажата кнопка добавить запись - добавляем:
if(isset($_POST['add_button']))
{
//Удаляем концевые пробелы
$_POST['add']=trim($_POST['add']);

//Проверяем наличие записи в форме
if(empty($_POST['add']))
{
echo'<font color="red">Пустое имя недопустимо</font><br>';
}
else
{
//Проверяем включены-ли "магические кавычки"
if(get_magic_quotes_gpc())
{
$_POST['add']=stripslashes($_POST['add']);
}
//Экранируем
$_POST['add']=mysql_real_escape_string($_POST['add']);

//Записываем данные в БД
mysql_query("INSERT INTO `names` (`id` ,`date` ,`name` )VALUES (NULL , CURRENT_TIMESTAMP , '". $_POST['add'] ."')");

//Перенаправление к списку зарегистрированных "пользователей"(защита от F5)
header('location: index.php');
exit();
}
}


//Поиск-ищем
if(isset($_GET['find_button']))
{
//Проверяем строку поиска
if(!empty($_GET['find']))
{
//Проверяем включены-ли "магические кавычки"
if(get_magic_quotes_gpc())
{
$_GET['find']=stripslashes($_GET['find']);
}

//Переменная для возврата текста в форму поиска
$findtext=$_GET['find'];

//Ищем в БД записи удовлетворяющие условию поиска

$_GET['find']=str_replace('\\', '\\\\', $_GET['find']);

$_GET['find']=str_replace('%', '\%', $_GET['find']);

$_GET['find']=str_replace('_', '\_', $_GET['find']);

$result=mysql_query("SELECT `name` FROM `names` WHERE name LIKE '%". mysql_real_escape_string($_GET['find']) ."%'");

//Если что-то нашлось
if(mysql_num_rows($result))
{
echo 'По запросу: '. $findtext .' найдено записей: '. mysql_num_rows($result) .'<br>';

while($findrow=mysql_fetch_assoc($result))
{
echo'• '. htmlentities($findrow['name']) .'<br>';
}

echo '<hr>';

}else
{
echo'Ничего не найдено<br>';
}
}

else
{
echo'Что ищем?<br>';
}
}


//Вывод общего списка

//Вывод даты регистрации пользователя по ссылке


if(isset($_GET['link']))
{
$result=mysql_query("SELECT * FROM `names` WHERE `id`=".$_GET['link']);

while($user=mysql_fetch_assoc($result))
{
if($_GET['link']==$user['id'])
{
echo '<h3>Пользователь "'.htmlentities($user['name']).'" зарегистрирован '.$user['date'].'</h3><br>';
break;
}
}
}


//Выводим список всех пользователей
$result=mysql_query('SELECT * FROM `names` ORDER BY `date`');

$string='';

while($row=mysql_fetch_assoc($result))
{
$string='•<a href=\'index.php?link='. $row['id'] .'\'>'. htmlentities($row['name']) .'</a><br>'.$string;
}
echo $string;

//Закрываем соединение с БД
mysql_close();

//Извлекаем содержимое буфера
$content=ob_get_contents();
ob_end_clean();

//Переменная для возврата текста в форму поиска
if(empty($findtext)) $findtext='';

//Подключаем файл с формой
include 'form.html';

?>



config.php


<?php
//Устанавливаем кодировку и уровень ошибок
header("Content-Type: text/html; charset=utf-8");
error_reporting(E_ALL);

//Проверяем наличие индексного файла

defined("KVD_KEY")?:header("location: 404.html") && exit();

//Устанавливаем константы для работы с БД

define("KVD_MYSQL_HOST","localhost");
define("KVD_MYSQL_USER_NAME","root");
define("KVD_MYSQL_PASSWORD","");

?>



form.html


<html>
<head>
<title></title>
</head>
<body>
<form
action method='POST'>
<input
type='text' name='add'>
<input
type='submit' name='add_button' value='Добавить запись'>
</form>
<form
action method='GET'>
<input
type='text' name='find' value="<?php echo $findtext; ?>">
<input
type='submit' name='find_button' value='Искать'>
</form>
<?php


echo $content;
//echo'<br><br><br> '.mysql_real_escape_string(htmlspecialchars('%'));

?>
</body>
</html>




.htaccess


AddDefaultCharset UTF-8
php_flag magic_quotes_gpc Off



По поводу "%" и "_" - сам нашел недостаток, сам его устранил! Пришлось изрядно покопаться в руководстве по МуСКУЛу.

Спустя 8 часов, 13 минут, 10 секунд (5.10.2010 - 08:09) twin написал(а):
Молодец. Гораааааздо лучше стало. smile.gif
По стилю еще пару замечаний (вернее советов)
1. Все же стоит отделять операторы пробелами. Это один из первейших признаков профессионального стиля
Не так
$_POST['add']=trim($_POST['add']);
а так
$_POST['add'] = trim($_POST['add']);

2. Если уж взялся писать кавычки - пиши их. Или используй апострофы везде. А так получается разброд и шатания. Тут одно:
define("KVD_KEY",1);
тут другое
if(isset($_POST['add_button']))

3. Не используй длинных строк. Есть же символ переноса)))
Вот даже на широком экране горизонтальный скрол. sad.gif
$connect=mysql_connect(KVD_MYSQL_HOST, KVD_MYSQL_USER_NAME, KVD_MYSQL_PASSWORD) or die('Не удалось установить установить соединение с MySQL<br>'.mysql_error());
Куда как приятнее, когда все перед глазами:
    $connect = mysql_connect(KVD_MYSQL_HOST, KVD_MYSQL_USER_NAME, KVD_MYSQL_PASSWORD) 
or die('Не удалось установить установить соединение с MySQL<br>'. mysql_error());

4. В тегах валиднее использовать кавычки. Да и чище это:
    $string = '•<a href="index.php?link='. $row['id'] .'">'

5. Не ставь этот значек в конце файла ?>, это дырка в безопасности.


Ну а теперь по функционалу.
От этой строчки я впал в ступор:
    defined("KVD_KEY")?:header("location: 404.html") && exit();

Я думал короткая форма тернарников будет только в 6-й версии, оказалось уже в 5.3 Соответственно на моей 5.2 работать не хочет sad.gif
А вот испльзование логического оператора && в этом месте - полная новость для меня. Ошибка это или я отстал от жизни - выяснить не удалось, нет 5.3

Но в любом случае ошибка в этой строке есть. Функция header() в location требует полного пути, вместе с протоколом.

Теперь чуть выше:
//Устанавливаем кодировку и уровень ошибок
header("Content-Type: text/html; charset=utf-8");
error_reporting(E_ALL);
Это есть уже в индексе, не нужно дублировать.

Ну и сам индекс.
Задача решена не полностью.
1. С магическими кавычками недотянуто. Поставь в .htaccess
php_flag magic_quotes_gpc On
и зарегистрируй имя O'Relly
2. XSS цветет махровым цветом. Попробуй в поле поиска сунуть это:
Цитата
"><iframe src="http://sex.ru" />


3. Грубая ошибка - не установлена кодировка соединения с БД. Кракозяблы не дремлют.

Остальное вроде в пределах нормы. Если не считать мелочей.
Вот тут хромает логика:
    if(isset($_POST['add_button']))
{
//Удаляем концевые пробелы
$_POST['add']=trim($_POST['add']);
так как есть вероятность обратиться к несуществующему элементу массива. Тогда уж так нужно было:
//Если нажата кнопка добавить запись - добавляем:
if(isset($_POST['add_button']))
{
//Проверяем наличие записи в форме
if(empty($_POST['add']))
{
echo'<font color="red">Пустое имя недопустимо</font><br>';
}
else
{
//Удаляем концевые пробелы
$_POST['add'] = trim($_POST['add']);



Если используешь разделение логики с представлением, то уж дели полностью. А так получается вывод выше тела HTML.

А в целом очень даже ничего. Еще немного и будет похоже на эталон. smile.gif

Спустя 2 часа, 23 минуты, 27 секунд (5.10.2010 - 10:32) arvitaly написал(а):
Цитата
Функция header() в location требует полного пути, вместе с протоколом.



С чего бы это?

Спустя 1 час, 7 минут, 15 секунд (5.10.2010 - 11:40) twin написал(а):
Цитата
С чего бы это?

С RFC, батенька, с RFC.

Спустя 11 часов, 34 минуты, 59 секунд (5.10.2010 - 23:15) kovaldm написал(а):
Файлы, претерпевшие изменения:

index.php

<?php
//Устанавливаем кодировку и уровень ошибок
header('Content-Type: text/html; charset=utf-8');
error_reporting(E_ALL);

//Отправляем вывод в буфер
ob_start();

//Определяем константу "KVD_KEY" для доступа к остальным файлам
define('KVD_KEY', 1);

//Подключаем конфигурационный файл
include 'config.php';

//Устанавливаем соединение с БД

$connect = mysql_connect(KVD_MYSQL_HOST, KVD_MYSQL_USER_NAME, KVD_MYSQL_PASSWORD)
or die('Не удалось установить установить соединение с MySQL<br>'.mysql_error());

//Кодировка соединения с MySQL
mysql_query('SET NAMES utf8');

echo mysql_error();

$select = mysql_select_db('names') or die('Не удалось установить соединение с БД'.mysql_error());

//Если нажата кнопка добавить запись - добавляем:
if(isset($_POST['add_button']))
{
//Проверяем наличие записи в форме
if(empty($_POST['add']))
{
echo'<font color="red">Пустое имя недопустимо</font><br>';
}
else
{
//Удаляем концевые пробелы
$_POST['add'] = trim($_POST['add']);

//Проверяем включены-ли "магические кавычки"
if(get_magic_quotes_gpc())
{
$_POST['add'] = stripslashes($_POST['add']);
}
//Экранируем
$_POST['add'] = mysql_real_escape_string($_POST['add']);

//Записываем данные в БД
mysql_query('INSERT INTO `names` (`id` ,`date` ,`name` )VALUES (NULL , CURRENT_TIMESTAMP , \''. $_POST['add'] .'\')');

//Перенаправление к списку зарегистрированных "пользователей"(защита от F5)
header('location: index.php');
exit();
}
}


//Поиск-ищем
if(isset($_GET['find_button']))
{
//Проверяем строку поиска
if(!empty($_GET['find']))
{
//Проверяем включены-ли "магические кавычки"
if(get_magic_quotes_gpc())
{
$_GET['find'] = stripslashes($_GET['find']);
}

//Переменная для возврата текста в форму поиска
$findtext = htmlentities($_GET['find']);

//Ищем в БД записи удовлетворяющие условию поиска

$_GET['find'] = str_replace('\\', '\\\\', $_GET['find']);

$_GET['find'] = str_replace('%', '\%', $_GET['find']);

$_GET['find'] = str_replace('_', '\_', $_GET['find']);

$result = mysql_query('SELECT `name` FROM `names` WHERE name LIKE \'%'. mysql_real_escape_string($_GET['find']) .'%\'');

//Если что-то нашлось
if(mysql_num_rows($result))
{
echo 'По запросу: '. $findtext .' найдено записей: '. mysql_num_rows($result) .'<br>';

while($findrow = mysql_fetch_assoc($result))
{
echo'• '. htmlentities($findrow['name']) .'<br>';
}

echo '<hr>';

}else
{
echo'Ничего не найдено<br>';
}
}

else
{
echo'Что ищем?<br>';
}
}


//Вывод общего списка

//Вывод даты регистрации пользователя по ссылке


if(isset($_GET['link']))
{
$result = mysql_query('SELECT * FROM `names` WHERE `id`='.$_GET['link']);

while($user = mysql_fetch_assoc($result))
{
if($_GET['link'] == $user['id'])
{
echo '<h3>Пользователь "'.htmlentities($user['name']).'" зарегистрирован '.$user['date'].'</h3><br>';
break;
}
}
}


//Выводим список всех пользователей
$result = mysql_query('SELECT * FROM `names` ORDER BY `date`');

if(mysql_num_rows($result))
{
$string = '';

while($row = mysql_fetch_assoc($result))
{
$string = '•<a href="index.php?link='. $row['id'] .'">'. htmlentities($row['name']) .'</a><br>'.$string;
}
echo $string;
}
else
{
echo'В базе данных записей нет.';
}

//Закрываем соединение с БД
mysql_close();

//Извлекаем содержимое буфера
$content = ob_get_contents();
ob_end_clean();

//Переменная для возврата текста в форму поиска
if(empty($findtext)) $findtext = '';

//Подключаем файл с формой
include 'form.html';


config.php

<?php

//Проверяем наличие индексного файла

if(!defined('KVD_KEY'))
{
header("HTTP/1.1 404 Not Found");
exit();
}

//Устанавливаем константы для работы с БД

define('KVD_MYSQL_HOST', 'localhost');
define('KVD_MYSQL_USER_NAME', 'root');
define('KVD_MYSQL_PASSWORD','');


1. С магическими кавычками все нормально работает. Где вы здесь увидели недостаток? "Опасных" запросов к БД всего два: добавление записи и поиск, в обоих случаях данные обрабатываются. Все имена из списка для проверки регистрируются и находятся. В любом случае.

2. XSS обработал

3. Кодировку установил, но данные в БД записываются нормально, а вот при выводе показывает супер шифры(наверное секретная информация). Буду над этим работать.

Спустя 41 минута, 55 секунд (5.10.2010 - 23:57) twin написал(а):
Напугал я тебя кавычками)))

Запросы - это исключение из правила. Их как раз и нужно писать в кавычках. Еще те места, где требуются служебные символы (перенос строки допустим).
В апострофах пишутся чистые строки, где ничего больше нет. А запросы в кавычках удобнее - не нужно экранировать апострофы.

С магическими - таки да, я недоглядел. Была включена директива
php_flag magic_quotes_runtime On
(еще одно горе от ума)
У тебя все в порядке.

И еще совет - если пишешь однострочный комментарий, считай его за пустую строку. И пустыми строками выделяй блоки, не каждую переменную. Слишком растянутый по вертикали получается код:
//Поиск-ищем
if(isset($_GET['find_button']))
{ //Проверяем строку поиска
if(!empty($_GET['find']))
{ //Проверяем включены-ли "магические кавычки"
if(get_magic_quotes_gpc())
$_GET['find'] = stripslashes($_GET['find']);
//Переменная для возврата текста в форму поиска
$findtext = htmlentities($_GET['find']);
//Ищем в БД записи удовлетворяющие условию поиска
$_GET['find'] = str_replace('\\', '\\\\', $_GET['find']);
$_GET['find'] = str_replace('%', '\%', $_GET['find']);
$_GET['find'] = str_replace('_', '\_', $_GET['find']);


Ну и практически все в ажуре. Кодировку я думаю допинаешь, осталось немножко))

Спустя 22 часа, 5 минут, 9 секунд (6.10.2010 - 22:02) kovaldm написал(а):
Вобще запутался.

Итак:
Вывод данных из скрипта в utf8.
Таблица в БД в cp1251.
Кириллица в БД записывается корректно, выводится в виде кракозябров. 'SET NAMES utf8' не помогает, принудительный перевод таблицы в utf8 командой 'ALTER TABLE `names` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci' тоже не помогает, с браузером тоже экспериментировал - ситуация остается неизменной.
Подскажите, кто чем может, в каком направлении копать, или литературу о взаимодействии mysql и php. А то поисковики выдают очень однообразные советы, которые не помогают.

Спустя 1 час, 3 минуты, 16 секунд (6.10.2010 - 23:05) kovaldm написал(а):
Все, сам разобрался с кодировкой! Чуть позже выложу окончательный вариант.

Спустя 33 минуты, 13 секунд (6.10.2010 - 23:38) kovaldm написал(а):
Листинг №3.

index.php

<?php
//Устанавливаем кодировку и уровень ошибок
header('Content-type:text/html; charset="utf-8"');
error_reporting(E_ALL);
//Отправляем вывод в буфер
ob_start();
//Определяем константу "KVD_KEY" для доступа к остальным файлам
define('KVD_KEY', 1);
//Подключаем конфигурационный файл
include 'config.php';
//Устанавливаем соединение с БД
$connect = mysql_connect(KVD_MYSQL_HOST, KVD_MYSQL_USER_NAME, KVD_MYSQL_PASSWORD)
or die('Не удалось установить установить соединение с MySQL<br>'. mysql_error());
//Кодировка соединения с MySQL
mysql_query("SET NAMES `utf8`");

$select = mysql_select_db('names') or die('Не удалось установить соединение с БД'. mysql_error());
//Если нажата кнопка добавить запись - добавляем:
if(isset($_POST['add_button']))
{//Проверяем наличие записи в форме
if(empty($_POST['add']))
{
echo'<font color="red">Пустое имя недопустимо</font><br>';
}
else
{//Удаляем концевые пробелы
$_POST['add'] = trim($_POST['add']);
//Проверяем включены-ли "магические кавычки"
if(get_magic_quotes_gpc())
{
$_POST['add'] = stripslashes($_POST['add']);
}
//Экранируем
$_POST['add'] = mysql_real_escape_string($_POST['add']);
//Записываем данные в БД
mysql_query("INSERT INTO `names` (`id` ,`date` ,`name` )VALUES (NULL , CURRENT_TIMESTAMP , '". $_POST['add'] ."')");
//Перенаправление к списку зарегистрированных "пользователей"(защита от F5)
header('location: index.php');
exit();
}
}

//Поиск-ищем
if(isset($_GET['find_button']))
{//Проверяем строку поиска
if(!empty($_GET['find']))
{//Проверяем включены-ли "магические кавычки"
if(get_magic_quotes_gpc())
{
$_GET['find'] = stripslashes($_GET['find']);
}
//Переменная для возврата текста в форму поиска
$findtext = htmlentities($_GET['find'], ENT_COMPAT, 'utf-8');
//Ищем в БД записи удовлетворяющие условию поиска
$_GET['find'] = str_replace('\\', '\\\\', $_GET['find']);
$_GET['find'] = str_replace('%', '\%', $_GET['find']);
$_GET['find'] = str_replace('_', '\_', $_GET['find']);

$result = mysql_query("SELECT `name` FROM `names` WHERE name LIKE '%". mysql_real_escape_string($_GET['find']) ."%'");

//Если что-то нашлось
if(mysql_num_rows($result))
{
echo 'По запросу: '. $findtext .' найдено записей: '. mysql_num_rows($result) .'<br>';
while($findrow = mysql_fetch_assoc($result))
{
echo'• '. htmlentities($findrow['name'], ENT_COMPAT, 'utf-8') .'<br>';
}
echo '<hr>';
}else
{
echo'Ничего не найдено<br>';
}
}

else
{
echo'Что ищем?<br>';
}
}

//Вывод общего списка
//Вывод даты регистрации пользователя по ссылке

if(isset($_GET['link']))
{
$result = mysql_query("SELECT * FROM `names` WHERE `id`=". (int)$_GET['link']);

while($user = mysql_fetch_assoc($result))
{
if($_GET['link'] == $user['id'])
{
echo '<h3>Пользователь "'. htmlentities($user['name'], ENT_COMPAT, 'utf-8') .'" зарегистрирован '. $user['date'] .'</h3><br>';
break;
}
}
}

//Выводим список всех пользователей
$result = mysql_query("SELECT * FROM `names` ORDER BY `date`");

if(mysql_num_rows($result))
{
$string = '';

while($row = mysql_fetch_assoc($result))
{
$string = '•<a href="index.php?link='. $row['id'] .'">'. htmlentities($row['name'], ENT_COMPAT, 'utf-8') .'</a><br>'. $string;
}
echo $string;
}
else
{
echo'В базе данных записей нет.';
}

//Закрываем соединение с БД
mysql_close();
//Извлекаем содержимое буфера
$content = ob_get_contents();
ob_end_clean();
//Переменная для возврата текста в форму поиска
if(empty($findtext)) $findtext = '';
//Подключаем файл с формой
include 'form.html';


config.php

<?php
//Проверяем наличие индексного файла
if(!defined('KVD_KEY'))
{
header("HTTP/1.1 404 Not Found");
exit();
}
//Устанавливаем константы для работы с БД
define('KVD_MYSQL_HOST', 'localhost');
define('KVD_MYSQL_USER_NAME', 'root');
define('KVD_MYSQL_PASSWORD','');


form.html

<html>
<head>
<title></title>
</head>
<body>
<form
action method="POST">
<input
type="text" name="add">
<input
type="submit" name="add_button" value="Добавить запись">
</form>
<form
action method="GET">
<input
type="text" name="find" value="<?php echo $findtext; ?>">
<input
type="submit" name="find_button" value="Искать">
</form>
<?php


echo $content;

?>
</body>
</html>



.htaccess

AddDefaultCharset UTF-8
php_flag magic_quotes_gpc On

Спустя 1 час, 6 минут, 59 секунд (7.10.2010 - 00:45) twin написал(а):
Вот уже хотел сказать - эТО ПЯТЬ!

Ан нет. Вот тут косяк:
        //Переменная для возврата текста в форму поиска
$findtext = htmlentities($_GET['find'], null, 'utf-8');

Вот скажи, чем тебе обычная htmlspecialchars() не угодила? Вот чего было так мудрить?

И дело даже не в этом. Дело в том, что ты пока не научился тестить свои же скрипты.

Есть несколько проблемных символов. И несколько ситуаций, где эти проблемы могут вылезти.
Ну почему ты не сунул кавычку в поле поиска? А ведь злые хакеры сидят и суют. А если они туда сунут это:
Цитата
"onmousemove="alert(document.cookie)
?

Запомни, опасными считаются символы разметки. Это не значит, что их нужно удалять - для того и задача. Но нужно всегда проверять, что где может не так.


Остальное выше всяких похвал. Все красиво, аккуратно, надежно и грамотно.
Респектище за труд, даже эта ложка дегтя не омрачает приятного впечатления.
Молодец. user posted image

Спустя 20 минут, 20 секунд (7.10.2010 - 01:05) kovaldm написал(а):
Исправил.
htmlentities() выбрал потому что она преобразует все html-символы, в отличие от htmlspecialchars().
Много нового узнал, с простым чтением книжек не сравнить.
Вам респектище за задачу.

Результат

Спустя 20 дней, 22 часа, 3 минуты, 6 секунд (27.10.2010 - 23:09) DorianLeroy написал(а):
Здравствуйте, я дилетант в PHP, решал задачу twin'a сам, и сравнивал с кодом других, в частности kovaldm. Накопился ряд вопросов, думал логично было задать их здесь.
1. В чём смысл использования записи и вывода буфера, почему просто не написать html вместе с php?
2. Зачем ставить кавычки в SQL-запросах, например:
$result = mysql_query("SELECT * FROM `names`...

3. Зачем выставлять кодировку UTF-8? C кодировкой у меня вообще непонимание, киньте ссылку на хороший материал, я не понимаю почему в большинстве случаев стандартизируется код под UTF-8;
4. В этом куске кода:
  while($row = mysql_fetch_assoc($result))
{
$string = '•<a href="index.php?link='. $row['id'] .'">'. htmlentities($row['name']) .'</a><br>'.$string;
}
echo $string;

есть какая-то польза от забивания инфы в переменную, а потом вывод её после итерации.
5. Я честно перелопатил форум по наличию тем про защиту от F5,редирект header, но ничего толком не понял(тем много, но конкретно для новичка мало что понятного), вот в этой теме http://phpforum.ru/index.php?showtopic=202...F2%E0+%EE%F2+f5 обсуждается данная проблема, но уже не на уровне новичка.Хотел бы материал про редирект и header, в мануале тоже толком не расписано=(

Спустя 17 минут, 24 секунды (27.10.2010 - 23:26) twin написал(а):
Цитата
Здравствуйте, я дилетант в PHP, решал задачу twin'a сам, и сравнивал с кодом других, в частности kovaldm. Накопился ряд вопросов, думал логично было задать их здесь.

Это совсем не логично. Создай отдельную тему, предложи свое решение. Я обещаю детальнейший разбор и советы. smile.gif


_____________
sdfcfgvbgmlmknhvdfgctghvbj
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.