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

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

 

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

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

тема: Ответ на задачу №21
 
 автор: Николай2357   (20.08.2008 в 03:10)   письмо автору
 
 

Ответ 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;amp;","&",$name); 
$name=str_replace("&amp;quot;","\"",$name); 
$name=str_replace("&amp;lt;","<",$name);
$name=str_replace("&amp;gt;",">",$name);
$name=str_replace("&amp;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==|| $count_var==3||$count_var==4){ 
$varsh="символа"
}
if(
$count_var==|| 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']){ 
$namerawurlencode($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;amp;","&",$link); 
$link_name=str_replace("&amp;quot;","\"",$link_name);
$link_name=preg_replace("#[\s]{1}#","&nbsp;",$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 Одну проблему решить не смог: отображение пробелов (когда одни пробелы). Заменить на _ нельзя, получится нижнее подчеркивание,а не пробел.

  Ответить  
 
 автор: Trianon   (20.08.2008 в 10:28)   письмо автору
 
   для: Николай2357   (20.08.2008 в 03:10)
 

В ветке с обсуждением задачи есть табличка тестовых имен.

(01.06.2007 в 21:41)

Сколько из них вы проверили?
Сдается мне - ни одного.

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 11:45)   письмо автору
 
   для: Trianon   (20.08.2008 в 10:28)
 

Да, ни одного не проверил. По этой ссылке тема отсутствует.

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 12:10)   письмо автору
 
   для: Николай2357   (20.08.2008 в 11:45)
 

Извиняюсь, наверное форум проглючил, писал большими красными буквами, что темы нет. Сейчас посмотрел еще раз, сработало.
Проверил все, есть один "косячок", не отображает комбинацию символов %25. Попробую что-нибудь придумать.

  Ответить  
 
 автор: Trianon   (20.08.2008 в 13:14)   письмо автору
 
   для: Николай2357   (20.08.2008 в 12:10)
 

А для остальных имен правильно считает длину и корректно укладывает имена в таблицу?

Код Ваш у меня выдает нотайсы. Так что...

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 13:23)   письмо автору
 
   для: Trianon   (20.08.2008 в 13:14)
 

Я совсем незнаком с методами тестирования, так что все делаю вручную. Исправленный скрипт имена из тестовой таблицы обрабатывает корректно. Подскажите, что не так?
На счет длинны - он пробелы за символ считает, но в задании о всех символах говорилось. Правда когда одни пробелы... Но я писал уже об этом.

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 14:46)   письмо автору
 
   для: Trianon   (20.08.2008 в 13:14)
 

Подскажите, хоть какие нотайсы, у меня все ровоно, не знаю на что и думать.
Что я зря пыхтел?

  Ответить  
 
 автор: Trianon   (20.08.2008 в 14:59)   письмо автору
20.4 Кб
 
   для: Николай2357   (20.08.2008 в 14:46)
 

Пожалуйста. См аттач ====>

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 15:15)   письмо автору
 
   для: Trianon   (20.08.2008 в 14:59)
 

А что сие значит? Почему у меня не ругается? Не так настроено?

  Ответить  
 
 автор: BinLaden   (20.08.2008 в 16:10)   письмо автору
 
   для: Николай2357   (20.08.2008 в 15:15)
 

> Не так настроено?

Да. У вас и у Trianon похоже по-разному выставлен error_reporting

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 13:21)   письмо автору
 
   для: Николай2357   (20.08.2008 в 12:10)
 

Нашел ошибку, вчера засыпал уже, не ту версию отправил.
Нужно убрать 10-ю и 98-ю строки, а 99-ю переписать на
<?
$link_name
=str_replace("&amp;quot;","\"",$link);

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 14:00)   письмо автору
 
   для: Николай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="раз";  
}

  Ответить  
 
 автор: BinLaden   (20.08.2008 в 14:57)   письмо автору
 
   для: Николай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;amp;","&",$name);  
$name=str_replace("&amp;quot;","\"",$name);  
$name=str_replace("&amp;lt;","<",$name); 
$name=str_replace("&amp;gt;",">",$name);
?>


4) А это зачем?

<?php
$name
=str_replace("\\","\\\\",$name);
?>


Я не понимаю...

5)
<?php
$link_name
=str_replace("&amp;amp;","&",$link);  
$link_name=str_replace("&amp;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) и перепроверить скрипт.

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 16:28)   письмо автору
 
   для: 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;amp;","&",$name);   
