|
|
|
| Ответ 008 на задачу N 21.
С условиями задачи можно ознакомится по ссылке.http://www.softtime.ru/info/task.php?id_article=110
<?php
//Задачу решал для себя, поэтому использовал свое подключение
include "dbconnect.php";
//Это от флуда предосторожности
if($_GET['go']||$_GET['name']){
$name = $_POST['name'];
//Обработка входных даных
if($_GET['name']){
$name = stripslashes(htmlspecialchars($_GET['name']));
$name = rawurldecode($name);
$name=str_replace("&amp;","&",$name);
$name=str_replace("&quot;","\"",$name);
$name=str_replace("&lt;","<",$name);
$name=str_replace("&gt;",">",$name);
$name=str_replace("&nbsp;"," ",$name);
//Подсчет символов, пока всяких слэшей не навтыкалось
$count_name=strlen($name);
$name=str_replace("\\","\\\\",$name);
}
//Это так, не люблю ошибки, потому что сам много их делаю
$count=strlen($count_name)-1;
$count_var=substr($count_name, $count);
if($count_var==1){
$varsh="символ";
}
if($count_var==2 || $count_var==3||$count_var==4){
$varsh="символа";
}
if($count_var==0 || preg_match("/[5-9]/",$count_name) || preg_match("/[1][\d]/",$count_name)){
$varsh="символов";
}
//Обработка данных для запроса
if (get_magic_quotes_gpc()) $name = stripslashes($name);
$name_db = mysql_real_escape_string($name);
$name = htmlspecialchars($name);
//Поиск имени.
$query = mysql_query("SELECT visits FROM guests WHERE guestname='".$name_db."'") or die ('Error: 1' . mysql_error());
$userdata = mysql_fetch_assoc($query);
$visits = $userdata['visits'];
//Это опять прическа
$count=strlen($visits)-1;
$count_var=substr($visits, $count);
if($count_var==2||$count_var==3||$count_var==4){
$varsh_c="раза";
}
else
{
$varsh_c="раз";
}
//Если вход
if($_POST['in']){
if(!$visits){//Если нет имени в БД, добавляю строчку
$visits=1;
mysql_query("INSERT INTO guests SET guestname='".$name_db."', visits='".$visits."'") or die ('Error: 2' . mysql_error());
}
else
{//Если есть, плюсую визит
$visits++;
mysql_query("UPDATE guests SET visits ='".$visits."' WHERE guestname='".$name_db."'") or die ('Error: 3' . mysql_error());
$mess_d="На юзьверя под ником <b>".$name."</b> уже заведено досье. ";//Не примите за чистую монету
}
//Война с F5
if($_POST['name']){
$name= rawurlencode($name);
header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']."?new=1&name=$name");
exit;
}
}
//Формирую сообщение
if($_GET['new'])$mess=$mess_d."Таки здрасти <b>".$name."</b>! Мы знаем, что в Вашем имени ".$count_name." ".$varsh.", и Вы у нас ".$visits."-й раз";
//Если поиск введенного имени
if($_GET['sel']||$_GET['name']&&!$_GET['new']){
if(!$visits){
$mess="Не, <b>".$name."</b> пока не числится, зайдите позже! Хотя мы знаем, что в его имени ".$count_name." ".$varsh ;
}
else
{
$mess="Гражданин <b>".$name."</b> побывал у нас ".$visits." ".$varsh_c.". Поэтому мы знаем, что в его имени ".$count_name." ".$varsh;
$mysql=" WHERE guestname='".$name_db."'";
$all="<a href='?go=1'>Показать всех</a>";
}
}
}
//Список соискателей
$query = mysql_query("SELECT guestname, visits, id FROM guests $mysql") or die ('Error: 4' . mysql_error());
$count=mysql_num_rows($query);
if($count==0)$mess="Пусто.";
for($i=0;$i<$count; $i++){
$link = htmlspecialchars(mysql_result($query, $i, "guestname"));
$link_name=str_replace("&amp;","&",$link);
$link_name=str_replace("&quot;","\"",$link_name);
$link_name=preg_replace("#[\s]{1}#"," ",$link_name);
$link_del=str_replace("\\","\\\\",$link);
$link_del=str_replace("'","\'",$link_del);
$href_name = rawurlencode($link_name);
$tr.="<tr><td style='width:20px'>".($i+1)."</td><td><a href='".$PHP_SELF."?name=".$href_name."'>".$link_name."</a></td>
<td>".mysql_result($query, $i, "visits")."</td>
<td><a href='#' onclick=\"javascript:Delete('".mysql_result($query, $i, "id")."','".$link_del."')\">dell</a></td></tr>";
}
//Таблица
$table="<table><tr><td style='width:20px'><b>№</b></td><td><b>Имя</b></td><td><b>Визиты</b></td><td><b>Удалить</b></td></tr>".$tr."</table>";
//Удаление строчки
if($_GET['delete']){
mysql_query("DELETE FROM guests WHERE id = '".intval($_GET['id'])."'") or die ('Error: 5' . mysql_error());
header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']."?go=1");
exit;
}
//Формы
$form="<form action=".$PHP_SELF."?go=1 method=post ><input type=text name=name ><input type=submit name=in value=Войти ></form>
<form action=".$PHP_SELF."?go=1 method=get ><input type=text name=name ><input name=sel type=submit value=Найти ></form>";
?>
<html>
<head>
<style>
body{
background-color:#FFFFCC;
}
table {
border-collapse: collapse;
}
td{
border: 1px solid;
width:100px;
text-align:center;
color:#666699;
background-color:#e6e6e6;
}
</style>
<script type="text/javascript">
function Delete(id, name){
confirm("Вы действительно хотите навсегда удалить "+name+"?")?
location.href="<? echo $PHP_SELF ?>?delete=1&id="+id : alert("А зря.");
}
</script>
<meta http-equiv="Выберите расширение для паковки" content="text/html; charset=windows-1251" /><meta http-equiv="Выберите расширение для паковки" content="text/html; charset=windows-1251" /></head>
<body>
<?
echo "<span style='color:red'>".$mess."</span>";
?>
<hr>
<?
echo $all.$form.$table;
?>
</body>
</html>
|
Так как ответ вне конкурса, постараюсь извлечь максимум пользы. Писал специально в своей манере, не на выставку, чтобы натыкали носом. Пожалуйста, если можно, прокомментируйте по подробнее, не только ошибки по теме, но и в общих чертах.
Спасибо.
PS Одну проблему решить не смог: отображение пробелов (когда одни пробелы). Заменить на _ нельзя, получится нижнее подчеркивание,а не пробел. | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 03:10)
| | В ветке с обсуждением задачи есть табличка тестовых имен.
(01.06.2007 в 21:41)
Сколько из них вы проверили?
Сдается мне - ни одного. | |
|
|
|
|
|
|
|
для: Trianon
(20.08.2008 в 10:28)
| | Да, ни одного не проверил. По этой ссылке тема отсутствует. | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 11:45)
| | Извиняюсь, наверное форум проглючил, писал большими красными буквами, что темы нет. Сейчас посмотрел еще раз, сработало.
Проверил все, есть один "косячок", не отображает комбинацию символов %25. Попробую что-нибудь придумать. | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 12:10)
| | А для остальных имен правильно считает длину и корректно укладывает имена в таблицу?
Код Ваш у меня выдает нотайсы. Так что... | |
|
|
|
|
|
|
|
для: Trianon
(20.08.2008 в 13:14)
| | Я совсем незнаком с методами тестирования, так что все делаю вручную. Исправленный скрипт имена из тестовой таблицы обрабатывает корректно. Подскажите, что не так?
На счет длинны - он пробелы за символ считает, но в задании о всех символах говорилось. Правда когда одни пробелы... Но я писал уже об этом. | |
|
|
|
|
|
|
|
для: Trianon
(20.08.2008 в 13:14)
| | Подскажите, хоть какие нотайсы, у меня все ровоно, не знаю на что и думать.
Что я зря пыхтел? | |
|
|
|
|
 20.4 Кб |
