[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Попытка номер раз.
Zenith
Попробовал решить задачку из этого топика.
Жду ваши тапки :P
P.s. Над защитой от % и _ пока думаю.

Собственно форма

<?php
session_start();
$_SESSION['enter']="Алонсо!";
?>
<form method="post" action="obrabotka.php">
<
input type="text" name="name">
<
input type="submit" name="knopka" value="Enter">
</
form>
<?


Собственно обработчик

<?php
session_start();
connect();
function connect(){
$host="localhost";
$user="root";
$pass="";
$bd="names";
mysql_connect($host,$user,$pass) or die("Не удалось подключиться к серверу базы данных");
mysql_select_db($bd) or die("Не удалось выбрать базу данных".mysql_error());

}
function enter(){
if(isset($_SESSION['enter'])){
return true;
}else{return false;}
}

function plus_slash($a){
$b=chr(92);
$a=str_replace($b,$b.$b,$a);
return $a;
}
function minus_slash($a){
$b=chr(92);
$a=str_replace($b.$b,$b,$a);
return $a;
}
if(enter()){
if(isset($_POST['name']) and ($_SESSION['enter']!=$_POST['knopka'])){
$name1=trim($_POST['name']);
if(strlen($name1)===0){session_destroy();header('location:form.php');die();}
$name1=mysql_real_escape_string($_POST['name']);
$name1=plus_slash($name1);
$q=mysql_query("INSERT INTO names SET name='$name1'") or die(mysql_error());
if($q){$_SESSION['enter']=$_POST['knopka'];$_SESSION['inside']=$_SESSION['enter'];}
}

if(isset($_SESSION['inside']) and isset($_GET['id'])){
$id=mysql_real_escape_string($_GET['id']);
$query_date=mysql_query("SELECT `date` FROM `names` WHERE `id`=$id") or die(mysql_error());
echo mysql_result($query_date, 0);
echo " <a href='obrabotka.php'>список</a>";
}
elseif(isset($_SESSION['inside']) && isset($_GET['knopka_poiska'])){
$f=trim($_GET['what_search']);
$s=trim($_GET['what_search']);
$f=plus_slash($f);
$f=mysql_real_escape_string($f);
echo "<br>Результат поиска по запросу \"".$_GET['what_search']."\"";
$query_search=mysql_query("SELECT `id`,`name` FROM `names` WHERE `name` LIKE '%$f%'");
$html="<table>";
if($query_search){
while($result=mysql_fetch_array($query_search)){
$q=minus_slash($result['name']);
$q=htmlspecialchars($q);
$html.="<tr><td>".$q."</td></tr>";
}
}

$html.="</table>";
echo $html;
?>
<form>
<
input type="text" name="what_search" value="<?=$s;?>">
<
input type="submit" name="knopka_poiska" value="search">
</
form><?
echo " <a href='obrabotka.php'>список</a>";
}
else {
$query_all=mysql_query("SELECT `id`,`name` FROM `names` ORDER BY `date` DESC") or die(mysql_error());
$html="<table>";
while($result=mysql_fetch_assoc($query_all)){
$q=minus_slash($result['name']);
$q=htmlspecialchars($q);
$html.="<tr><td><a href='obrabotka.php?id=".$result['id']."'>".$q."</td></tr>";
}
$html.="</table>";
$html.="<form>
<input type='text' name='what_search'>
<input type='submit' name='knopka_poiska' value='search'>
</form>"
;
echo $html;

}
}

else{
session_destroy();
header('location:form.php');
}




Спустя 3 часа, 29 минут, 15 секунд (8.02.2011 - 07:19) twin написал(а):
Ну что сказать... Код совсем небольшой, но крайне запутанный.
Ты хоть бы обозначил, как файлы называть.

Стиль ужасен. Пипец глазам. Где начало блока еще видно, где конец: ищи-свищи. Я первым делом засунул его сюда. Стало немного понятнее.

С юзабилити что то явно не то. Как я не пыхтел, не смог понять, как мне кого-нибудь зарегать. Поиск вижу, а где форма реги? Не, я конечно понимаю, что нужно на файл form.php, но где ссыль?

Дальше по условиям задачи. Ничего не выполнено. SQL инъекции налицо, про магические кавычки ни намека, XSS буйным цветом, с процентами ты сам сказал.

Вобщем вердикт - исключительно плохо. На пересдачу. smile.gif

Спустя 2 часа, 28 минут, 8 секунд (8.02.2011 - 09:47) Zenith написал(а):
И вправду, бес попутал.
Пойду делать чтоб работало.
За линк спасибо.

Спустя 6 дней, 12 часов, 6 минут, 11 секунд (14.02.2011 - 21:53) Zenith написал(а):
Я наверное не совсем понял: решение лучше получить в виде одного файла с скриптом или можно в несколько разделённых файлов? Или это не принципиально?

Спустя 2 часа, 50 минут, 5 секунд (15.02.2011 - 00:43) twin написал(а):
Это не важно. Но вообще любой скрипт нужно писать с прицелом на легкую интеграцию. Это хорошая привычка.

Спустя 1 день, 2 часа, 21 минута, 22 секунды (16.02.2011 - 03:05) Zenith написал(а):
В общем зверь страшный получился. :ph34r:
Ща пойду склеивать в один файл.

файл №1 aut.php собственно форма
<head>
</head>
<body>
<center><table>
<form
method="post" action="enter.php">
<tr><td><input
type="text" name="login"></td></tr>
<tr><td><input
type="submit" name="knopka" value="Вход"></td></tr>
</form>
</table>
</center>
</body>


файл №2 enter.php обработчик формы
<?php
session_start();
require_once "names_function.php";
defend_refer();
defend_quotes();
connect();
if(isset($_POST['knopka']) and isset ($_POST['login'])){

$name1=trim($_POST['login']);
//если переданно любое кол-во пробелов без прочих символов, срабатывает переадресация на вход
if(strlen($name1)===0){session_destroy();header('location:aut.php');die();}
$name1=mysql_real_escape_string($name1);
$q=mysql_query("INSERT INTO names SET name='$name1'") or die(mysql_error());
$w=mysql_query("SELECT `name` FROM `names` WHERE `id`='".mysql_insert_id()."'");
$_SESSION['in']=true;
$n=htmlspecialchars(mysql_result($w, 0));
$_SESSION['name']=$n;
header('location:index.php');
}?>


файл №3 index.php список логинов и форма для поиска
<?php
session_start();
require_once "names_function.php";
defend_refer();
defend_quotes();
connect();
if(!isset($_SESSION['in'])){
session_destroy();
header('location:aut.php');}
elseif (isset($_SESSION['name'])){
$show_all=mysql_query("SELECT `id`,`name` FROM `names` ORDER BY `date` DESC") or die(mysql_error());
$html="<table border='1'>
<caption>В нашем зоопарке водятся:
</caption>"
;
while($result=mysql_fetch_assoc($show_all)){
$q=htmlspecialchars($result['name']);
$html.="<tr><td><a href='infa1.php?id=".$result['id']."'>".$q."</td></tr>";
}
$html.="</table>";
echo $html;
}
?><table><caption>Ищем зверя по имени:</caption><form action="to_hunt.php">
<
tr><td><input type="text" name="login"></td></tr>
<
tr><td><input type="submit" name="poisk" value="На охоту!"></td></tr>
</
form></table>

файл 4 infa1.php получение информации о пользователе
<?php
session_start();
require_once 'names_function.php';
defend_refer();
defend_quotes();
connect();
if(isset($_SESSION['in'])){
if(isset($_GET['id'])) {
$id=mysql_real_escape_string($_GET['id']);
$query_date=mysql_query("SELECT * FROM `names` WHERE `id`=$id") or die(mysql_error());
if($query_date){
$infa=mysql_fetch_array($query_date);
$_SESSION['search']['sName']=htmlspecialchars($infa['name']);
$_SESSION['search']['sId']=$infa['id'];
$_SESSION['search']['sDate']=$infa['date'];
header('location:infa.php');
}
}
else {
header('location:index.php');
}
}
else {
session_destroy();header('location:aut.php');
}
?>


файл №5 infa.php вывод информации о пользователе в браузер.

<?php
session_start();
require_once 'names_function.php';
defend_refer();
defend_quotes();
connect();
if(!isset($_SESSION['in'])){
session_destroy();header('location:aut.php');
} elseif (isset($_SESSION['search'])) {
echo "<h3>Инфа по зверю ".$_SESSION['search']['sName']."</h3>";
echo "Id:".$_SESSION['search']['sId']."<br>";
echo "Дата регистрации: ".$_SESSION['search']['sDate']."<br>";
echo "</br><a href='index.php'>Назад в зверинец</a>";
}
?>


файл №6 to_hunt.php обработка поискового запроса и вывод в браузер

<?php
session_start();
require_once 'names_function.php';
defend_refer();
defend_quotes();
connect();
if(isset($_SESSION['in'])){
if (isset($_GET['login'])){
$f=trim($_GET['login']);//начинаем формировать текcт для запроса
$la=$f;//это для возврата значения в поле поиска
/* Тут начинаются танцы с бубном. Что бы из БД вытащить зверя с одинарным слешом в имени, например "\"
* приходится этот слеш экранировать спомощью стринг_ескейпа ещё до запроса в БД.
* В результате имеем запрос такого вида:
* "SELECT `id`,`name` FROM `names` WHERE `name` '\\'
* Однако если в запросе после слеша присутствуют другие служебные знаки, после стринг_ескейпа
* может получиться такая хрень:
* "SELECT `id`,`name` FROM `names` WHERE `name` LIKE '\\%'"
* Т.Е. экранированный слеш заэкранирует процент или другой символ и испортит запрос
* (в приведённом примере получчается выборка из БД всех имён со знаком процента, а не со слешом)
* Для того что бы этого избежать ручками экранируем слеш, потом экранируем стрингом.
* Получим запрос вида:
* "SELECT `id`,`name` FROM `names` WHERE `name` LIKE '\\\\%'"
* (Получаем выборку из БД всех имён с слешом и любым количеством любых символов после него)
* Наверное можно сделать лучше? но у мну не получилось ;(
*/

$f=plus_ekran($f);/*Ручками экранируем следующие символы:\, %, _ */
$f=mysql_real_escape_string($f);
$sql="SELECT `id`,`name` FROM `names` WHERE `name` LIKE '%$f%'";
$query_search=mysql_query($sql) or die(mysql_error());
if((mysql_num_rows($query_search))>0){
$html="<table>";
while($result=mysql_fetch_array($query_search)){
//формируем тескт для вывода на экран
$nam=htmlspecialchars($result['name']);
$html.="<tr><td><a href='infa1.php?id=".$result['id']."'>".$nam."</a></td></tr>";
}
$html.="</table>";
echo $html;
} elseif ((mysql_num_rows($query_search))==0) {
echo "Зверей не найденно";
}
echo "</br><a href='index.php'>Назад в зверинец</a>";
/*ниже снова идёт форма поиска с возвращённым начальным запросом*/
?>
<table><caption>Продолжаем поиск:</caption>
<
form action="to_hunt.php">
<
tr><td><input type="text" name="login" value=<?=$la;?>></td></tr>
<
tr><td><input type="submit" name="poisk" value="На охоту!"></td></tr>
</
form>
</
table>
<?
}

}
else{
session_destroy();header('location:aut.php');
}?>


файл №7 names_function.php набор функций


<?php
function
connect(){//без комментариев
$host="localhost";
$user="root";
$pass="";
$bd="names";
mysql_connect($host,$user,$pass) or die("Не удалось подключиться к серверу базы данных");
mysql_select_db($bd) or die("Не удалось выбрать базу данных".mysql_error());
}
function plus_ekran($string){/*экранируем слеш, процент и подстрочник
* реально эта хрень нужна только для поиска по БД
*/

$slash=chr(92);
$string=str_replace($slash, $slash.$slash,$string);
$string=str_replace("%", "\%", $string);
$string=str_replace("_", "\_", $string);
return $string;
}
function defend_refer(){
$home="http://".$_SERVER['SERVER_NAME'];
if(!substr($_SERVER['HTTP_REFERER'], 0, strlen($home))==$home){
//если обращение к скрипту идёт с другого сервера сбрасываем сесию
session_destroy();header('location:aut.php');
}

}

function stripslashes_array($array) { //© спёрто тут http://webew.ru/articles/198.webew
return is_array($array) ?
array_map('stripslashes_array', $array) : stripslashes($array);
}

function defend_quotes(){
if (get_magic_quotes_gpc()) { //© спёрто тут http://webew.ru/articles/198.webew
$_GET = stripslashes_array($_GET);
$_POST = stripslashes_array($_POST);
$_COOKIE = stripslashes_array($_COOKIE);
}
}


Спустя 7 минут, 20 секунд (16.02.2011 - 03:12) Zenith написал(а):
мозг сказал "спать" blink.gif . Склеивать буду на работе.

Спустя 11 минут, 57 секунд (16.02.2011 - 03:24) twin написал(а):
И сразу стиль поправь. Глаза поломать можно. Почитай тут.

Спустя 2 часа, 51 минута, 37 секунд (16.02.2011 - 06:16) Zenith написал(а):
Цитата (twin @ 16.02.2011 - 00:24)
И сразу стиль поправь. Глаза поломать можно. Почитай тут.

unsure.gif а ты вообще спишь когда-нибудь?
Или кредо по жизни: сон для слабаков?

Спустя 7 дней, 15 часов, 24 минуты, 13 секунд (23.02.2011 - 21:40) Zenith написал(а):
В общем сессию пора сдавать, так что это в ближайшее время последняя "шлифовка напильником", прошу оценить.
P.s. Спасибо за ссылку на форматер кода.
P.p.s. Можете дать совет или ссылку на то, как бороться с избыточностью кода? Буду очень признателен.

<?php
session_start();

$_SESSION['history'];//нужно для записи истории перемещений по страницам
function connect()
{
//без комментариев
$host = "localhost";
$user = "root";
$pass = "";
$bd = "names";
mysql_connect($host, $user, $pass) or die("Не удалось подключиться к серверу базы данных");
mysql_select_db($bd) or die("Не удалось выбрать базу данных". mysql_error());
}
function plus_ekran($string)
{

/*экранируем слеш, процент и подстрочник
* реально эта хрень нужна только для поиска по БД
*/

$slash = chr(92);
$string = str_replace($slash, $slash . $slash, $string);
$string = str_replace("%", "\%", $string);
$string = str_replace("_", "\_", $string);
return $string;
}
function defend_refer()
{
$home = "http://". $_SERVER['SERVER_NAME'];

if(!substr($_SERVER['HTTP_REFERER'], 0, strlen($home)) == $home)
{
//если обращение к скрипту идёт с другого сервера сбрасываем сесию
session_destroy();
header('location:2.php');
}
}

function stripslashes_array($array)
{
//© спёрто тут http://webew.ru/articles/198.webew
return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array);
}
function defend_quotes()
{

if(get_magic_quotes_gpc())
{
//© спёрто тут http://webew.ru/articles/198.webew
$_GET = stripslashes_array($_GET);
$_POST = stripslashes_array($_POST);
$_COOKIE = stripslashes_array($_COOKIE);
}
}