$name=str_replace("&amp;quot;","\"",$name);   
$name=str_replace("&amp;lt;","<",$name);  
$name=str_replace("&amp;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;amp;","&",$link);   
$link_name=str_replace("&amp;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 Можно еще нагло попросить дать общую оценку, на что следует обратить внимание при написании скриптов.
Опять спасибо.

  Ответить  
 
 автор: Trianon   (20.08.2008 в 16:54)   письмо автору
 
   для: Николай2357   (20.08.2008 в 16:28)
 

Где последний текст скрипта?

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 17:00)   письмо автору
 
   для: 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;amp;","&",$name);  
$name=str_replace("&amp;quot;","\"",$name);  
$name=str_replace("&amp;lt;","<",$name); 
$name=str_replace("&amp;gt;",">",$name); 
$name=str_replace("&amp;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==|| $count_var==3||$count_var==4){  
$varsh="символа";  

if(
$count_var==|| 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 выше
$namerawurlencode($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("&amp;quot;","\"",$link); 
$link_name=preg_replace("#[\s]{1}#","&nbsp;",$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> 

  Ответить  
 
 автор: Trianon   (20.08.2008 в 17:24)   письмо автору
 
   для: Николай2357   (20.08.2008 в 17:00)
 

Нотайсы никуда не исчезли.
Код пестрит совершенно ненужными преобразованиями, расставленными как попало.
Как результат - ошибки в обработке.
к примеру, добавить а затем поискать имя &amp; - находится совсем другое имя.
добавить имя 0 не удается вообще. При добавлении руками в таблицу его невозможно найти.

Незачет, короче.

UPD.
неудача Ваша вытекает в первую очередь из того , что Вы не хотите понимать, какие функции в каких случаях и для каких целей требется применять.
Начинается это непонимание буквально в первых строках
 
if($_GET['name']){  
$name = stripslashes(htmlspecialchars($_GET['name']));


Вот здесь сразу три ошибки:
1. Обращение к элементу массива $_GET['name'] который запросто может отсутствовать .
2. применение htmlspecialchars в отсутствии необходимости перехода от текста к гипертексту
3. применение stripslashes а) без условия и б) не к входному параметру скрипта.

И так далее...

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 17:58)   письмо автору
 
   для: 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 а) без условия и б) не к входному параметру скрипта.
что есть, то есть. С перепугу наверное. Учту на будущее. Спасибо.

А далее не затруднит? Хорошее пособие для начинающих может получиться. Не только для меня...

  Ответить  
 
 автор: BinLaden   (20.08.2008 в 18:29)   письмо автору
 
   для: Николай2357   (20.08.2008 в 17:58)
 

> Как же написать "Мы приветствуем Вас <Trianon>!"

Вы там ничего не пишите. По крайней мере в этом куске кода.

  Ответить  
 
 автор: Trianon   (20.08.2008 в 18:51)   письмо автору
 
   для: Николай2357   (20.08.2008 в 17:58)
 

>
$name=  $_GET['name'];


опять.
это надо писать либо явно
if(isset($_GET['name']) $name = $_GET['name'];
else $name = null;

либо неявно, но с локальной блокировкой диагностик.
$name =@$_GET['name'];


>>2. применение htmlspecialchars в отсутствии необходимости перехода от текста к гипертексту
>есть необходимость, помоему...
нету. Потому, что в этом конкретном месте Вы вывод гипертекста не делаете.
а строка уже будет преобразована. Еще одно преобразование поверх - и первое окажется необратимым.

>>3. применение stripslashes а) без условия и б) не к входному параметру скрипта.
>что есть, то есть. С перепугу наверное. Учту на будущее. Спасибо.
>
>А далее не затруднит? Хорошее пособие для начинающих может получиться. Не только для меня...
А Вас не затруднит сперва изучить вот это решение?
http://softtime.ru/forum/read.php?id_forum=7&id_theme=38424

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 19:46)   письмо автору
 
   для: Trianon   (20.08.2008 в 18:51)
 

