[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Решение задачи twin'а
Shuriken
Всем привет!

Задача twin'а здесь

Решение ниже



header("Content-Type: text/html; charset=utf-8");

$host='localhost';
$name='names';
$user='root';
$pass='';

@mysql_connect($host,$user,$pass);

@mysql_select_db($name);

$sql_insert="insert into names(name) values ('$_POST[name]')";
$sql_search="SELECT name
FROM names
WHERE name like '%"
.$_GET['name_s']."%'";
$sql_all="SELECT id, name
FROM names
ORDER by date desc"
;
$sql_url="SELECT id, name, date
FROM names
where id="
.substr(strstr($_SERVER['REQUEST_URI'],"id="),3);



if (isset($_POST['add']) && !empty($_POST['name']))
{
str_replace(' ', '', $_POST['name'], $count);
if ($count<>strlen($_POST['name']))
{
mysql_query($sql_insert);
header("location: ".$_SERVER['PHP_SELF']);
}
else echo "<font color=red><b>Имя пользователя не должно содержать только пробелы</b></font><br>";
}

if (strstr($_SERVER['REQUEST_URI'],"id="))
{
$url=mysql_query($sql_url) or die();
while ($row2=mysql_fetch_array($url))
{
echo "Пользователь <font color=green>".htmlspecialchars($row2['name'])."</font> добавлен ".$row2['date']."<br>";
}
}


if (isset ($_GET['search']) && !empty($_GET['name_s']))
{
$search_query=mysql_query($sql_search);
while($row=mysql_fetch_array($search_query))
{
echo htmlspecialchars($row['name'])."<br>";
$i++;
}
if ($i==0)
{
echo "<font color=red size=3><b>Пользователь с таким именем не зарегистрирован</b></font><br><hr>";
$i=0;
}
else echo "<hr>";
}

$all=mysql_query($sql_all);

while($row1=mysql_fetch_array($all))
{
echo "<a href=".$_SERVER['PHP_SELF']."?id=".$row1['id'].">".htmlspecialchars($row1['name'])."</a><br>";
}






<form action="" method=POST>
Имя <br><input type=text name="name"><br>
<input
type=submit name="add" value="Добавить">
</form>

<form
action="" method=get>
<br>
Поиск: <input type=text name="name_s" value="<? echo $_GET['name_s'];?>">
<input
type=submit name="search" value="Поиск">
</form>




На счёт защиты от SQL-инъекций и XSS-атак я не совсем разобрался. Если возможно, то привидите примеры SQL-инъекций и XSS-атак, которые проёдут на данной страничке.



Спустя 7 минут, 18 секунд (21.08.2012 - 11:34) Winston написал(а):
Цитата (Shuriken @ 21.08.2012 - 12:27)
На счёт защиты от SQL-инъекций и XSS-атак я не совсем разобрался

Так какой вообще смысл было делать задачу если ты не разобрался ни с SQL ни с XSS, ведь цель задачи была, чтобы научить пользователя защищаться от inj и xss

Спустя 16 минут, 47 секунд (21.08.2012 - 11:51) Shuriken написал(а):
Цитата (Winston @ 21.08.2012 - 09:34)
Цитата (Shuriken @ 21.08.2012 - 12:27)
На счёт защиты от SQL-инъекций и XSS-атак я не совсем разобрался

Так какой вообще смысл было делать задачу если ты не разобрался ни с SQL ни с XSS, ведь цель задачи была, чтобы научить пользователя защищаться от inj и xss

Например, смысл в том, чтобы мне помогли разобраться.

Против SQL-инъекция я поставил ковычки, попробовал несколько вариантов из гугла инъекций. Инъекция не проконала.

На счёт XSS-атакничего толком не нашёл, в основном написано как от них защититься, но мало где написано, то это. Как я могу понять как защититься от того, чего не понимаю.

Добавлял пользлвателя с именем <script>alert()</script>, после клика на нём выдавалось сообщение. htmlspecialchars эту проблему решил.

Напиши пару примеров инъекция и атак, которые могут навредить данной странице.

Спустя 12 минут, 3 секунды (21.08.2012 - 12:03) Winston написал(а):
Выложи этот код на какой то бесплатный хостинг

Спустя 14 минут, 44 секунды (21.08.2012 - 12:18) Winston написал(а):
Цитата (Shuriken @ 21.08.2012 - 12:27)
insert into names(name) values ('$_POST[name]')";

Попробуй зарегистрировать такое имя O'Relly, нормально пройдет рега?

А так же зарегистрируй все имена, что даны в задании, а потом по ним произведи поиск, корректно ли будет произведен поиск?
Mc''donalds
volt&amp;
I 100% know
Guest004
<Jensen & partners>
2*2=5?
\ bacslashes \
-=++++
%%%%

Спустя 13 минут, 13 секунд (21.08.2012 - 12:31) Shuriken написал(а):
Я всё это пробовал, всё отлично добавилось.

Спустя 3 минуты, 17 секунд (21.08.2012 - 12:34) inpost написал(а):
Отключи на сервере магические кавычки. Потом снова же попробуй свой код!
Отключение является обязательным, потому что в 5.4. уже нет магических кавычек.

Спустя 7 минут, 24 секунды (21.08.2012 - 12:42) Winston написал(а):
Т.к. в требовании написано
Цитата
5. Скрипт не должен зависеть от настройки magic_quotes.

То лучше использовать такую ф-ю
Свернутый текст
# Борьба с магическими кавычками      

if (get_magic_quotes_gpc())
{
function stripslashes_deep($value)
{
if( is_array($value) )
{
$value = array_map('stripslashes_deep', $value);
}
elseif ( !empty($value) && is_string($value) )
{
$value = stripslashes($value);
}
return $value;
}

$_GET = stripslashes_deep($_GET);
$_POST = stripslashes_deep($_POST);
$_COOKIE = stripslashes_deep($_COOKIE);
$_REQUEST = stripslashes_deep($_REQUEST);
}

Спустя 28 минут, 54 секунды (21.08.2012 - 13:11) Игорь_Vasinsky написал(а):
Winston
ох как я её не давно искал.. кое как нашёл)

