[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Задача на корректную обработку данных
nefarius
Уважаемый twin и форумчане!
Недавно увидел твою задачу и решил закрепить свои знания.
Очень интересно услышать результат. Не судите строго так как изучаю php чуть больше мецяца



<form action="<?=$_SERVER['PHP_SELF'];?>" method="POST">
Registration:<br>
<
input type="text" name="name"><br>
<
input type="submit" value="Register"><br>
</
form>

<
form action="<?=$_SERVER['PHP_SELF'];?>" method="GET">
Searching:<br>
<
input type="text" name="search" value="<?php if (!empty($_GET["search"])){ //check the existence of a global variable, else - is empty
echo htmlspecialchars(
$_GET["search"]);
}else {echo "";}?>"
>
<
br>
<
input type="submit" value="Search"><br>
</
form>




<?php
error_reporting (E_ALL);

define ("DB_HOST", "localhost");
define ("DB_LOGIN", "root");
define ("DB_PASSWORD", "");
define ("DB_NAME", "names");

//connect to server
mysql_connect (DB_HOST, DB_LOGIN, DB_PASSWORD) or die ("Error when connecting to server: " .mysql_error());
//select "names"
mysql_select_db (DB_NAME) or die ("Error when selecting database {DB_NAME}: " .mysql_error());
//////////////////////////////////////////////////////////////////////////////////////////////////// ///////


// function for filter the data
function filterData($data, $type = "s"){
switch($type){
case "s":
return mysql_real_escape_string(trim($data));
case "i":
return (int)$data;
}
}



// receives data and put them in the database
if (!empty($_POST["name"])){
$name = filterData ($_POST["name"]);
$sql = "INSERT INTO names(name) VALUES('$name')";
mysql_query($sql) or die("Error for DB: ".mysql_error());

header("Location: ".$_SERVER['PHP_SELF']);
exit;
}

// receiving and filtering data from the search field
if(!empty($_GET["search"])){
$search = str_replace("%", "|%", filterData($_GET["search"]));
$search = str_replace("_", "|_", $search);

$sql = "SELECT name FROM names WHERE name LIKE '%$search%' ESCAPE '|'";
$found_result = mysql_query($sql) or die ("Bug in search: ".mysql_error());
}

// make select all names
$sql = "SELECT id,name FROM names ORDER BY id DESC";
$row = mysql_query($sql) or die(mysql_error());

// output number of registered users and number of matches found
echo "<p>Total registered: ".mysql_num_rows($row)." users<br>";
if(!empty($found_result)){
echo "<p>Found similar records: ".mysql_num_rows($found_result);
}

// output found usernames
if(!empty($found_result)){
$match = array();
while($match = mysql_fetch_assoc($found_result)){
echo "<ul>";
echo "<li>".htmlspecialchars($match["name"]);
echo "</ul>"; // perhaps so many 'echo', but I find this way fullest rational
}
}


// receiving and filtering data from global variable $_GET["id"] to display the date of registration
if(!empty($_GET["id"])){
$id = filterData($_GET["id"], "i");
if($id>0){
$sql = "SELECT date,name FROM names WHERE id = $id";
$id_date = mysql_query($sql) or die(mysql_error());
$id_date = mysql_fetch_assoc($id_date);
echo "<p>User <b>{$id_date["name"]}</b> registered: {$id_date["date"]}"; // output line date of registration
}
}


//close connection
mysql_close();

// output all names in cycle
$user = array();
while($user = mysql_fetch_assoc($row)){
?>
<hr>
<
p>
User: <a href='<?=$_SERVER['PHP_SELF']?>?id=<?=$user["id"]?>'><?=htmlspecialchars($user["name"])?></a><br>
</
p>

<?php
}
?>




Спустя 6 часов, 31 минута, 20 секунд (7.09.2012 - 08:26) Shuriken написал(а):
action="<?=$_SERVER['PHP_SELF'];?>"


Тут можно просто написать
action=""



value="<?php if (!empty($_GET["search"])){  //check the existence of a global variable, else - is empty
echo htmlspecialchars(
$_GET["search"]);
}else {echo "";}?>"
>