>опять.
это надо писать либо явно
Спасибо, дошло. Я просто много нахватался "верхушек", пытаюсь учиться у других. Видел много раз свой вариант и решил, что это оптимально. Так же как и с переменными в двойных кавычках и пр... Буду знать.
>нету. Потому, что в этом конкретном месте Вы вывод гипертекста не делаете.
а строка уже будет преобразована. Еще одно преобразование поверх - и первое окажется необратимым.
Вынужден не согласиться. Преобразование необходимо именно в этом месте, то есть в блоке
if(isset($_GET['name']){
........
так как оно применяется для $_GET['name'], соответственно для вывода имени в приветствие и запрос. Напротив, при отсутствии этой переменной запрос формируется из $_POST['name'] , без преобразований. Действительно, дальше есть еще одно, и обратное невозможно, но оно уже и не нужно. Наверняка такой подход не есть грамотный, но в данном контексте оправдан.
>А Вас не затруднит сперва изучить вот это решение?
Вы думаете я не умею читать? Я изучил его с ног до головы, прекрасно понимая, чье оно. Потом закрыл и не подглядывал. И пошел другим путем. Дело в том, что практическое решение данной задачи меня не интересует, а интересует меня различные подходы, и более всего (чeго кревить) "грамотность" моих каракулей. Тупо списать - проку мало...
Спасибо за поддержку.
PS Я не успокоюсь, пока в божеский вид не приведу свой скрипт, это будет полезней.

  Ответить  
 
 автор: Trianon   (20.08.2008 в 20:36)   письмо автору
 
   для: Николай2357   (20.08.2008 в 19:46)
 

Понятно... Вы предпочитаете, чтобы Вас додавливали контрпримерами.
Ок.
Вот приходит новый user и вводит в качестве имени &amp;amp; из девяти символов.
Ваш скрипт в строке $name=str_replace("&amp;amp;","&",$name); меняет его на один символ & .
В таком виде он и попадает в БД.

Исправляйте.

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 22:44)   письмо автору
 
   для: Trianon   (20.08.2008 в 20:36)
 

Да это то просто:
$name=preg_replace("#&amp;(.*?)#i","&$1",$name);

только я еще раз повторюсь, решить эту задачу на 100% наверное нельзя, да и не к чему это. В Вашем скрипте тоже не все гладко. Попробуйте набрать тот же пресловутый амперсанд с пробелом впереди. И где же тот пробел?
Главное вынести максимум пользы. Я вот допустим в смятении, не могу прочитать 0 из GET запроса. С теми же пробелами непонятно, они то плюсом кодируются, то %20. Вот это важно. Сделать еще один запрос в БД не трудно, но ведь в жизни придется решать и такие задачи, где это не поможет...

  Ответить  
 
 автор: BinLaden   (20.08.2008 в 23:10)   письмо автору
 
   для: Николай2357   (20.08.2008 в 22:44)
 

> Да это то просто:

На деле покажите? Имею ввиду запихните это в скрипт, который по ссылке http://test.inkz.ru/, чтобы все убедились, что это "просто".

Но сам факт того, что Вы предлагаете такое решение только говорит о том, что Вы еще ничего не поняли...:(

> Попробуйте набрать тот же пресловутый амперсанд с пробелом впереди. И где же тот пробел?
Он никуда не девался. Разве MySQL в конце строки при поиске пробелы подчищает и если в базе данных строка

"&   "
, то её можно будет найти хоть по запросу
"&"
, хоть по
"&       "

Хотя тип поля и TINYTEXT, а не (VAR)CHAR какой-нибудь.

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 23:59)   письмо автору
 
   для: BinLaden   (20.08.2008 в 23:10)
 

Ну вот, и Вы туда же. Не умею я наверное грамотно изъясняться.

>На деле покажите? Имею ввиду запихните это в скрипт, который по
Да пожалуйста, смотрите. Там далеко не все работает, но это работает точно. Кроме того, если уж пошла такая пьянка, в условиях четко сказано, использовать абсолютно любые символы. То есть и пробел. Как я понимаю, юзер по имени "два пробела амперсанд", это не юзер "один пробел амперсанд". У меня это тоже работает. Сделал это не для решения задачи, а просто показать, что подходы бывают разными.

>Но сам факт того, что Вы предлагаете такое решение только говорит о том, что Вы еще ничего не поняли...:(

Я не пытаюсь решить эту задачу на 100%!!!!! Я хочу выяснить то, чего до сих пор не знал.
Не знал и не знаю очень многого, и это проблема. А не то, что у меня подход другой. Лучше расскажите, как из GET прочитать 0. Спать не буду, пока не придумаю.
Спасибо.

  Ответить  
 
 автор: BinLaden   (21.08.2008 в 00:24)   письмо автору
 
   для: Николай2357   (20.08.2008 в 23:59)
 

Давайте постараемся убрать лишнии эмоции.
Про пробелы спросили Вы - я Вам ответил, но Вы почему-то этим раздражены.

> Сделал это не для решения задачи, а просто показать, что подходы бывают разными
Спасибо, но, мягко говоря, это не говорит о том, что раз такие подходы существуют, то их надо показывать :) От них надо избавляться.

> Я хочу выяснить то, чего до сих пор не знал.
Как это не покажется странным, но для того, чтобы что-то новое выяснить придётся решить задачу. Правильно решить. А не пытаться обмануть себя.

> Лучше расскажите, как из GET прочитать 0. Спать не буду, пока не придумаю.

<?php
$val 
0;
if( 
$val != '' )
{
      
# ....
}
?>

  Ответить  
 
 автор: Николай2357   (21.08.2008 в 01:07)   письмо автору
 
   для: BinLaden   (21.08.2008 в 00:24)
 

>Про пробелы спросили Вы - я Вам ответил, но Вы почему-то этим раздражены.

Да нет, что Вы, я злюсь на себя, что объяснить не могу.

>От них надо избавляться.
Вот опять к примеру. Я про подход к постановке вопроса, а не к решению задачи. Вообще то, если вспомните, вся эта эпопея началась из-за MySQL иньекций. Мне нужно эту проблему решить раз и навсегда. А не то, как амперсанд лучше вытащить, GET запросом или из базы. Это не принципиально. Задачу эту можно решить, только зачем? Ведь важен не результат, он практического применения вряд ли найдет. А вот передача данных - это важно.
За ноль спасибо, гениальное - как просто! И еще про кавычки функция мне очень понравилась. А скрипт я заставлю работать, дело принципа. Не сегодня, конечно, и так второй день на смарку.

  Ответить  
 
 автор: BinLaden   (21.08.2008 в 02:00)   письмо автору
 
   для: Николай2357   (21.08.2008 в 01:07)
 

А это все едино: есть текст и мы должны его обработать так, чтобы с ним ничего не произошло в результате: не добавилось лишнего и наоборот - ничего не потерялось. Ведь htmlspecialchars() и mysql_escape_string() по сути делают одно и то же: экранируют спец. символы для правильной вставки текста на страницу/в запрос Все "гениально и просто": и не требует иных подходов, которые могут допустить взлом

  Ответить  
 
 автор: BinLaden   (20.08.2008 в 17:03)   письмо автору
 
   для: Николай2357   (20.08.2008 в 16:28)
 

> По этому я и делаю вот это:

Как ловко Вы увернулись от ответа зачем Вы делаете то, то и вот то. Я Вас не спрашиваю почему Вы в принципе не делаете то же самое с POST-данными. Я Вас спрашиваю зачем Вы вообще применяете в данном случае htmlspecialchars(), stripslashes() и прочее.

> иначе GET переменная выводится некорректно.
Вы методом тыка подводите переменную к такому виду, чтобы она "выводилась правильно".

> то для того, чтобы правильно отображались бэкслэши. иначе их получается не то количество.
С какой стати их не то количество? На то должны быть причины.

> Тут как раз наоборот, посмотрите, пожалуйста на переменные. Они используются для вывода в HTML, подругому их просто не будет видно.
Я внимательно посмотрел на то, что делает Ваш код с данными из таблички Trianon'а. И мне это не понравилось. Хотя сейчас Вы что-то явно поменяли...

> Отключено у меня, разумеется
Я Ваш скрипт тестировал при включенном magic_quotes_gpc и данные в большинстве случаев действительно отображались так, как надо. Отключив, уже данные типа "\'" искажались.
Поэтому я сомневаюсь.

Добавьте в конец скрипта echo get_magic_quotes_gpc() ? "MQ Включено" : "MQ Отключено";

  Ответить  
 
 автор: Николай2357   (20.08.2008 в 17:19)   письмо автору
 
   для: BinLaden   (20.08.2008 в 17:03)
 

>Как ловко Вы увернулись от ответа зачем Вы делаете то, то и вот то. Я Вас не спрашиваю почему Вы в принципе не делаете то же самое с POST-данными. Я Вас спрашиваю зачем Вы вообще применяете в данном случае htmlspecialchars(), stripslashes() и прочее.
Да нет, и не думал уватачиваться. Просто объяснять наверное не умею. Я написал выше, что на вывод в строку "Здрасти..." данные беру из переменных окружения. Поэтому и такая карусель. htmlspecialchars(), stripslashes() соответственно применяю для того, чтобы было "Здрасти <Mac'cormic>...", а не что попало.
> иначе GET переменная выводится некорректно.
Вы методом тыка подводите переменную к такому виду, чтобы она "выводилась правильно".
Наверное, просто других методов пока не знаю. Подскажите...
> то для того, чтобы правильно отображались бэкслэши. иначе их получается не то количество.
С какой стати их не то количество? На то должны быть причины.
Разумеется есть, раз не то количество. Другой вопрос, знаю ли я их? Нет. Но победить как то надо. Буду искать причины.
> Тут как раз наоборот, посмотрите, пожалуйста на переменные. Они используются для вывода в HTML, подругому их просто не будет видно.
Я внимательно посмотрел на то, что делает Ваш код с данными из таблички Trianon'а. И мне это не понравилось. Хотя сейчас Вы что-то явно поменяли...
Поменял только то, что описывал, сравните сами.
Добавьте в конец скрипта echo get_magic_quotes_gpc() ? "MQ Включено" : "MQ Отключено";
Дома точно отключено, на хостинге сейчас проверю.
Спасибо.

Да, действительно, на хостинге были включены. Отключил - пока изменений не вижу.

  Ответить  
 
 автор: BinLaden   (20.08.2008 в 17:43)   письмо автору
 
   для: Николай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.

  Ответить  
 
 автор: BinLaden   (20.08.2008 в 17:44)   письмо автору
 
   для: Николай2357   (20.08.2008 в 17:19)
 

> Отключил - пока изменений не вижу.

Введите имя "\'" (бекслеш и апостроф).

  Ответить  
 
 автор: Николай2357   (21.08.2008 в 13:36)   письмо автору
 
   для: Николай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==|| $count_var==3||$count_var==4)
                     {  
                 
$varsh="символа";  
                     } 
                     if(
$count_var==|| 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}#","&nbsp;",$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 &amp partners doesn''t eat Mc''donalds Gamburgers\\Cheeseburgers<br /> 
Mc''robbins'<br />
O"Relly <br />
Jensen & partners<br />
total %25 of sales <br />
&amp;amp; <br />
&amp;<br />
characterictics of volt&amp;amp; any other graphs <br />
Guest004
</body>  
</html> 