тока чтоб не испугаться

 $_GET     = isset($_GET) ? stripslashes_deep($_GET) : null;
$_POST = isset($_POST) ? stripslashes_deep($_POST) : null;
$_COOKIE = isset($_COOKIE) ? stripslashes_deep($_COOKIE) : null;
$_REQUEST = isset($_REQUEST) ? stripslashes_deep($_REQUEST) : null;

Спустя 9 минут, 23 секунды (21.08.2012 - 13:20) Winston написал(а):
Игорь_Vasinsky
Твоя запись бессмысленна, т.к. все суперглобальные массивы которые ты проверяешь существуют всегда, можешь проверить
var_dump($_GET, $_POST, $_COOKIE, $_REQUEST);

Спустя 14 минут, 14 секунд (21.08.2012 - 13:34) Shuriken написал(а):
Цитата (inpost @ 21.08.2012 - 10:34)
Отключи на сервере магические кавычки. Потом снова же попробуй свой код!
Отключение является обязательным, потому что в 5.4. уже нет магических кавычек.

Отключение в файле php.ini?

Там я всё отключил


; Magic quotes
;

; Magic quotes for incoming GET/POST/Cookie data.
magic_quotes_gpc = Off

; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
magic_quotes_runtime = Off

; Use Sybase-style magic quotes (escape ' with '' instead of \').
magic_quotes_sybase = Off



Добавляются пользователи нормально

Спустя 3 минуты, 26 секунд (21.08.2012 - 13:38) Игорь_Vasinsky написал(а):
Цитата
Твоя запись бессмысленна,

точно... не задумывался над этим ohmy.gif

Спустя 2 минуты, 5 секунд (21.08.2012 - 13:40) Winston написал(а):
Shuriken
А после отключения перезапускал сервер?

Скрипт вообще не должен зависеть от магических кавычек, т.к. на некоторых хостингах они по умолчанию включены, и ты не можешь их выключить, здесь остается использовать только ф-ю которую я дал выше

Спустя 12 минут, 36 секунд (21.08.2012 - 13:52) inpost написал(а):
Если при insert ты вставишь одинарную кавычку с отключенными "магическими кавычками", у тебя тут же выйдет sql ошибка!

Спустя 1 минута, 38 секунд (21.08.2012 - 13:54) Игорь_Vasinsky написал(а):
ну вон же Winston дал функцию исключающую двойное экранирование при mysql_real_escape_string() + magic_quotes_gpc on

Спустя 4 часа, 4 минуты, 9 секунд (21.08.2012 - 17:58) twin написал(а):
То, что взялся решать задачу - респект. И то, что решил сам, без подсказок - тоже. Самостоятельность мышления - очень важный момент.

Однако, как и бывает в большинстве случаев, задача решена в корне не верно. Не учтен почти ни один пункт из требований к скрипту.

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

И вот когда сделаешь работу над ошибками, проведем доскональный разбор и твоего решения. Просто не хочется повторяться.

Спустя 17 часов, 32 минуты, 11 секунд (22.08.2012 - 11:30) Shuriken написал(а):
Цитата

Однако, как и бывает в большинстве случаев, задача решена в корне не верно. Не учтен почти ни один пункт из требований к скрипту.

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

И вот когда сделаешь работу над ошибками, проведем доскональный разбор и твоего решения. Просто не хочется повторяться.


У меня код был зависим от настройки magic_quotes, и как следствие при выключении magic_quotes не добавлялись имена, содержащие одинарную кавычку и \.

Работу над ошибками сделал. Вот что получилось:


header("Content-Type: text/html; charset=utf-8");

$host='localhost';
$name='names';
$user='root';
$pass='';

@mysql_connect($host,$user,$pass);

@mysql_select_db($name);

if (get_magic_quotes_gpc())
{
function stripslashes_deep($value)
{
if( is_array($value) )
{
$value = array_map('stripslashes_deep', $value);
}
elseif ( !empty($value) && is_string($value) )
{
$value = stripslashes($value);
}
return $value;
}

$_GET = stripslashes_deep($_GET);
$_POST = stripslashes_deep($_POST);
$_COOKIE = stripslashes_deep($_COOKIE);
$_REQUEST = stripslashes_deep($_REQUEST);

}


$sql_insert="insert into names(name) values ('".mysql_real_escape_string($_POST['name'])."')";
$sql_search="SELECT name
FROM names
WHERE name like '%"
.mysql_real_escape_string($_GET['name_s'])."%'";
$sql_all="SELECT id, name
FROM names
ORDER by date desc"
;
$sql_url="SELECT id, name, date
FROM names
where id="
.substr(strstr($_SERVER['REQUEST_URI'],"id="),3);



if (isset($_POST['add']) && !empty($_POST['name']))
{
str_replace(' ', '', $_POST['name'], $count);
if ($count<>strlen($_POST['name']))
{
mysql_query($sql_insert) or die ("error insert");
header("location: ".$_SERVER['PHP_SELF']);
}
else echo "<font color=red><b>Имя пользователя не должно содержать только пробелы</b></font><br>";
}

if (strstr($_SERVER['REQUEST_URI'],"id="))
{
$url=mysql_query($sql_url) or die ("error click");
while ($row2=mysql_fetch_array($url))
{
echo "Пользователь <font color=green>".htmlspecialchars($row2['name'])."</font> добавлен ".$row2['date']."<br>";
}
}


if (isset ($_GET['search']) && !empty($_GET['name_s']))
{
$search_query=mysql_query($sql_search) or die ("error search");
while($row=mysql_fetch_array($search_query))
{
echo htmlspecialchars($row['name'])."<br>";
$i++;
}
if ($i==0)
{
echo "<font color=red size=3><b>Пользователь с таким именем не зарегистрирован</b></font><br><hr>";
$i=0;
}
else echo "<hr>";
}

$all=mysql_query($sql_all) or die ("error select");

while($row1=mysql_fetch_array($all))
{
echo "<a href=".$_SERVER['PHP_SELF']."?id=".$row1['id'].">".htmlspecialchars($row1['name'])."</a><br>";
}








<form action="" method=POST>
Имя <br><input type=text name="name"><br>
<input
type=submit name="add" value="Добавить">
</form>

<form
action="" method=get>
<br>
Поиск: <input type=text name="name_s" value="<? echo $_GET['name_s'];?>">
<input
type=submit name="search" value="Поиск">
</form>



Спустя 16 минут, 47 секунд (22.08.2012 - 11:47) inpost написал(а):
Введи текст, а потом проверь длину его через strlen smile.gif Будет ошибка.

Спустя 17 минут, 15 секунд (22.08.2012 - 12:04) Shuriken написал(а):
Цитата (inpost @ 22.08.2012 - 09:47)
Введи текст, а потом проверь длину его через strlen smile.gif Будет ошибка.

Куда ввести текст?

Спустя 3 минуты, 40 секунд (22.08.2012 - 12:08) Zzepish написал(а):
Цитата (inpost @ 21.08.2012 - 10:34)
Отключи на сервере магические кавычки. Потом снова же попробуй свой код!
Отключение является обязательным, потому что в 5.4. уже нет магических кавычек.

УРАААААА! Наконец-то =)