Здесь else лишний, зачем лишний раз вывод делать.


header("Location: ".$_SERVER['PHP_SELF']);

А на это у тебя не ругается при добавлении юзера? header должен быть до выводов каких-либо данных в браузер.

Спустя 2 часа, 4 минуты, 12 секунд (7.09.2012 - 10:30) nefarius написал(а):
header("Location: ".$_SERVER['PHP_SELF']);


Нет, не ругается вообще.

Спасибо за замечания.

Спустя 4 часа, 19 минут, 2 секунды (7.09.2012 - 14:50) 123456 написал(а):
Цитата
<input type="text" name="search" value="<?php if (!empty($_GET["search"])){  //check the existence of a global variable, else - is empty
          echo htmlspecialchars($_GET["search"]);
          }else {echo "";}?>">

=

<input type="text" name="search" value="<?=isset($_GET['search']) ?$_GET['search'] :NULL?>">



Цитата
$sql = "INSERT INTO names(name) VALUES('$name')";
mysql_query($sql) or die("Error for DB: ".mysql_error());


=


mysql_query("INSERT INTO names(name) VALUES('$name')") or die("Error for DB: ".mysql_error());

и везде аналогично

Спустя 18 часов, 54 минуты, 37 секунд (8.09.2012 - 09:44) twin написал(а):
Начало хорошее, но немного перемудрил.

Первое - магические кавычки. Ничего я не увидел про них, условие не выполнено.
Дальше. Функция filterData(). Почему он так называется? Почему фильтр? Это очень важно для понимания процесса - если обработка называется фильтрацией, значит в голове до сих пор каша.
Цитата
Фильтрация  — процесс разделения неоднородных систем.
Где тут разделение? Фильтр обычно что-то пропускает, а что-то задерживает. А в условиях задачи явно и недвусмысленно сказано:
Цитата
могут присутствовать абсолютно любые символы, включая пробел
Значит фильтрация тут неуместна.
К слову сказать, функция фильтрацией и не занимается, но терминология, особенно в названии функций, очень важна. Ибо по названию ожидаешь действия. Что было бы, если PHP на команду print не печатал бы аргумент, а извлекал бы из него квадратный корень...

Еще совет по этой функции. Уж коль скоро сделал универсальную обертку, так и апострофы сунь в неё:
// function for filter the data
function filterData($data, $type = "s"){
switch($type){
case "s":
return "'". mysql_real_escape_string(trim($data)) ."'";
case "i":
return (int)$data;
}
}


Дальше. Вот сравни это:
// receives data and put them in the database
if (!empty($_POST["name"])){
$name = filterData ($_POST["name"]);
$sql = "INSERT INTO names(name) VALUES('$name')";
mysql_query($sql) or die("Error for DB: ".mysql_error());

header("Location: ".$_SERVER['PHP_SELF']);
exit;
}
с этим
// receives data and put them in the database
if (!empty($_POST["name"])){

mysql_query("INSERT INTO names(name) VALUES(". filterData ($_POST["name"]).")")
or die("Error for DB: ".mysql_error());

header("Location: ".$_SERVER['PHP_SELF']);
exit;
}
и сделай выводы. Кода меньше, а значит читабельнее - раз, на две переменные меньше, а это экономия памяти - два, меньше на две операции перезаписи (экономия времени) - три. Старайся писать без лишних телодвижений. Чем лаконичнее код, тем лучше.

Продолжим.
Вот с этим разберись повнимательнее.
// receiving and filtering data from the search field
if(!empty($_GET["search"])){
$search = str_replace("%", "|%", filterData($_GET["search"]));
$search = str_replace("_", "|_", $search);

$sql = "SELECT name FROM names WHERE name LIKE '%$search%' ESCAPE '|'";
$found_result = mysql_query($sql) or die ("Bug in search: ".mysql_error());
}


Во-первых не работает. Во вторых, это все как то криво, мудрено и бестолково по большому счету. Не буду комментировать - сам должен понять.