PS Комментировать не стал, и так бумаги попортил.
Спасибо.

  Ответить  
 
 автор: Trianon   (21.08.2008 в 15:27)   письмо автору
 
   для: Николай2357   (21.08.2008 в 13:36)
 

по-моему, во всех сравнениях, подобных этому
$go != null
Вы имели в виду на самом деле
$go !== null


В остальном таки да. Прогресс имеет место быть.

  Ответить  
 
 автор: Николай2357   (21.08.2008 в 15:48)   письмо автору
 
   для: Trianon   (21.08.2008 в 15:27)
 

Спасибо. Подскажите еще, пожалуйста,
1)Когда использовать === (строго равно)?
2)Нужно ли в конце подобных скриптов session_destroy ?
3) И самый главный вопрос, из за которого я старался: теперь можно спать спокойно на счет иньекций?
Спасибо.

  Ответить  
 
 автор: GeorgeIV   (21.08.2008 в 16:38)   письмо автору
 
   для: Николай2357   (21.08.2008 в 15:48)
 

$a=false;
$b=0;
$a==$b будет истина
$a===$b будет ложь
почувствуй разницу

  Ответить  
 
 автор: Николай2357   (21.08.2008 в 16:43)   письмо автору
 
   для: GeorgeIV   (21.08.2008 в 16:38)
 

Почувствовал, спасибо.
А главного я так и не понял. Мне в PHP еще пахать и пахать, куда уж хакерские методы изучить... Только видел я примеры иньекций, где нет ни одной кавычки. От них это тоже спасает? И с сессией не понятно. Как то раз выключил интернет не закрыв страницу, а на следующий день включил - сессия живая. Это как так?

  Ответить  
Rambler's Top100
вверх

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