Спустя 2 минуты, 2 секунды (22.08.2012 - 12:10) Игорь_Vasinsky написал(а):
Цитата
header("Content-Type: text/html; charset=utf-8");

Цитата
if ($count<>strlen($_POST['name']))

Спустя 58 секунд (22.08.2012 - 12:11) inpost написал(а):
Введи в форму текст и посчитай его длину через strlen. Увидишь, что функция strlen не подходит, так как нужна библиотека mb_ для ЮТФ-8

Спустя 3 минуты, 7 секунд (22.08.2012 - 12:14) Shuriken написал(а):
Цитата (inpost @ 22.08.2012 - 10:11)
Введи в форму текст и посчитай его длину через strlen. Увидишь, что функция strlen не подходит, так как нужна библиотека mb_ для ЮТФ-8

Ошибки нет

Спустя 2 минуты, 39 секунд (22.08.2012 - 12:17) Игорь_Vasinsky написал(а):
кирилицу введи

Спустя 1 минута, 40 секунд (22.08.2012 - 12:18) inpost написал(а):
Shuriken
Ошибки и не будет, просто считать будет иначе. strlen считает байты, а русские символы в UTF-8 - двухбайтные.

Спустя 19 минут, 33 секунды (22.08.2012 - 12:38) Shuriken написал(а):
Цитата (inpost @ 22.08.2012 - 10:18)
Shuriken
Ошибки и не будет, просто считать будет иначе. strlen считает байты, а русские символы в UTF-8 - двухбайтные.