while($match = mysql_fetch_assoc($found_result)){
echo "<ul>";
echo "<li>".htmlspecialchars($match["name"]);
echo "</ul>"; // perhaps so many 'echo', but I find this way fullest rational
}


Find so vain. Писать echo на каждой строчке - моветон. А если там 50 строк? Уж лучше конкатенацию тогда. Да и попытка упорядочить код таким образом терпит фиаско - достаточно посмотреть исходник HTML. Там все слепилось в одну строчку.

А вот что требует рациональности, так это компоновка. У тебя сначала идет форма, потом скрипт. А при регистрации стоит редирект. А это значит, что заголовок будет после вывода, что невозможно. Раз у тебя этот момент не вызвал затруднений, значит на сервере принудительно включена буферизация. А это так не у всех. Пропиши в .htaccess эту директиву
Цитата
output_buffering Off
и посмотри, что будет.

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


Спустя 8 часов, 42 минуты, 48 секунд (8.09.2012 - 18:27) twin написал(а):
И еще одно важное место проглядел. Регаем имя <script>alert("Хак!")</script> и жмем на него в списке. Ая-яй.

Спустя 1 день, 19 часов, 28 минут, 45 секунд (10.09.2012 - 13:56) nefarius написал(а):
Спасибо за ответ!
Всё переделал.
output_buffering отключен
Как бы всё сделал, а добавление кириллицы не смог настроить. При отправке формы поля "name" из кириллическими символами выдает: Incorrect string value: '\xEA\xEE\xF2' for column 'name' at row 1
Сам файл скрипта находиться в кодировке utf-8 без bom. При установке Mysql 5.5.27 была выбрана кодировка utf-8. Версия PHP 5.4.6
Вопрос:
Как правильно организовать добавление и выборку данных из базы в этой кодировке?
Где можно об этом почитать чтобы было доступно описано?

<?php
error_reporting (E_ALL);

define ("DB_HOST", "localhost");
define ("DB_LOGIN", "root");
define ("DB_PASSWORD", "");
define ("DB_NAME", "names");

//connect to server
mysql_connect (DB_HOST, DB_LOGIN, DB_PASSWORD)
or die ("Error when connecting to server: " .mysql_error());
//select "names"
mysql_select_db (DB_NAME)
or die ("Error when selecting database {DB_NAME}: " .mysql_error());
//////////////////////////////////////////////////////////////////////////////////////////////////// ///////

// rewrite global varieble without magic_quotes_gpc
if (get_magic_quotes_gpc()) {
function stripslashes_gpc(&$value)
{
$value = stripslashes($value);
}
array_walk_recursive($_GET, 'stripslashes_gpc');
array_walk_recursive($_POST, 'stripslashes_gpc');
}


// function for processing the data
function Data ($data, $type = "s") {
switch($type)
{
case "s":
return mysql_real_escape_string($data); // returns string with escapes following characters: \x00, \n, \r, \, ', ", \x1a
case "i":
return (int)$data; // returns type integer
case "h":
return htmlspecialchars($data); // convert special characters to HTML entities
}
}


// receives data and put them in the database
if (!empty($_POST["name"])){
$name = Data ($_POST["name"]);

mysql_query("INSERT INTO names(name) VALUES('$name')")
or die("Error for DB: ".mysql_error());

header("Location: ".$_SERVER['PHP_SELF']);
exit;
}

// make select all names
$row = mysql_query("SELECT id,name FROM names ORDER BY id DESC")
or die(mysql_error());

// receiving and processing data from the search field
if(!empty($_GET["search"])){
$search = Data($_GET["search"]);

$found_names = mysql_query("SELECT name FROM names WHERE name LIKE '%". addcslashes($search, "%,_") ."%'")
or die ("Bug in search: ".mysql_error());
}

// receiving and processing data from global variable $_GET["id"] to display the date of registration
if(!empty($_GET["id"])){
$id = Data($_GET["id"], "i");
if($id>0)
{
$id_date = mysql_query("SELECT date,name FROM names WHERE id = $id")
or die(mysql_error());

$id_date = mysql_fetch_assoc($id_date);
}
}