|
|
для: Николай2357
(20.08.2008 в 14:46)
| | Пожалуйста. См аттач ====> | |
|
|
|
|
|
|
|
для: Trianon
(20.08.2008 в 14:59)
| | А что сие значит? Почему у меня не ругается? Не так настроено? | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 15:15)
| | > Не так настроено?
Да. У вас и у Trianon похоже по-разному выставлен error_reporting | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 12:10)
| | Нашел ошибку, вчера засыпал уже, не ту версию отправил.
Нужно убрать 10-ю и 98-ю строки, а 99-ю переписать на
<?
$link_name=str_replace("&quot;","\"",$link);
|
| |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 13:21)
| | Еще одну неприятность увидел, но это так, декорация:
<?
if($count_var==2||$count_var==3||$count_var==4){
$varsh_c="раза";
}
else
{
$varsh_c="раз";
}
if(preg_match("/[1][\d]/",$visits))
{
$varsh_c="раз";
}
|
| |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 03:10)
| | Я не понимаю:
0) Зачем Вы по-разному обрабатываете GET и POST. Это видно отсюда:
<?php
if($_GET['go']||$_GET['name']){
$name = $_POST['name'];
//Обработка входных даных
if($_GET['name']){
?>
|
1) Зачем Вы делаете это:
<?php
$name = stripslashes(htmlspecialchars($_GET['name']));
?>
|
А именно я не понимаю зачем Вы применяете htmlspecialchars() (выводить эту строку собрались?) и урезаете количество бекслешей с помощью stripslashes() (с какой целью Вы их удаляете?)
2) $name = rawurldecode($name) - лишняя строка. PHP сам URL-декодирует входящие данные. Отсюда и проблемы с "%25".
3) Это ... вообще зачем?
<?php
$name=str_replace("&amp;","&",$name);
$name=str_replace("&quot;","\"",$name);
$name=str_replace("&lt;","<",$name);
$name=str_replace("&gt;",">",$name);
?>
|
4) А это зачем?
<?php
$name=str_replace("\\","\\\\",$name);
?>
|
Я не понимаю...
5)
<?php
$link_name=str_replace("&amp;","&",$link);
$link_name=str_replace("&quot;","\"",$link_name);
?>
|
Вы этим разрушаете отображамое имя, Вам так не кажется?
6)
<?php
$form="<form action=".$PHP_SELF."?go=1 method=post ><input type=text name=name ><input type=submit name=in value=Войти ></form>
<form action=".$PHP_SELF."?go=1 method=get ><input type=text name=name ><input name=sel type=submit value=Найти ></form>";
?>
|
Вы вроде раньше использовали $_SERVER['PHP_SELF'], а теперь $PHP_SELF. Зачем перешли на неправильный вариант?
Я бы Вам посоветовал отключить magic_quotes_gpc (это можно сделать через .htaccess) и перепроверить скрипт. | |
|
|
|
|
|
|
|
для: BinLaden
(20.08.2008 в 14:57)
| | <Зачем Вы по-разному обрабатываете GET и POST.
Ну я решил таким образом бороться с F5. Переменная $_GET['go'] есть только когда отправляется форма:
<form action=".$PHP_SELF."?go=1 method=post >
|
а при редерикте есть $_GET['name'], которая формируется из $_POST['name'] при входе из этой формы. Дальше запрос один, а обработка разная для GET и для POST.
По этому я и делаю вот это:
>1) Зачем Вы делаете это:
<?php
$name = stripslashes(htmlspecialchars($_GET['name']));
?>
| и дальше
>3) Это ... вообще зачем?
<?php
$name=str_replace("&amp;","&",$name);
$name=str_replace("&quot;","\"",$name);
$name=str_replace("&lt;","<",$name);
$name=str_replace("&gt;",">",$name);
?>
|
>4) А это зачем?
<?php
$name=str_replace("\\","\\\\",$name);
?>
|
иначе GET переменная выводится некорректно.
Что касается
>2) $name = rawurldecode($name) - лишняя строка. PHP сам URL-декодирует входящие данные. Отсюда и проблемы с "%25".
Вы обсолютно правы, я исправил это двумя постами выше. Там еще кое что исправлено.
Дальше:
>4) А это зачем?
<?php
$name=str_replace("\\","\\\\",$name);
?>
|
это для того, чтобы правильно отображались бэкслэши. иначе их получается не то количество.
>Я не понимаю...
5)
<?php
$link_name=str_replace("&amp;","&",$link);
$link_name=str_replace("&quot;","\"",$link_name);
?>
|
Вы этим разрушаете отображамое имя, Вам так не кажется?
Тут как раз наоборот, посмотрите, пожалуйста на переменные. Они используются для вывода в HTML, подругому их просто не будет видно.
>6)
<?php
$form="<form action=".$PHP_SELF."?go=1 method=post ><input type=text name=name ><input type=submit name=in value=Войти ></form>
<form action=".$PHP_SELF."?go=1 method=get ><input type=text name=name ><input name=sel type=submit value=Найти ></form>";
?>
|
Вы вроде раньше использовали $_SERVER['PHP_SELF'], а теперь $PHP_SELF. Зачем перешли на неправильный вариант?
Тут я действительно намудрил, увлекся.
>Я бы Вам посоветовал отключить magic_quotes_gpc (это можно сделать через .htaccess) и перепроверить скрипт.
Отключено у меня, разумеется. Просто скрипт не только для меня писался, мало ли...
Скрипт я исправил и перепроверил. Вот тут можно посмотреть:
http://test.inkz.ru
От себя.
Наверное я намудрил лишнего, но ставил перед собой такую задачу: сделать скрипт как можно компактней и с минимальным количеством запросов к БД. Поэтому данные на вывод брал из переменных окружения, а не из базы. Если имена обрабатываются корректно (а это условие задачи), то незачем лишний раз туда лазить, ведь меняется шило на мыло. Судя по предыдущим ответам на задачу результата я достиг. Если убрать "прически" и всякие прибаутки, то скрипт получился по моему самым маленьким пока. И запросов всего 5 (не считая коннекта) Из них "однозапросно", да простит меня учительница русского языка, работают максимум 3. Кроме того, ставилась задача отобразить обсолютно любые символы. На пробелах я споткнулся, но судя по тому, что успел увидеть из ответов, продвинулся дальше всех. По крайней мере пробел в таблице на выводе отображается ссылкой, его можно пощупать. Я пишу это не для хвастовства, а как раз наоборот, для того, чтобы меня разубедили и научили писать скрипты правильно. Работать то он работает, но вот Trianon написал, что нотайсов куча. Где-то я чего-то важное упускаю.
Спасибо.
PS Можно еще нагло попросить дать общую оценку, на что следует обратить внимание при написании скриптов.
Опять спасибо. | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 16:28)
| | Где последний текст скрипта? | |
|
|
|
|
|
|
|
для: Trianon
(20.08.2008 в 16:54)
| | Вот, только тут почти ничего не изменилось, если учесть мои, описанные выше поправки.
<?php
//Задачу решал для себя, поэтому использовал свое подключение
include "dbconnect.php";
//Это от флуда предосторожности
if($_GET['go']||$_GET['name']){
$name = $_POST['name']; //Если запрос из первой формы, если из второй - переменная перезапишется на GET
//Обработка входных даных
if($_GET['name']){
$name = stripslashes(htmlspecialchars($_GET['name'])); //Это для вывода в строку "Здрасти..."
//$name = rawurldecode($name);
$name=str_replace("&amp;","&",$name);
$name=str_replace("&quot;","\"",$name);
$name=str_replace("&lt;","<",$name);
$name=str_replace("&gt;",">",$name);
$name=str_replace("&nbsp;"," ",$name);
//Подсчет символов, пока всяких слэшей не навтыкалось
$count_name=strlen($name);
$name=str_replace("\\","\\\\",$name);
}
//Это так, не люблю ошибки, потому что сам много их делаю
$count=strlen($count_name)-1;
$count_var=substr($count_name, $count);
if($count_var==1){
$varsh="символ";
}
if($count_var==2 || $count_var==3||$count_var==4){
$varsh="символа";
}
if($count_var==0 || preg_match("/[5-9]/",$count_name) || preg_match("/[1][\d]/",$count_name)){
$varsh="символов";
}
//Обработка данных для запроса
if (get_magic_quotes_gpc()) $name = stripslashes($name);
$name_db = mysql_real_escape_string($name); //Здесь другая переменная, для БД
$name = htmlspecialchars($name); //Это для вывода POST запроса
//Поиск имени.
$query = mysql_query("SELECT visits FROM guests WHERE guestname='".$name_db."'") or die ('Error: 1' . mysql_error());
$userdata = mysql_fetch_assoc($query);
$visits = $userdata['visits'];
//Это опять прическа
$count=strlen($visits)-1;
$count_var=substr($visits, $count);
if($count_var==2||$count_var==3||$count_var==4){
$varsh_c="раза";
}
else
{
$varsh_c="раз";
}
if(preg_match("/[1][\d]/",$visits))
{
$varsh_c="раз";
}
//Если вход
if($_POST['in']){
if(!$visits){//Если нет имени в БД, добавляю строчку
$visits=1;
mysql_query("INSERT INTO guests SET guestname='".$name_db."', visits='".$visits."'") or die ('Error: 2' . mysql_error());
}
else
{//Если есть, плюсую визит
$visits++;
mysql_query("UPDATE guests SET visits ='".$visits."' WHERE guestname='".$name_db."'") or die ('Error: 3' . mysql_error());
$mess_d="На юзьверя под ником <b>".$name."</b> уже заведено досье. ";//Не примите за чистую монету
}
//Война с F5
if($_POST['name']){ //Эдесь данные кодируются для редерикта, поэтому и все эти str_replace выше
$name= rawurlencode($name);
header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']."?new=1&name=$name");
exit;
}
}
//Формирую сообщение
if($_GET['new'])$mess=$mess_d."Таки здрасти <b>".$name."</b>! Мы знаем, что в Вашем имени ".$count_name." ".$varsh.", и Вы у нас ".$visits."-й раз";
//Если поиск введенного имени
if($_GET['sel']||$_GET['name']&&!$_GET['new']){
if(!$visits){
$mess="Не, <b>".$name."</b> пока не числится, зайдите позже! Хотя мы знаем, что в его имени ".$count_name." ".$varsh ;
}
else
{
$mess="Гражданин <b>".$name."</b> побывал у нас ".$visits." ".$varsh_c.". Поэтому мы знаем, что в его имени ".$count_name." ".$varsh;
$mysql=" WHERE guestname='".$name_db."'";
$all="<a href='?go=1'>Показать всех</a>";
}
}
}
//Список соискателей
$query = mysql_query("SELECT guestname, visits, id FROM guests $mysql") or die ('Error: 4' . mysql_error());
$count=mysql_num_rows($query);
if($count==0)$mess="Пусто.";
for($i=0;$i<$count; $i++){
$link = htmlspecialchars(mysql_result($query, $i, "guestname")); //Тут переменные делятся для HTML, JS и href
$link_name=str_replace("&quot;","\"",$link);
$link_name=preg_replace("#[\s]{1}#"," ",$link_name);
$link_del=str_replace("\\","\\\\",$link);
$link_del=str_replace("'","\'",$link_del);
$href_name = rawurlencode($link_name);
$tr.="<tr><td style='width:20px'>".($i+1)."</td><td><a href='".$PHP_SELF."?name=".$href_name."'>".$link_name."</a></td>
<td>".mysql_result($query, $i, "visits")."</td>
<td><a href='#' onclick=\"javascript:Delete('".mysql_result($query, $i, "id")."','".$link_del."')\">dell</a></td></tr>";
}
//Таблица
$table="<table><tr><td style='width:20px'><b>№</b></td><td><b>Имя</b></td><td><b>Визиты</b></td><td><b>Удалить</b></td></tr>".$tr."</table>";
//Удаление строчки
if($_GET['delete']){
mysql_query("DELETE FROM guests WHERE id = '".intval($_GET['id'])."'") or die ('Error: 5' . mysql_error());
header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']."?go=1");
exit;
}
//Формы
$form="<form action=".$PHP_SELF."?go=1 method=post ><input type=text name=name ><input type=submit name=in value=Войти ></form>
<form action=".$PHP_SELF."?go=1 method=get ><input type=text name=name ><input name=sel type=submit value=Найти ></form>";
?>
<html>
<head>
<style>
body{
background-color:#FFFFCC;
}
table {
border-collapse: collapse;
}
td{
border: 1px solid;
width:100px;
text-align:center;
color:#666699;
background-color:#e6e6e6;
}
</style>
<script type="text/javascript">
function Delete(id, name){
confirm("Вы действительно хотите навсегда удалить "+name+"?")?
location.href="<? echo $PHP_SELF ?>?delete=1&id="+id : alert("А зря.");
}
</script>
<meta http-equiv="Выберите расширение для паковки" content="text/html; charset=windows-1251" /><meta http-equiv="Выберите расширение для паковки" content="text/html; charset=windows-1251" /></head>
<body>
<?
echo "<span style='color:red'>".$mess."</span>";
?>
<hr>
<?
echo $all.$form.$table;
?>
</body>
</html>
|
| |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 17:00)
| | Нотайсы никуда не исчезли.
Код пестрит совершенно ненужными преобразованиями, расставленными как попало.
Как результат - ошибки в обработке.
к примеру, добавить а затем поискать имя & - находится совсем другое имя.
добавить имя 0 не удается вообще. При добавлении руками в таблицу его невозможно найти.
Незачет, короче.
UPD.
неудача Ваша вытекает в первую очередь из того , что Вы не хотите понимать, какие функции в каких случаях и для каких целей требется применять.
Начинается это непонимание буквально в первых строках
if($_GET['name']){
$name = stripslashes(htmlspecialchars($_GET['name']));
|
Вот здесь сразу три ошибки:
1. Обращение к элементу массива $_GET['name'] который запросто может отсутствовать .
2. применение htmlspecialchars в отсутствии необходимости перехода от текста к гипертексту
3. применение stripslashes а) без условия и б) не к входному параметру скрипта.
И так далее... | |
|
|
|
|
|
|
|
для: Trianon
(20.08.2008 в 17:24)
| | Ну я вообще то не для зачета писал, а как раз для того, чтобы научиться. Ноль, кстати, добавляется.
>
if($_GET['name']){
$name = stripslashes(htmlspecialchars($_GET['name']));
|
правильно так?
$name= $_GET['name'];
if($name){
$name = stripslashes(htmlspecialchars($name));
|
>2. применение htmlspecialchars в отсутствии необходимости перехода от текста к гипертексту
есть необходимость, помоему... Как же написать "Мы приветствуем Вас <Trianon>!" и тому подобное?
>3. применение stripslashes а) без условия и б) не к входному параметру скрипта.
что есть, то есть. С перепугу наверное. Учту на будущее. Спасибо.
А далее не затруднит? Хорошее пособие для начинающих может получиться. Не только для меня... | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 17:58)
| | > Как же написать "Мы приветствуем Вас <Trianon>!"
Вы там ничего не пишите. По крайней мере в этом куске кода. | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 17:58)
| | >
опять.
это надо писать либо явно
if(isset($_GET['name']) $name = $_GET['name'];
else $name = null;
|
либо неявно, но с локальной блокировкой диагностик.
>>2. применение htmlspecialchars в отсутствии необходимости перехода от текста к гипертексту
>есть необходимость, помоему...
нету. Потому, что в этом конкретном месте Вы вывод гипертекста не делаете.
а строка уже будет преобразована. Еще одно преобразование поверх - и первое окажется необратимым.
>>3. применение stripslashes а) без условия и б) не к входному параметру скрипта.
>что есть, то есть. С перепугу наверное. Учту на будущее. Спасибо.
>
>А далее не затруднит? Хорошее пособие для начинающих может получиться. Не только для меня...
А Вас не затруднит сперва изучить вот это решение?
http://softtime.ru/forum/read.php?id_forum=7&id_theme=38424 | |
|
|
|
|
|
|
|
для: Trianon
(20.08.2008 в 18:51)
| | >опять.
это надо писать либо явно
Спасибо, дошло. Я просто много нахватался "верхушек", пытаюсь учиться у других. Видел много раз свой вариант и решил, что это оптимально. Так же как и с переменными в двойных кавычках и пр... Буду знать.
>нету. Потому, что в этом конкретном месте Вы вывод гипертекста не делаете.
а строка уже будет преобразована. Еще одно преобразование поверх - и первое окажется необратимым.
Вынужден не согласиться. Преобразование необходимо именно в этом месте, то есть в блоке
if(isset($_GET['name']){
........
| так как оно применяется для $_GET['name'], соответственно для вывода имени в приветствие и запрос. Напротив, при отсутствии этой переменной запрос формируется из $_POST['name'] , без преобразований. Действительно, дальше есть еще одно, и обратное невозможно, но оно уже и не нужно. Наверняка такой подход не есть грамотный, но в данном контексте оправдан.
>А Вас не затруднит сперва изучить вот это решение?
Вы думаете я не умею читать? Я изучил его с ног до головы, прекрасно понимая, чье оно. Потом закрыл и не подглядывал. И пошел другим путем. Дело в том, что практическое решение данной задачи меня не интересует, а интересует меня различные подходы, и более всего (чeго кревить) "грамотность" моих каракулей. Тупо списать - проку мало...
Спасибо за поддержку.
PS Я не успокоюсь, пока в божеский вид не приведу свой скрипт, это будет полезней. | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 19:46)
| | Понятно... Вы предпочитаете, чтобы Вас додавливали контрпримерами.
Ок.
Вот приходит новый user и вводит в качестве имени &amp; из девяти символов.
Ваш скрипт в строке $name=str_replace("&amp;","&",$name); меняет его на один символ & .
В таком виде он и попадает в БД.
Исправляйте. | |
|
|
|
|
|
|
|
для: Trianon
(20.08.2008 в 20:36)
| | Да это то просто:
$name=preg_replace("#&(.*?)#i","&$1",$name);
|
только я еще раз повторюсь, решить эту задачу на 100% наверное нельзя, да и не к чему это. В Вашем скрипте тоже не все гладко. Попробуйте набрать тот же пресловутый амперсанд с пробелом впереди. И где же тот пробел?
Главное вынести максимум пользы. Я вот допустим в смятении, не могу прочитать 0 из GET запроса. С теми же пробелами непонятно, они то плюсом кодируются, то %20. Вот это важно. Сделать еще один запрос в БД не трудно, но ведь в жизни придется решать и такие задачи, где это не поможет... | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 22:44)
| | > Да это то просто:
На деле покажите? Имею ввиду запихните это в скрипт, который по ссылке http://test.inkz.ru/, чтобы все убедились, что это "просто".
Но сам факт того, что Вы предлагаете такое решение только говорит о том, что Вы еще ничего не поняли...:(
> Попробуйте набрать тот же пресловутый амперсанд с пробелом впереди. И где же тот пробел?
Он никуда не девался. Разве MySQL в конце строки при поиске пробелы подчищает и если в базе данных строка
, то её можно будет найти хоть по запросу , хоть по
Хотя тип поля и TINYTEXT, а не (VAR)CHAR какой-нибудь. | |
|
|
|
|
|
|
|
для: BinLaden
(20.08.2008 в 23:10)
| | Ну вот, и Вы туда же. Не умею я наверное грамотно изъясняться.
>На деле покажите? Имею ввиду запихните это в скрипт, который по
Да пожалуйста, смотрите. Там далеко не все работает, но это работает точно. Кроме того, если уж пошла такая пьянка, в условиях четко сказано, использовать абсолютно любые символы. То есть и пробел. Как я понимаю, юзер по имени "два пробела амперсанд", это не юзер "один пробел амперсанд". У меня это тоже работает. Сделал это не для решения задачи, а просто показать, что подходы бывают разными.
>Но сам факт того, что Вы предлагаете такое решение только говорит о том, что Вы еще ничего не поняли...:(
Я не пытаюсь решить эту задачу на 100%!!!!! Я хочу выяснить то, чего до сих пор не знал.
Не знал и не знаю очень многого, и это проблема. А не то, что у меня подход другой. Лучше расскажите, как из GET прочитать 0. Спать не буду, пока не придумаю.
Спасибо. | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 23:59)
| | Давайте постараемся убрать лишнии эмоции.
Про пробелы спросили Вы - я Вам ответил, но Вы почему-то этим раздражены.
> Сделал это не для решения задачи, а просто показать, что подходы бывают разными
Спасибо, но, мягко говоря, это не говорит о том, что раз такие подходы существуют, то их надо показывать :) От них надо избавляться.
> Я хочу выяснить то, чего до сих пор не знал.
Как это не покажется странным, но для того, чтобы что-то новое выяснить придётся решить задачу. Правильно решить. А не пытаться обмануть себя.
> Лучше расскажите, как из GET прочитать 0. Спать не буду, пока не придумаю.
<?php
$val = 0;
if( $val != '' )
{
# ....
}
?>
|
| |
|
|
|
|
|
|
|
для: BinLaden
(21.08.2008 в 00:24)
| | >Про пробелы спросили Вы - я Вам ответил, но Вы почему-то этим раздражены.
Да нет, что Вы, я злюсь на себя, что объяснить не могу.
>От них надо избавляться.
Вот опять к примеру. Я про подход к постановке вопроса, а не к решению задачи. Вообще то, если вспомните, вся эта эпопея началась из-за MySQL иньекций. Мне нужно эту проблему решить раз и навсегда. А не то, как амперсанд лучше вытащить, GET запросом или из базы. Это не принципиально. Задачу эту можно решить, только зачем? Ведь важен не результат, он практического применения вряд ли найдет. А вот передача данных - это важно.
За ноль спасибо, гениальное - как просто! И еще про кавычки функция мне очень понравилась. А скрипт я заставлю работать, дело принципа. Не сегодня, конечно, и так второй день на смарку. | |
|
|
|
|
|
|
|
для: Николай2357
(21.08.2008 в 01:07)
| | А это все едино: есть текст и мы должны его обработать так, чтобы с ним ничего не произошло в результате: не добавилось лишнего и наоборот - ничего не потерялось. Ведь htmlspecialchars() и mysql_escape_string() по сути делают одно и то же: экранируют спец. символы для правильной вставки текста на страницу/в запрос Все "гениально и просто": и не требует иных подходов, которые могут допустить взлом | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 16:28)
| | > По этому я и делаю вот это:
Как ловко Вы увернулись от ответа зачем Вы делаете то, то и вот то. Я Вас не спрашиваю почему Вы в принципе не делаете то же самое с POST-данными. Я Вас спрашиваю зачем Вы вообще применяете в данном случае htmlspecialchars(), stripslashes() и прочее.
> иначе GET переменная выводится некорректно.
Вы методом тыка подводите переменную к такому виду, чтобы она "выводилась правильно".
> то для того, чтобы правильно отображались бэкслэши. иначе их получается не то количество.
С какой стати их не то количество? На то должны быть причины.
> Тут как раз наоборот, посмотрите, пожалуйста на переменные. Они используются для вывода в HTML, подругому их просто не будет видно.
Я внимательно посмотрел на то, что делает Ваш код с данными из таблички Trianon'а. И мне это не понравилось. Хотя сейчас Вы что-то явно поменяли...
> Отключено у меня, разумеется
Я Ваш скрипт тестировал при включенном magic_quotes_gpc и данные в большинстве случаев действительно отображались так, как надо. Отключив, уже данные типа "\'" искажались.
Поэтому я сомневаюсь.
Добавьте в конец скрипта echo get_magic_quotes_gpc() ? "MQ Включено" : "MQ Отключено"; | |
|
|
|
|
|
|
|
для: BinLaden
(20.08.2008 в 17:03)
| | >Как ловко Вы увернулись от ответа зачем Вы делаете то, то и вот то. Я Вас не спрашиваю почему Вы в принципе не делаете то же самое с POST-данными. Я Вас спрашиваю зачем Вы вообще применяете в данном случае htmlspecialchars(), stripslashes() и прочее.
Да нет, и не думал уватачиваться. Просто объяснять наверное не умею. Я написал выше, что на вывод в строку "Здрасти..." данные беру из переменных окружения. Поэтому и такая карусель. htmlspecialchars(), stripslashes() соответственно применяю для того, чтобы было "Здрасти <Mac'cormic>...", а не что попало.
> иначе GET переменная выводится некорректно.
Вы методом тыка подводите переменную к такому виду, чтобы она "выводилась правильно".
Наверное, просто других методов пока не знаю. Подскажите...
> то для того, чтобы правильно отображались бэкслэши. иначе их получается не то количество.
С какой стати их не то количество? На то должны быть причины.
Разумеется есть, раз не то количество. Другой вопрос, знаю ли я их? Нет. Но победить как то надо. Буду искать причины.
> Тут как раз наоборот, посмотрите, пожалуйста на переменные. Они используются для вывода в HTML, подругому их просто не будет видно.
Я внимательно посмотрел на то, что делает Ваш код с данными из таблички Trianon'а. И мне это не понравилось. Хотя сейчас Вы что-то явно поменяли...
Поменял только то, что описывал, сравните сами.
Добавьте в конец скрипта echo get_magic_quotes_gpc() ? "MQ Включено" : "MQ Отключено";
Дома точно отключено, на хостинге сейчас проверю.
Спасибо.
Да, действительно, на хостинге были включены. Отключил - пока изменений не вижу. | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 17:19)
| | Есть такая вещь, как magic_quotes_gpc. Этот режим нагло экранирует входящие данные для SQL-запросов, да и то не всех СУБД. Это медвежья услуга называется. Поэтому надо применять stripslashes() только при включенном режиме magic_quotes_gpc. Можно это сделать быстро:
<?php
function rec_stripslashes($mixed)
{
if( is_array($mixed) )
{
return array_map('rec_stripslashes', $mixed);
}
else
{
return stripslashes($mixed);
}
}
if( get_magic_quotes_gpc() )
{
$_GET = rec_stripslashes( $_GET );
$_POST = rec_stripslashes( $_POST );
}
?>
|
Далее никаких stripslashes() применимо к входящим данным вообще говоря быть не должно.
htmlspecialchars() применяется непосредственно перед выводом на HTML-страницу какого-то простого текста (plain).
> переменных окружени
Переменные окружения вообще-то несколько другие переменные. Они находятся в $_ENV и $_SERVER. | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 17:19)
| | > Отключил - пока изменений не вижу.
Введите имя "\'" (бекслеш и апостроф). | |
|
|
|
|
|
|
|
для: Николай2357
(20.08.2008 в 03:10)
| | Ну вот, так вроде бы работает. Правда через сессию, но мне это тоже нужно знать. Посмотрите пожалуйста.
<?
include "dbconnect.php";
session_start();
function rec_stripslashes($mixed)
{
if( is_array($mixed) )
{
return array_map('rec_stripslashes', $mixed);
}
else
{
return stripslashes($mixed);
}
}
if( get_magic_quotes_gpc() )
{
$_GET = rec_stripslashes( $_GET );
$_POST = rec_stripslashes( $_POST );
}
$post_name = @$_POST['name'];
$in = @$_POST['in'];
$go = @$_GET['go'];
$new = @$_GET['new'];
$sel = @$_GET['sel'];
$hello = @$_GET['hello'];
$get_name_sel = @$_GET['getname'];
$tabsel = @$_GET['tabsel'];
$del = @$_GET['delete'];
$id = intval(@$_GET['id']);
$get_name = 0;
$get_val = @$_GET['name'];
if( $get_val != null )
{
$get_name = @$_GET['name'];
}
else
{
$get_name = null;
}
$host = $_SERVER['HTTP_HOST'];
$self = $_SERVER['PHP_SELF'];
if( $go != null && $post_name != null )
{
$_SESSION['name'] = $post_name;
header("Location: http://".$host.$self."?go=1&new=1");
exit;
}
elseif( $go != null && $get_name != null)
{
$_SESSION['name'] = $get_name;
header("Location: http://".$host.$self."?go=1&tabsel=".$tabsel);
exit;
}
elseif( $get_name_sel != null )
{
$_SESSION['name'] = $get_name_sel;
header("Location: http://".$host.$self."?go=1&sel=".$sel);
exit;
}
if( $go != null || $sel != null )
{
$name = @$_SESSION['name'];
if( $tabsel != null || $hello != null )
{
$name = html_entity_decode($name);
}
$count_name=strlen($name);
$count=strlen($count_name)-1;
$count_var=substr($count_name, $count);
if($count_var==1)
{
$varsh="символ";
}
if($count_var==2 || $count_var==3||$count_var==4)
{
$varsh="символа";
}
if($count_var==0 || preg_match("/[5-9]/",$count_name) || preg_match("/[1][\d]/",$count_name))
{
$varsh="символов";
}
$name_db = mysql_real_escape_string($name);
$name = htmlspecialchars($name);
$query = mysql_query("SELECT visits FROM guests WHERE guestname='".$name_db."'")
or die ('Error: 1' . mysql_error());
$userdata = mysql_fetch_assoc($query);
$visits = $userdata['visits'];
if( $visits != null )
{
$count=strlen($visits)-1;
$count_var=substr($visits, $count);
if($count_var==2||$count_var==3||$count_var==4){
$varsh_c="раза";
}
else
{
$varsh_c="раз";
}
if(preg_match("/[1][\d]/",$visits))
{
$varsh_c="раз";
}
}
if( $new != null )
{
if( $visits == null )
{
$visits=1;
mysql_query("INSERT INTO guests SET guestname='".$name_db."', visits='".$visits."'")
or die ('Error: 2' . mysql_error());
}
else
{
$visits++;
mysql_query("UPDATE guests SET visits ='".$visits."' WHERE guestname='".$name_db."'")
or die ('Error: 3' . mysql_error());
}
header("Location: http://".$host.$self."?go=1&hello=1");
exit;
}
if( $hello != null )
{
$mess=$mess_d."Таки здрасти <b>".$name."</b>!<br>
Мы знаем, что в Вашем имени ".$count_name." ".$varsh.", и Вы у нас ".$visits."-й раз";
}
if( $visits == null )
{
$mess="Не, <b>".$name."</b> пока не числится, зайдите позже!
Хотя мы знаем, что в его имени ".$count_name." ".$varsh ;
}
elseif( $hello == null )
{
$mess="Гражданин <b>".$name."</b><br> побывал у нас ".$visits." ".$varsh_c.".
Поэтому мы знаем, что в его имени ".$count_name." ".$varsh;
$mysql=" WHERE guestname='".$name_db."'";
$all="<a href='".$self."'>Показать всех</a>";
}
}
elseif( $del != null )
{
mysql_query("DELETE FROM guests WHERE id = '".$id."'")
or die ('Error: 4' . mysql_error());
header("Location: http://".$host.$self);
exit;
}
$query = mysql_query("SELECT guestname, visits, id FROM guests $mysql ORDER BY id DESC ")
or die ('Error: 5' . mysql_error());
$count=mysql_num_rows($query);
if($count==0)
{
$mess="Пусто.";
}
for($i=0;$i<$count; $i++)
{
$link = mysql_result($query, $i, "guestname");
$link = htmlspecialchars($link);
$link_name = preg_replace("#[\s]{1}#"," ",$link);
$link_del = addslashes($link);
$href_name = rawurlencode($link);
$id = mysql_result($query, $i, "id");
$tr.="<tr><td style='width:20px'>".($i+1)."</td>
<td><a href='".$self."?name=".$href_name."&go=1&tabsel=1'>".$link_name."</a></td>
<td>".mysql_result($query, $i, "visits")."</td>
<td><a href='#' onclick=\"javascript:Delete('".$id."','".$link_del."')\">
dell</a></td></tr>";
}
$table="<table>
<tr>
<td style='width:20px'><b>№</b>
</td>
<td style='width:400px'><b>Имя</b>
</td>
<td><b>Визиты</b></td>
<td><b>Удалить</b></td>
</tr>".$tr."</table>";
$form="<form action=".$self."?go=1 method=post ><input type=text size=80 name=name >
<input type=submit name=in value=Войти ></form>
<form action=".$self." method=get ><input size=80 type=text name=getname >
<input name=sel type=submit value=Найти ></form>";
?>
<html>
<head>
<style>
body{
background-color:#FFFFCC;
}
table {
border-collapse: collapse;
}
td{
border: 1px solid;
width:100px;
text-align:center;
color:#666699;
background-color:#e6e6e6;
}
</style>
<script type="text/javascript">
function Delete(id, name){
confirm("Вы действительно хотите навсегда удалить "+name+"?")?
location.href="<? echo $PHP_SELF ?>?delete=1&id="+id : alert("А зря.");
}
</script>
<meta http-equiv="Выберите расширение для паковки" content="text/html; charset=windows-1251"></head>
<body>
<?
echo "<span style='color:red'>".$mess."</span>";
?>
<hr>
<?
echo $all.$form.$table;
echo get_magic_quotes_gpc() ? "MQ Включено" : "MQ Отключено<br>";
?>
I 100% know why O"Relly & partners doesn''t eat Mc''donalds Gamburgers\\Cheeseburgers<br />
Mc''robbins'<br />
O"Relly <br />
Jensen & partners<br />
total %25 of sales <br />
&amp; <br />
&<br />
characterictics of volt&amp; any other graphs <br />
Guest004
</body>
</html>
|
PS Комментировать не стал, и так бумаги попортил.
Спасибо. | |
|
|
|
|
|
|
|
для: Николай2357
(21.08.2008 в 13:36)
| | по-моему, во всех сравнениях, подобных этому Вы имели в виду на самом деле
В остальном таки да. Прогресс имеет место быть. | |
|
|
|
|
|
|
|
для: Trianon
(21.08.2008 в 15:27)
| | Спасибо. Подскажите еще, пожалуйста,
1)Когда использовать === (строго равно)?
2)Нужно ли в конце подобных скриптов session_destroy ?
3) И самый главный вопрос, из за которого я старался: теперь можно спать спокойно на счет иньекций?
Спасибо. | |
|
|
|
|
|
|
|
для: Николай2357
(21.08.2008 в 15:48)
| | $a=false;
$b=0;
$a==$b будет истина
$a===$b будет ложь
почувствуй разницу | |
|
|
|
|
|
|
|
для: GeorgeIV
(21.08.2008 в 16:38)
| | Почувствовал, спасибо.
А главного я так и не понял. Мне в PHP еще пахать и пахать, куда уж хакерские методы изучить... Только видел я примеры иньекций, где нет ни одной кавычки. От них это тоже спасает? И с сессией не понятно. Как то раз выключил интернет не закрыв страницу, а на следующий день включил - сессия живая. Это как так? | |
|
|
|
|