Понял. Исправил. Хотя в данном коде эта функция не обязательно, т.к. пробел он и в Африке пробел, но за ликбез спасибо)


if (isset($_POST['add']) && !empty($_POST['name']))
{
str_replace(' ', '', $_POST['name'], $count);
if ($count<>mb_strlen($_POST['name'],'utf-8'))
{
mysql_query($sql_insert) or die ("error insert");
header("location: ".$_SERVER['PHP_SELF']);
}
else echo "<font color=red><b>Имя пользователя не должно содержать только пробелы</b></font><br>";
}

Спустя 56 минут, 49 секунд (22.08.2012 - 13:35) inpost написал(а):
убираем пробелы: trim() , проверяем на пустоту строки: !empty(). Так будет грамотнее.

Спустя 16 минут, 2 секунды (22.08.2012 - 13:51) Shuriken написал(а):
Цитата (inpost @ 22.08.2012 - 11:35)
убираем пробелы: trim() , проверяем на пустоту строки: !empty(). Так будет грамотнее.

О такой функции я не знал. Спасибо. Так будет не только грамотней, но и код будет проще


if (isset($_POST['add']) && !empty($_POST['name']))
{
if (trim($_POST['name']))
{
mysql_query($sql_insert) or die ("error insert");
header("location: ".$_SERVER['PHP_SELF']);
}
else echo "<font color=red><b>Имя пользователя не должно содержать только пробелы</b></font><hr><br>";
}

Спустя 46 минут, 12 секунд (22.08.2012 - 14:37) inpost написал(а):
Не так, trim убирает пробелы. Сначала убери пробелы с данных:
$_POST['name'] = trim($_POST['name']);
А уже потом проверяй, !empty ли данные. Не забывай, что перед этим ещё на isset проверять надо.

Спустя 19 минут, 28 секунд (22.08.2012 - 14:57) Shuriken написал(а):
Цитата (inpost @ 22.08.2012 - 12:37)
Не так, trim убирает пробелы. Сначала убери пробелы с данных:
$_POST['name'] = trim($_POST['name']);
А уже потом проверяй, !empty ли данные. Не забывай, что перед этим ещё на isset проверять надо.

Зачем проверять на isset, если проверяется на empty, что и делает эта запись if (trim($_POST['name']))?

Спустя 6 часов, 49 минут, 6 секунд (22.08.2012 - 21:46) twin написал(а):
Давай по порядку.

Вот это на грани паранойи как минимум, а на самом деле попахивает методом тыка.
    $_COOKIE  = stripslashes_deep($_COOKIE);
$_REQUEST = stripslashes_deep($_REQUEST);
Разве эти массивы используются скриптом? Явно лишнее телодвижение. Собственно как и эта проверка в функции:
       elseif ( !empty($value) && is_string($value) )
Дело в том, что все элементы суперглобальных массивов POST и GET имеют тип string, даже если там одни цифры.

В следующей строке обращение к несуществующему элементу:
$sql_insert="insert into names(name) values ('".mysql_real_escape_string($_POST['name'])."')";
Пока не нажата кнопка, $_POST['name'] отсутствует. В этом легко убедиться, включив максимльный уровень ошибок. Прописав первой строкой к примеру это:
    error_reporting(E_ALL);
Я понимаю, что денвер прощает такие вольности, но это очень плохая практика.

Следующий запрос не справтся с такими символами в имени: % и _, а это одно из ключевых условий задачи - все символы без исключений.

Тут не онял логики
$sql_url="SELECT id, name, date
FROM names
where id="
.substr(strstr($_SERVER['REQUEST_URI'],"id="),3);
А почему не сразу из GET... Ну с логикой позже, пока грубые ошибки.