//close connection
mysql_close();
?>

<form action="<?=$_SERVER['PHP_SELF'];?>" method="POST">
Registration:<br>
<
input type="text" name="name"><br>
<
input type="submit" value="Register"><br>
</
form>

<
form action="<?=$_SERVER['PHP_SELF'];?>" method="GET">
Searching:<br>
<
input type="text" name="search" value="<?=isset($_GET["search"]) ?$_GET["search"] :NULL?>">
<
br>
<
input type="submit" value="Search"><br>
</
form>


<?php
///////////////////OUTPUT///////////////////////////////////////
echo "<p>Total registered: ". mysql_num_rows($row) ." users</p>\n";

// output line date of registration
if(!empty($id_date)){
echo "<p>User <b>". Data($id_date["name"], "h") ."</b> registered: {$id_date["date"]}"."</p>\n";
}

// output the number of records found
if(!empty($found_names)){
echo "<p>Found similar records: ". mysql_num_rows($found_names) ."</p>\n";
}

// output the names found
if(!empty($found_names)){
$match = array();
?><ul><?php
while($match = mysql_fetch_assoc($found_names))
{
echo "\n\t<li>". Data($match["name"], "h") ."</li>\n";
}
?></ul><?php
}

// output all names in cycle
$user = array();
while($user = mysql_fetch_assoc($row)){
echo "\n<hr> User: <a href='". $_SERVER['PHP_SELF'] ."?id=". $user["id"] ."'>". Data($user["name"], "h") ."</a><br>\n";
}
?>

Спустя 1 час, 20 минут, 51 секунда (10.09.2012 - 15:17) twin написал(а):
Вот этого не понял:
Цитата
При отправке формы поля "name" из кириллическими символами выдает: Incorrect string value: '\xEA\xEE\xF2' for column 'name' at row 1
у меня нет такой ошибки.

Название функции Data() не многим лучше filterData(). Что за данные, зачем, почему... Причем в комментах же дано нормальное объяснение:
Цитата
function for processing the data
Само прям напрашивается processingData() smile.gif

И слэш обратный в поиске себя некорректно ведет.

Спустя 3 часа, 34 минуты, 13 секунд (10.09.2012 - 18:51) nefarius написал(а):
Цитата
При отправке формы поля "name" из кириллическими символами выдает: Incorrect string value: '\xEA\xEE\xF2' for column 'name' at row 1

Если у тебя нормально, то тогда это для меня загадка. blink.gif
Писал в Notepad++, изначально кодировка была в анси -> преобразовываю в utf-8 без bom -> сохраняю -> закрываю файл -> открываю файл -> смотрю, опять анси.
Может быть глупый вопрос, но может ли Notepad++ как нибудь на это повлиять? Возможно стоит попробывать чем то другим сохранить?

Спустя 11 минут, 48 секунд (10.09.2012 - 19:03) nefarius написал(а):
Релиз
<?php
error_reporting (E_ALL);

define ("DB_HOST", "localhost");
define ("DB_LOGIN", "root");
define ("DB_PASSWORD", "");
define ("DB_NAME", "names");

//connect to server
mysql_connect (DB_HOST, DB_LOGIN, DB_PASSWORD)
or die ("Error when connecting to server: " .mysql_error());
//select "names"
mysql_select_db (DB_NAME)
or die ("Error when selecting database {DB_NAME}: " .mysql_error());
//////////////////////////////////////////////////////////////////////////////////////////////////// ///////

// rewrite global varieble without magic_quotes_gpc
if (get_magic_quotes_gpc()) {
function stripslashes_gpc(&$value)
{
$value = stripslashes($value);
}
array_walk_recursive($_GET, 'stripslashes_gpc');
array_walk_recursive($_POST, 'stripslashes_gpc');
}


// function for processing the data
function processingData ($data, $type = "s") {
switch($type)
{
case "s":
return mysql_real_escape_string($data); // returns string with escapes following characters: \x00, \n, \r, \, ', ", \x1a
case "i":
return (int)$data; // returns type integer
case "h":
return htmlspecialchars($data); // convert special characters to HTML entities
}
}


