Результат здесь.
Приветствую всех форумчан. Вот мое решение. Чужие коды не смотрел - так не интересно.
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 написал(а):
Привет.
Вывод ошибок при подключениях к БД можно было сделать проще:
В этом случае не требуется exit и лишние условия.
Так же с выбором БД
Что значит "пустое или недопустимое"? Я вижу только не лучшую проверку на пустоту. Почему не сделать так: empty( $_POST['add'] );? Вроде бы empty пробелы тоже не пропускает. А если пропускает то, можно еще добавить trim. Что так же будет лучше.
Теперь странная обработка волшебных кавычек. Не стоит полагаться на эти кавычки, все нужно делать самому:
Так будет лучше. А то у вас, теоретически, возможна инъекция.
Я вот только не понял, зачем для поиска извлекать все записи, когда можно произвести этот поиск средствами SQL?
$_GET['find'] - обязательно нужно экранировать.
В итоге возвращается результат поиска. А все что после вашего запроса не нужно вообще.
Честно говоря не понял что за "вывод даты регистрации пользователя по ссылке". В поток выдается только первая запись, которую вернул запрос выше. Но вот только зачем тогда $_GET['link'], не знаю.
Вывод списка пользователей, тоже непонятно сделан. Все это можно реализовать в одном цикле и без создания каких-либо дополнительных массивов.
А после этого:
Не плохо было бы поставить exit(); Если уже ключ не был установлен, то делает переадресацию, и останавливаем все что дальше.
Еще неясно, зачем принудительно включать волшебные кавычки?
Ну, вот собственно все.
Работа не плохая. Мысли мыслят в нужную сторону - это хорошо.
Нужно поднатаскаться в теории и все будет отличненько.
P.S. Совет: уже с "раннего детства" пытайтесь отделять php и HTML кода.
И еще было бы очень хорошо, если бы все сообщения для юзера, вынеслись в массив, который можно положить в конфиге. Там будет крайне удобно
Вывод ошибок при подключениях к БД можно было сделать проще:
$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](http://phpforum.ru/html/emoticons/wink.gif)
Спустя 1 час, 58 минут, 37 секунд (3.10.2010 - 09:23) twin написал(а):
Привет. Тут уже посмотрели... Я добавлю немного.
Сначала по стилю. Просто с некоторых пор я не могу читать код, пока не приведу в порядок.
1.
тут сразу три недочета. Вопервых, константы желательно писать в верхнем регистре, иначе они в коде смтрятся как недописанные переменные. Это сбивает. Штатные (предопределенные) константы принято писать именно так: __FILE__, а не так __File__. Хотя работать конечно будет.
Дальше - кавычки. В таких местах, где не нужно использовать подстановки, лучше пользоваться апострофами. С ними код получается чище. Ну и пробелом нужно отделять операторы
2. Вот и смотри, как похоже на переменные...
Причем HostName в одном (верблюжьем) стиле, а Password иначе.
Вообще мой совет, делай константам префиксы. Это красивее, а главное убережет от конфликтов имен, если скрипт будет интегрирован в другую среду:
Никаких конфликтов, никакой неоднозначности, предельно ясно содержание константы.
3. Слишком много пустых строк. Приходится скролить лишнего и соответственно меньше кода входит на экран. И про сдвиги не забывай.
В таких местах не то что пустые строки, скобки ставить и то излишество:
Обрати внимание на кавычки. У тебя зачем то экранированные апострофы, это невалидно.
4.
5. Конкатенацию тоже желательно выделять пробелами.
Я делаю это со значимой строны. И экономно и читабельно.
6. Ну и табуляторы. Не пользуйся табуляторами, смотри какая каша получилась из-за них:
Где чья скобка... Черт ногу сломит.
По функционалу ApuktaChehov написал уже, правда не все.
Я попозже допишу. Можешь пока исправить в рамках этих замечаний.
Сначала по стилю. Просто с некоторых пор я не могу читать код, пока не приведу в порядок.
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](http://phpforum.ru/html/emoticons/biggrin.gif)
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
config.php
form.html
.htaccess
По поводу "%" и "_" - сам нашел недостаток, сам его устранил! Пришлось изрядно покопаться в руководстве по МуСКУЛу.
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 написал(а):
Молодец. Гораааааздо лучше стало.
По стилю еще пару замечаний (вернее советов)
1. Все же стоит отделять операторы пробелами. Это один из первейших признаков профессионального стиля
Не так
2. Если уж взялся писать кавычки - пиши их. Или используй апострофы везде. А так получается разброд и шатания. Тут одно:
3. Не используй длинных строк. Есть же символ переноса)))
Вот даже на широком экране горизонтальный скрол.
4. В тегах валиднее использовать кавычки. Да и чище это:
5. Не ставь этот значек в конце файла ?>, это дырка в безопасности.
Ну а теперь по функционалу.
От этой строчки я впал в ступор:
Я думал короткая форма тернарников будет только в 6-й версии, оказалось уже в 5.3 Соответственно на моей 5.2 работать не хочет
А вот испльзование логического оператора && в этом месте - полная новость для меня. Ошибка это или я отстал от жизни - выяснить не удалось, нет 5.3
Но в любом случае ошибка в этой строке есть. Функция header() в location требует полного пути, вместе с протоколом.
Теперь чуть выше:
Ну и сам индекс.
Задача решена не полностью.
1. С магическими кавычками недотянуто. Поставь в .htaccess
2. XSS цветет махровым цветом. Попробуй в поле поиска сунуть это:
![smile.gif](http://phpforum.ru/html/emoticons/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](http://phpforum.ru/html/emoticons/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](http://phpforum.ru/html/emoticons/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'Relly2. 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](http://phpforum.ru/html/emoticons/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
config.php
1. С магическими кавычками все нормально работает. Где вы здесь увидели недостаток? "Опасных" запросов к БД всего два: добавление записи и поиск, в обоих случаях данные обрабатываются. Все имена из списка для проверки регистрируются и находятся. В любом случае.
2. XSS обработал
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');
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. А то поисковики выдают очень однообразные советы, которые не помогают.
Итак:
Вывод данных из скрипта в 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
config.php
form.html
.htaccess
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 написал(а):
Вот уже хотел сказать - эТО ПЯТЬ!
Ан нет. Вот тут косяк:
Вот скажи, чем тебе обычная htmlspecialchars() не угодила? Вот чего было так мудрить?
И дело даже не в этом. Дело в том, что ты пока не научился тестить свои же скрипты.
Есть несколько проблемных символов. И несколько ситуаций, где эти проблемы могут вылезти.
Ну почему ты не сунул кавычку в поле поиска? А ведь злые хакеры сидят и суют. А если они туда сунут это:
Ан нет. Вот тут косяк:
//Переменная для возврата текста в форму поиска
$findtext = htmlentities($_GET['find'], null, 'utf-8');
Вот скажи, чем тебе обычная htmlspecialchars() не угодила? Вот чего было так мудрить?
И дело даже не в этом. Дело в том, что ты пока не научился тестить свои же скрипты.
Есть несколько проблемных символов. И несколько ситуаций, где эти проблемы могут вылезти.
Ну почему ты не сунул кавычку в поле поиска? А ведь злые хакеры сидят и суют. А если они туда сунут это:
Цитата |
"onmousemove="alert(document.cookie) |
?
Запомни, опасными считаются символы разметки. Это не значит, что их нужно удалять - для того и задача. Но нужно всегда проверять, что где может не так.
Остальное выше всяких похвал. Все красиво, аккуратно, надежно и грамотно.
Респектище за труд, даже эта ложка дегтя не омрачает приятного впечатления.
Молодец.
Запомни, опасными считаются символы разметки. Это не значит, что их нужно удалять - для того и задача. Но нужно всегда проверять, что где может не так.
Остальное выше всяких похвал. Все красиво, аккуратно, надежно и грамотно.
Респектище за труд, даже эта ложка дегтя не омрачает приятного впечатления.
Молодец.
![user posted image](http://pharm-forum.ru/smiles/applaus/1appl.gif)
Спустя 20 минут, 20 секунд (7.10.2010 - 01:05) kovaldm написал(а):
Исправил.
htmlentities() выбрал потому что она преобразует все html-символы, в отличие от htmlspecialchars().
Много нового узнал, с простым чтением книжек не сравнить.
Вам респектище за задачу.
Результат
htmlentities() выбрал потому что она преобразует все html-символы, в отличие от htmlspecialchars().
Много нового узнал, с простым чтением книжек не сравнить.
Вам респектище за задачу.
Результат
Спустя 20 дней, 22 часа, 3 минуты, 6 секунд (27.10.2010 - 23:09) DorianLeroy написал(а):
Здравствуйте, я дилетант в PHP, решал задачу twin'a сам, и сравнивал с кодом других, в частности kovaldm. Накопился ряд вопросов, думал логично было задать их здесь.
1. В чём смысл использования записи и вывода буфера, почему просто не написать html вместе с php?
2. Зачем ставить кавычки в SQL-запросах, например:
3. Зачем выставлять кодировку UTF-8? C кодировкой у меня вообще непонимание, киньте ссылку на хороший материал, я не понимаю почему в большинстве случаев стандартизируется код под UTF-8;
4. В этом куске кода:
есть какая-то польза от забивания инфы в переменную, а потом вывод её после итерации.
5. Я честно перелопатил форум по наличию тем про защиту от F5,редирект header, но ничего толком не понял(тем много, но конкретно для новичка мало что понятного), вот в этой теме http://phpforum.ru/index.php?showtopic=202...F2%E0+%EE%F2+f5 обсуждается данная проблема, но уже не на уровне новичка.Хотел бы материал про редирект и header, в мануале тоже толком не расписано=(
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](http://phpforum.ru/html/emoticons/smile.gif)
_____________
sdfcfgvbgmlmknhvdfgctghvbj