Здесь первая проверка лишняя
if (isset($_POST['add']) && !empty($_POST['name']))
Прелесть функции empty() в том, что она не генерирует нотис при отсутствии переменной. Однако при использовании её в данном контексте не пройдет имя 0(ноль), а это тоже ошибка.

Дальше пытались что-то поправить.
if (trim($_POST['name']))

грубое нарушение семмантики. Неинициализирована переменная - раз, функция trim() не возвращает булевых значений. Тогда уж нужно привести тип.

После редиректа:
		header("location: ".$_SERVER['PHP_SELF'])
скрипт желательно останавливать.

Дальше та же семмантика и невнятный $_SERVER['REQUEST_URI'] вместо GET

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

Насчет логики и выполнения условий пока не скажу - нужно ставить и тестить. А ставить это безобразие нет смысла. спрвляй.

Спустя 57 минут, 33 секунды (22.08.2012 - 22:43) inpost написал(а):
twin
Давай я тебя подправлю по двум пунктам.
"Дело в том, что все элементы суперглобальных массивов POST и GET имеют тип string, даже если там одни цифры." за исключением массивов, хотя в их случае уже элементы массивов будут стринговые.

"error_reporting(E_ALL);" - правильнее error_reporting(-1);, до того, пока 5.4 php не вошла в обороты.


Спустя 25 минут, 38 секунд (22.08.2012 - 23:09) twin написал(а):
По первому вопросу - массивы отсекаются первой проверкой. Разумеется имелись ввиду конечные элементы.

По второму вопросу - с чего бы ради 5.4? Предопределенная константа E_ALL появилась за долго до этой ветки. И содержит она 30719, а вовсе не -1.

Спустя 55 минут, 10 секунд (23.08.2012 - 00:04) inpost написал(а):
Чтобы включить вывод абсолютно всех ошибок, включая E_STRICT. Цитата из мануала:
"Passing in the value -1 will show every possible error, even when new levels and constants are added in future PHP versions. The E_ALL constant also behaves this way as of PHP 5.4."

Спустя 12 часов, 44 минуты, 22 секунды (23.08.2012 - 12:48) twin написал(а):
А, вон ты про что. Ну это уже на любителя. Тут была уже небольшая полемика на эту тему. По мне, так E_STRICT - явный перебор. Хотя ты прав, для максимального уровня ошибок нужно и deprecadet ловить. Только -1 не радует, прозрачнее так:
error_reporting(E_ALL | E_STRICT);

Спустя 21 час, 38 минут, 48 секунд (24.08.2012 - 10:27) Shuriken написал(а):
Цитата
Вот это на грани паранойи как минимум, а на самом деле попахивает методом тыка.
    $_COOKIE  = stripslashes_deep($_COOKIE);
    $_REQUEST = stripslashes_deep($_REQUEST);

Разве эти массивы используются скриптом? Явно лишнее телодвижение. Собственно как и эта проверка в функции:
      elseif ( !empty($value) && is_string($value) )

Дело в том, что все элементы суперглобальных массивов POST и GET имеют тип string, даже если там одни цифры.


Согласен, перебор, исправил.

Цитата
В следующей строке обращение к несуществующему элементу:
<pre clasВ следующей строке обращение к несуществующему элементу:
$sql_insert="insert into names(name) values ('".mysql_real_escape_string($_POST['name'])."')";

Пока не нажата кнопка, $_POST['name'] отсутствует.

Дальше пытались что-то поправить.
if (trim($_POST['name']))


грубое нарушение семмантики. Неинициализирована переменная - раз, функция trim() не возвращает булевых значений. Тогда уж нужно привести тип.



Исправил

if (isset($_POST['add']) && !empty($_POST['name']))  
{
$_POST['name']=trim($_POST['name']);
if (!empty($_POST['name']))
{
$sql_insert="insert into names(name) values ('".mysql_real_escape_string($_POST['name'])."')";
mysql_query($sql_insert) or die ("error insert");
header("location: ".$_SERVER['PHP_SELF']);
exit;
}
else echo "<font color=red><b>Имя пользователя не должно содержать только пробелы</b></font><hr><br>";
}



На счёт 0 (нуля) не знаю как, подскажите плз.


Цитата
Следующий запрос не справтся с такими символами в имени: % и _, а это одно из ключевых условий задачи - все символы без исключений.