function change_page()
{
//это нужно для вывода на экран определённой инфы

if(($_SESSION['page'] == "index" or $_SESSION['page'] == "search") and (isset($_GET["id"])))
{
//для вывода инфы по пользователю
$_SESSION['id_for_search'] = $_GET["id"];
$_SESSION['page'] = "infa";
//обновляем значение страницы
}
elseif(($_SESSION['page'] == 'index' or $_SESSION['page'] == "search") and (isset($_GET['poisk'])))
{
//для вывода результата поиска
$_SESSION['login_for_search'] = $_GET['login'];
//забиваем сюда то что нужно искать
$_SESSION['page'] = "search";
//обновляем значение страницы
}
elseif(($_SESSION['page'] == "infa" or $_SESSION['page'] == "search") and (isset($_GET['back'])))
{
//для возврата на предыдущую страницу
$nCurr = count($_SESSION['history']) - 1;
//номер записи текущей страницы
$nPrev = count($_SESSION['history']) - 2;
//номер записи предыдущей страницы
$_SESSION['page'] = $_SESSION['history'][$nPrev];
//назначаем предыдущую страницу как текущую
unset($_SESSION['history'][$nCurr]);
//удаляем запись текущей страницы
}
}

function updateHistory()
{
$b = count($_SESSION['history']) - 1;
//получаем индекс последней записи

if($_SESSION['history'][$b] != $_SESSION['page'])
{
//сравниваем последнюю запись с текущим значением страницы, если не совпадает записываем новое значение
$_SESSION['history'][] = $_SESSION['page'];
}
}