// receives data and put them in the database
if (!empty($_POST["name"])){
$name = processingData ($_POST["name"]);

mysql_query("INSERT INTO names(name) VALUES('$name')")
or die("Error for DB: ".mysql_error());

header("Location: ".$_SERVER['PHP_SELF']);
exit;
}

// make select all names
$row = mysql_query("SELECT id,name FROM names ORDER BY id DESC")
or die(mysql_error());

// receiving and processing data from the search field
if(!empty($_GET["search"])){
$search = processingData($_GET["search"]);

$found_names = mysql_query("SELECT name FROM names WHERE name LIKE '%". addcslashes($search, "%_'\\") ."%'")
or die ("Bug in search: ".mysql_error());
}

// receiving and processing data from global variable $_GET["id"] to display the date of registration
if(!empty($_GET["id"])){
$id = processingData($_GET["id"], "i");
if($id>0)
{
$id_date = mysql_query("SELECT date,name FROM names WHERE id = $id")
or die(mysql_error());

$id_date = mysql_fetch_assoc($id_date);
}
}


//close connection
mysql_close();
?>

<form action="<?=$_SERVER['PHP_SELF'];?>" method="POST">
Registration:<br>
<
input type="text" name="name"><br>
<
input type="submit" value="Register"><br>
</
form>

<
form action="<?=$_SERVER['PHP_SELF'];?>" method="GET">
Searching:<br>
<
input type="text" name="search" value="<?=isset($_GET["search"]) ?$_GET["search"] :NULL?>">
<
br>
<
input type="submit" value="Search"><br>
</
form>


<?php
///////////////////OUTPUT///////////////////////////////////////
echo "<p>Total registered: ". mysql_num_rows($row) ." users</p>\n";

// output line date of registration
if(!empty($id_date)){
echo "<p>User <b>". processingData($id_date["name"], "h") ."</b> registered: {$id_date["date"]}"."</p>\n";
}

// output the number of records found
if(!empty($found_names)){
echo "<p>Found similar records: ". mysql_num_rows($found_names) ."</p>\n";
}

// output the names found
if(!empty($found_names)){
$match = array();
?><ul><?php
while($match = mysql_fetch_assoc($found_names))
{
echo "\n\t<li>". processingData($match["name"], "h") ."</li>\n";
}
?></ul><?php
}

// output all names in cycle
$user = array();
while($user = mysql_fetch_assoc($row)){
echo "\n<hr> User: <a href='". $_SERVER['PHP_SELF'] ."?id=". $user["id"] ."'>". processingData($user["name"], "h") ."</a><br>\n";
}
?>
user posted image

Спустя 2 часа, 32 минуты, 39 секунд (10.09.2012 - 21:35) twin написал(а):
Отличная работа user posted image

С кодировками я давно не эксперементирую, для меня utf-8 закон. Так что не подскажу тут на счет редактора. Наверное должно что-то ставиться по умолчанию.

Хвостик ?> в конце файла зря ставишь)) Вредно это.

Спустя 13 часов, 27 минут, 31 секунда (11.09.2012 - 11:03) nefarius написал(а):
Цитата
Хвостик ?> в конце файла зря ставишь))

Хорошо, уже почитал smile.gif
Спасибо тебе twin за поддержку! Очень помог разобраться!

Спустя 59 минут, 58 секунд (11.09.2012 - 12:03) Shuriken написал(а):
Цитата (twin @ 10.09.2012 - 18:35)
Хвостик ?> в конце файла зря ставишь)) Вредно это.

В чём вредность?

Спустя 5 минут, 8 секунд (11.09.2012 - 12:08) nefarius написал(а):
Вот здесь можно почитать

Спустя 2 часа, 41 минута, 44 секунды (11.09.2012 - 14:50) nefarius написал(а):
Разобрался с кодировкой.
Нужно было прописать вначале скрипта заголовок: header('Content-type: text/html; charset=utf-8');
Быстрый ответ:

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