Добавил функцию str_replace
if (isset ($_GET['search']) && !empty($_GET['name_s']))
{
$replace=str_replace('%','\%',$_GET['name_s']);
$replace=str_replace('_','\_',$replace);
$sql_search="SELECT name
FROM names
WHERE name like '%"
.mysql_real_escape_string($replace)."%'";
$search_query=mysql_query($sql_search) or die ("error search");
while($row=mysql_fetch_array($search_query))
{
echo htmlspecialchars($row['name'])."<br>";
$i++;
}
if ($i==0)
{
echo "<font color=red size=3><b>Пользователь с таким именем не зарегистрирован</b></font><br><hr>";
$i=0;
}
else echo "<hr>";
}


Цитата
Дальше та же семмантика и невнятный $_SERVER['REQUEST_URI'] вместо GET


Я не нашёл как черехз клик по ссылке передать данные через GET, поэтому использовал массив $_SERVER

Спустя 4 минуты, 43 секунды (24.08.2012 - 10:32) Shuriken написал(а):
Не знаю почему, но код не хочет обрамлятся тегами php

Спустя 1 час, 49 минут, 24 секунды (24.08.2012 - 12:21) inpost написал(а):
Их надо вручную,
[php][/php]

Спустя 11 часов, 43 минуты, 53 секунды (25.08.2012 - 00:05) twin написал(а):
Цитата (Shuriken @ 24.08.2012 - 08:32)
Не знаю почему, но код не хочет обрамлятся тегами php

Это глюк форума. Сапожник без сапог.

Выложи весь код плиз, так трудно ориентироваться.

Спустя 2 дня, 8 часов, 57 минут, 36 секунд (27.08.2012 - 09:03) Shuriken написал(а):

<?
header("Content-Type: text/html; charset=utf-8");

$host='localhost';
$name='names';
$user='root';
$pass='';

@mysql_connect($host,$user,$pass);

@mysql_select_db($name);

if (get_magic_quotes_gpc())
{
function stripslashes_deep($value)
{
if( is_array($value) )
{
$value = array_map('stripslashes_deep', $value);
}
return $value;
}

$_GET = stripslashes_deep($_GET);
$_POST = stripslashes_deep($_POST);
}


$sql_all="SELECT id, name
FROM names
ORDER by date desc"
;

$sql_url="SELECT id, name, date
FROM names
where id="
.substr(strstr($_SERVER['REQUEST_URI'],"id="),3);


if (isset($_POST['add']) && !empty($_POST['name']))
{
$_POST['name']=trim($_POST['name']);
if (!empty($_POST['name']))
{
$sql_insert="insert into names(name) values ('".mysql_real_escape_string($_POST['name'])."')";
mysql_query($sql_insert) or die ("error insert");
header("location: ".$_SERVER['PHP_SELF']);
exit;
}
else echo "<font color=red><b>Имя пользователя не должно содержать только пробелы</b></font><hr><br>";
}


if (strstr($_SERVER['REQUEST_URI'],"id="))
{
$url=mysql_query($sql_url) or die ("error click");
while ($row2=mysql_fetch_array($url))
{
echo "Пользователь <font color=green>".htmlspecialchars($row2['name'])."</font> добавлен ".$row2['date']."<br>";
}
}


if (isset ($_GET['search']) && !empty($_GET['name_s']))
{
$replace=str_replace('%','\%',$_GET['name_s']);
$replace=str_replace('_','\_',$replace);
$sql_search="SELECT name
FROM names
WHERE name like '%"
.mysql_real_escape_string($replace)."%'";
$search_query=mysql_query($sql_search) or die ("error search");
while($row=mysql_fetch_array($search_query))
{
echo htmlspecialchars($row['name'])."<br>";
$i++;
}
if ($i==0)
{
echo "<font color=red size=3><b>Пользователь с таким именем не зарегистрирован</b></font><br><hr>";
$i=0;
}
else echo "<hr>";
}

$all=mysql_query($sql_all) or die ("error select");

while($row1=mysql_fetch_array($all))
{
echo "<a href=".$_SERVER['PHP_SELF']."?id=".$row1['id'].">".htmlspecialchars($row1['name'])."</a><br>";
}


?>


<form action="" method=POST>
Имя <br><input type=text name="name"><br>
<input
type=submit name="add" value="Добавить">
</form>

<form
action="" method=get>
<br>
Поиск: <input type=text name="name_s" value="<? echo $_GET['name_s'];?>">
<input
type=submit name="search" value="Поиск">
</form>



Стиль кодирования я ещё не правил. Вопрос по стилю: почему для отступа использовать пробелы, а не табуляцию?

Спустя 3 минуты, 43 секунды (27.08.2012 - 09:06) Invis1ble написал(а):
наверное потому что табуляция везде отображается по разному