defend_quotes();
connect();

if(isset($_POST['knopka']) and isset($_POST['login']))
{
//первичный вход-регистрация
$name1 = trim($_POST['login']);
//если переданно любое кол-во пробелов без прочих символов, срабатывает переадресация на вход

if(strlen($name1) === 0)
{
session_destroy();
header('location:2.php');
die();
}
$name1 = mysql_real_escape_string($name1);
$q = mysql_query("INSERT INTO names SET name='$name1'") or die(mysql_error());
$w = mysql_query("SELECT `name` FROM `names` WHERE `id`='".mysql_insert_id()."'");
$_SESSION['name'] = htmlspecialchars(mysql_result($w, 0));

if(isset($_SESSION['name']))
{
$_SESSION['in'] = true;
//подтверждаем факт входа
$_SESSION['page'] = "index";
//для вывода на экран по умолчанию стоит главная таблица
header('location:2.php');
//пересылка на смаого себя обнулит массив POST
}
}

change_page();

if(isset($_SESSION['in']))
{
//проверка наличия авторизации
defend_refer();

if($_SESSION['page'] == "index")
{
//вывод основной таблицы
updateHistory();
//записываем в историю значение страницы
$show_all = mysql_query("SELECT `id`,`name` FROM `names` ORDER BY `date` DESC") or die(mysql_error());
$html = "<table border='1'>
<caption>В нашем зоопарке водятся:
</caption>"
;
while($result = mysql_fetch_assoc($show_all))
{
$q = htmlspecialchars($result['name']);
$html .= "<tr><td><a href='2.php?id=".$result['id']."'>". $q ."</td></tr>";
}
$html .= "</table>";
$html .= "<table><caption>Ищем зверя по имени:</caption><form action='2.php'>";
$html .= "<tr><td><input type='text' name='login'></td></tr>";
$html .= "<tr><td><input type='submit' name='poisk' value='На охоту!'></td></tr>";
$html .= "</form></table>";
echo $html;
}
elseif($_SESSION['page'] == "infa")
{
//вывод на экран инфы по конкретному пользователю
updateHistory();
//записываем в историю значение страницы

if(isset($_SESSION['id_for_search']))
{
//если есть сессия с id то вытащим инфу из базы данных
$id = mysql_real_escape_string($_SESSION['id_for_search']);
unset($_SESSION['id_for_search']);
//не придумал зачем мне ещё может понадобиться этот id
$query_date = mysql_query("SELECT * FROM `names` WHERE `id`=$id") or die(mysql_error());
}

if($query_date)
{
//если получен результат запроса, подготоавливаем его для вывода на экран
$infa = mysql_fetch_array($query_date);
$_SESSION['vSearch']['iName'] = htmlspecialchars($infa['name']);
$_SESSION['vSearch']['iId'] = $infa['id'];
$_SESSION['vSearch']['iDate'] = $infa['date'];
}

if(isset($_SESSION['vSearch']))
{
//выводим инфу на экран
echo "<h3>Инфа по зверю ". $_SESSION['vSearch']['iName'] ."</h3>";
echo "Id:". $_SESSION['vSearch']['iId'] ."<br>";
echo "Дата регистрации: ". $_SESSION['vSearch']['iDate'] ."<br>";
?><form><input type="submit" name="back" value="назад"></form><?
//кнопка возврата на предыдущую страницу
}
}

elseif($_SESSION['page'] == "search")
{
//поиск по запросу
updateHistory();
//записываем в историю значение страницы

if($_SESSION['login_for_search'])
{
//если в сессии указанна инфа для поиска, то подготавливаем её для запроса
$f = trim($_SESSION['login_for_search']);
$la = $f;
//это для возврата значения в поле поиска

/* Тут начинаются танцы с бубном. Что бы из БД вытащить зверя с одинарным слешом в имени, например "\"
* приходится этот слеш экранировать спомощью стринг_ескейпа ещё до запроса в БД.
* В результате имеем запрос такого вида:
* "SELECT `id`,`name` FROM `names` WHERE `name` '\\'
* Однако если в запросе после слеша присутствуют другие служебные знаки, после стринг_ескейпа
* может получиться такая хрень:
* "SELECT `id`,`name` FROM `names` WHERE `name` LIKE '\\%'"
* Т.Е. экранированный слеш заэкранирует процент или другой символ и испортит запрос
* (в приведённом примере получчается выборка из БД всех имён со знаком процента, а не со слешом)
* Для того что бы этого избежать ручками экранируем слеш, потом экранируем стрингом.
* Получим запрос вида:
* "SELECT `id`,`name` FROM `names` WHERE `name` LIKE '\\\\%'"
* (Получаем выборку из БД всех имён с слешом и любым количеством любых символов после него)
* Наверное можно сделать лучше? но у мну не получилось ;(
*/

$f = plus_ekran($f);

/*Ручками экранируем следующие символы:\, %, _ */
$f = mysql_real_escape_string($f);
$sql = "SELECT `id`,`name` FROM `names` WHERE `name` LIKE '%$f%'";
$query_search = mysql_query($sql) or die(mysql_error());

if((mysql_num_rows($query_search)) > 0)
{
//формируем таблицу результата поиска
$html = "<table>";
while($result = mysql_fetch_array($query_search))
{
//формируем тескт для вывода на экран
$nam = htmlspecialchars($result['name']);
$html .= "<tr><td><a href='2.php?id=".$result['id']."'>". $nam ."</a></td></tr>";
}
$html .= "</table>";
}
elseif((mysql_num_rows($query_search)) == 0)
{
echo "Зверей не найденно";
}
$html .= "<table><caption>Продолжаем поиск:</caption>";
$html .= "<form action='2.php'>";
$html .= "<tr><td><input type='text' name='login' value='".$la."'></td></tr>";
$html .= "<tr><td><input type='submit' name='poisk' value='На охоту!'></td></tr>";
$html .= "</form></table>";
echo $html;
?><form><input type="submit" name="back" value="назад"></form><?
//кнопка возврата на предыдущую страницу
}
}
}