Спустя 1 час, 32 минуты, 55 секунд (27.08.2012 - 10:39) inpost написал(а):
Shuriken
По правилам надо использовать ИЛИ-ИЛИ. Лично я использую табуляцию. Плохой тон - это перемешивать.

Спустя 3 часа, 52 минуты, 16 секунд (27.08.2012 - 14:32) twin написал(а):
Вот это плохо:
	$_POST['name']=trim($_POST['name']);
Ты модифицируешь суперглобальный массив, а это не гоже.

Тут нотис:
<br>Поиск: <input type=text name="name_s" value="<? echo $_GET['name_s'];?>">


Ну и со стилем что-то нужно делать. А там и сам увидишь, где можно написать порациональнее. Вот тут к примеру:
	$replace=str_replace('%','\%',$_GET['name_s']);
$replace=str_replace('_','\_',$replace);
А в целом уже совсем недурственно. :)

Спустя 21 минута, 20 секунд (27.08.2012 - 14:53) Shuriken написал(а):
twin
Так можно писать?
        $replace = str_replace('_', '\_', (str_replace('%', '\%', $_GET['name_s'])));


Что такое нотис?

Спустя 2 минуты, 40 секунд (27.08.2012 - 14:56) KOPOJI написал(а):
Что такое нотис? ошибка уровня E_NOTICE - о несуществующих индексах, переменных, об использовании в массивах строковых индексов без кавычек/апострофов. По умолчанию обычно отключено (E_ALL & ~E_NOTICE)

Спустя 5 минут, 40 секунд (27.08.2012 - 15:01) Shuriken написал(а):
Если я рпавильно понял, то здесь:

<br>Поиск: <input type=text name="name_s" value="<? echo $_GET['name_s'];?>">


должна выскакивать ошибка? Но у меня значение поиска вставляется нормально, без искажений.

Спустя 5 минут, 36 секунд (27.08.2012 - 15:07) KOPOJI написал(а):
Цитата
должна выскакивать ошибка? Но у меня значение поиска вставляется нормально, без искажений.

а вы в начале скрипта пропишите
error_reporting(E_ALL);
я ж говорю, они по умолчанию отключены)

Спустя 20 часов, 20 минут, 8 секунд (28.08.2012 - 11:27) Shuriken написал(а):
Включил нотисы, в поле поиска до нажатия кнопки Поиск выводилась ошибка, т.к. переменной $_GET['name_s'] не существовало ещё. Подправил. Но сейчас нотисы выводятся при поиске.

Вот скрипт:

<?  
header("Content-Type: text/html; charset=utf-8");
$host = 'localhost';
$name = 'names';
$user = 'root';
$pass = '';
@mysql_connect($host, $user, $pass);
@mysql_select_db($name);

error_reporting(E_ALL);

if(get_magic_quotes_gpc())
{
function stripslashes_deep($value)
{

if(is_array($value))
{
$value = array_map('stripslashes_deep', $value);
}
return $value;
}
$_GET = stripslashes_deep($_GET);
$_POST = stripslashes_deep($_POST);
}
$sql_all = "SELECT id, name
FROM names
ORDER by date desc"
;
$sql_url = "SELECT id, name, date
FROM names
where id="
. substr(strstr($_SERVER['REQUEST_URI'], "id="), 3);

if(isset($_POST['add']) && !empty($_POST['name']))
{
$add = trim($_POST['name']);

if(!empty($add))
{
$sql_insert = "insert into names(name) values ('".mysql_real_escape_string($add)."')";
mysql_query($sql_insert) or die("error insert");
header("location: ". $_SERVER['PHP_SELF']);
exit;
}
else
{
echo "<font color=red><b>Имя пользователя не должно содержать только пробелы</b></font><hr><br>";
}
}


if(strstr($_SERVER['REQUEST_URI'], "id="))
{
$url = mysql_query($sql_url) or die("error click");
while($row2 = mysql_fetch_array($url))
{
echo "Пользователь <font color=green>". htmlspecialchars($row2['name']) ."</font> добавлен ". $row2['date'] ."<br>";
}
}


if(isset($_GET['search']) && !empty($_GET['name_s']))
{
$replace = str_replace('_', '\_', (str_replace('%', '\%', $_GET['name_s'])));
$sql_search = "SELECT name
FROM names
WHERE name like '%"
.mysql_real_escape_string($replace)."%'";
$search_query = mysql_query($sql_search) or die("error search");
while($row = mysql_fetch_array($search_query))
{
echo htmlspecialchars($row['name']) ."<br>";
$i++;
}

if($i == 0)
{
echo "<font color=red size=3><b>Пользователь с таким именем не зарегистрирован</b></font><br><hr>";
$i = 0;
}
else
{
echo "<hr>";
}
}

$all = mysql_query($sql_all) or die("error select");
while($row1 = mysql_fetch_array($all))
{
echo "<a href=". $_SERVER['PHP_SELF'] ."?id=". $row1['id'] .">". htmlspecialchars($row1['name']) ."</a><br>";
}
?>


<form action="" method=POST>
Имя <br><input type=text name="name"><br>
<input
type=submit name="add" value="Добавить">
</form>

<form
action="" method=get>
<br>
Поиск: <input type=text name="name_s" value="<? if(isset($_GET['search'])) echo $_GET['name_s'];?>">
<input
type=submit name="search" value="Поиск">
</form>


Если данный пользователь есть в базе, то выводится список пользователей и такая ошибка:

Notice: Undefined variable: i in K:\home\localhost\www\twin\index.php on line 69

69-тая сторка это
$i++;


Если пользователя в базе нет, то

Notice: Undefined variable: i in K:\home\localhost\www\twin\index.php on line 72

72-ая строчка это
if($i == 0)


В чём ошибка?

Стиль подправил воспользовавшись данной ссылкой))))

Спустя 22 минуты, 10 секунд (28.08.2012 - 11:49) twin написал(а):
Последний штрих, посмотри, что будет с обратным слэшем.

Кстати, зачем из функции stripslashes_deep() убрал stripslashes()?

Вот этого я так и не понял:
    $sql_url = "SELECT id, name, date 
FROM names
where id="
. substr(strstr($_SERVER['REQUEST_URI'], "id="), 3);

Чем не угодил просто GET?

И еще. Введи в поле поиска это:
Цитата
"><iframe src="http://sex.ru" />

будет интересно.

Цитата
В чём ошибка?

Ты пытаешься инкрементировать несуществующую переменную. То есть не задал начальное знчение. Нужно до цикла написать
$i = 0;

Спустя 1 час, 4 минуты, 59 секунд (28.08.2012 - 12:54) Shuriken написал(а):
Цитата
Кстати, зачем из функции stripslashes_deep() убрал stripslashes()?


Ой, провтыкал)

Цитата


Вот этого я так и не понял:
<pre class="sh_sourceCode" rel="php">    <span class="sh_variable">$sql_url</span> <span class="sh_symbol">=</span> <span class="sh_string">"SELECT id, name, date
                    FROM names 
                    where id="</span><span class="sh_symbol">.</span> <span class="sh_function">substr</span><span class="sh_symbol">(</span><span class="sh_function">strstr</span><span class="sh_symbol">(</span><span class="sh_variable">$_SERVER</span><span class="sh_symbol">[</span><span class="sh_string">'REQUEST_URI'</span><span class="sh_symbol">],</span> <span class="sh_string">"id="</span><span class="sh_symbol">),</span> <span class="sh_number">3</span><span class="sh_symbol">);</span></pre>
Чем не угодил просто GET?



Как по клику на ссылку передать значение через GET?

Цитата

И еще. Введи в поле поиска это:
Цитата
"><iframe src="http://sex.ru" />

будет интересно.


Это XSS атака? Как от неё защититься?

Для обратного слэша вот такое добавить:

$replace = str_replace('\\','\\\\',(str_replace('_', '\_', (str_replace('%', '\%', $_GET['name_s'])))));

Спустя 10 минут, 12 секунд (28.08.2012 - 13:04) twin написал(а):
Цитата (Shuriken @ 28.08.2012 - 10:54)
Как по клику на ссылку передать значение через GET?



Очень просто... Посмотри как у других сделано.

Цитата
Это XSS атака? Как от неё защититься?
Она самая. Нужно всегда вывод обрабатывать htmlspecialchars()

Цитата
Для обратного слэша вот такое добавить:

$replace = str_replace('\\','\\\\',(str_replace('_', '\_', (str_replace('%', '\%', $_GET['name_s'])))));
можно и так. Хотя лучше внимательно почитать мануал про функцию str_replace(). Особенно в части массивов в аргументе.

Спустя 1 день, 23 часа, 12 минут, 50 секунд (30.08.2012 - 12:17) Shuriken написал(а):
Заменил

$replace = str_replace('\\','\\\\',(str_replace('_', '\_', (str_replace('%', '\%', $_GET['name_s'])))));


на

$s=array ('_', '%', '\\');
$r=array ('\_', '\%', '\\\\');
$replace=str_replace($s, $r, $_GET['name_s']);


Вроде всё правильно, но _ заменяется на \\_, с % точно также. Что не так?
Быстрый ответ:

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