else
{
?>
<center><table>
<
form method="post" action="2.php">
<
tr><td><input type="text" name="login"></td></tr>
<
tr><td><input type="submit" name="knopka" value="Вход"></td></tr>
</
form>
</
table>
</
center>
<?
}
?>

Спустя 8 часов, 39 минут, 30 секунд (24.02.2011 - 06:19) Xpund написал(а):
Я всёже думаю что сессии лишние.


А по стилю с запросами помойму так лучше если память мне не изменяет
$q = mysql_query("INSERT INTO
`names` SET
`name`='"
.$name1."'")


 $query_date = mysql_query("SELECT * FROM `names` WHERE `id`=$id") or die(mysql_error());

Тут тоже ошибочка.

Спустя 13 дней, 6 часов, 48 минут, 53 секунды (7.03.2011 - 13:08) twin написал(а):
Упс, как то потерялась из виду темка.... Прошу пардона за задержку.

Итак. Что сразу бросается в глаза - избыточность. Да ты и сам это зметил.
Дальше, поставь первой строчкой это:
    error_reporting(E_ALL); 
и будешь неприятно удивлен обилием нотайсов.
Третье, скрипт жестко привязан к названию файла, а это очень нехорошо.
Ну и сессия тут наверное совсем лишняя вещь. Задача достаточно простая и решать её нужно было менее ресурсоемким способом.

Но в остальном достаточно серьёзный прогресс. Стиль уже радует, немного перестарался с комментами, но это для контрольной работы скорее плюс, чем минус.

Основные условия задачи выполнены, респект. :)


_____________
"Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете". (с) Макконнелл, "Совершенный код".
Быстрый ответ:

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