|
|
|
| Задача N2. (Категория 2) Вывод из файла и запись в файл.
Условие:
Написать скрипт index.php, который выводит из файла data.txt
все строки с разделителем '=' в таблицу и имеет в конце форму с 1 полем
ввода text и 1 полем ввода textarea для передачи данных в скрипт-обработчик
script2.php. Обработчик заносит данные в файл data.txt с
разделителем '=' и возвращает пользователя обратно в index.php.
(мини-гостевая книга)
Примечание:
data.txt:
text1=text2
text3=text4
...
---------------------------------
Вопросы в тему не задаем. В условии достаточно информации для решения.
Если по вашему мнению необходимо внести в решение что-то не
описанное в условии - внесите с пояснениями для чего.
НЕ ПИШИТЕ ГРОМОЗДКИЕ конструкции со стилевыми оформлениями, старайтесь
уместить все в тот минимум кода, который будет просто работать правильно.
Все желающие пишут свои варианты решения (2 файла - index.php
и script2.php) и отправляют их на e-mail: fatboy@hotmail.kg
(еще продублируйте на e-mail: fatboy_php@mail.ru)
В заголовке письма пишется "Решение задачи N2".
В теле письма:
<?php
// скрипт index.php к задаче N2
// Фамилия, Имя, ФОРУМОВСКИЙ Ник
...
полное решение с комментариями и пояснениями
...
// end of index.php
?>
|
<?php
// скрипт script2.php к задаче N2
...
полное решение с комментариями и пояснениями
...
// end of script2.php
?>
|
Вложения не допускаются. Все решения будут проиндексированы
и выложены через 12-18 часов на форуме (без указания авторства) для
обсуждения. Обсуждение длится сутки, потом выкладываются
Ники авторов.
PS. Не стесняйтесь прислать свой вариант решения. | |
|
|
|
|
|
|
|
|
для: FatBoy
(31.01.2006 в 00:58)
| | Итак, ответы на задачу N2. (не забываем комментировать и оценивать) | |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:12)
| |
<?php
// скрипт index.php к задаче N2
// Решение 002-001
$file = 'data.txt';
if(isset($_GET['ok'])) { echo "Запись добавлена"; }
if(file_exists($file) && is_readable($file)) {
$records = file($file);
$total = count($records);
if($total > 0) {
echo "<table border=1>\r\n";
foreach ($records as $value) {
$rec = explode("=", $value);
// В следующих строках избавляемся от защиты = и \r\n
$item1 = stripslashes(str_replace('\\x3d', '=', $rec[0]));
$item2 = stripslashes(str_replace('\\x3d', '=', $rec[1]));
echo "<tr><td>" . $item1 . "</td><td>" . trim($item2) . "</td></tr>\r\n";
}
echo "</table>\r\n";
} else {
echo "Записей нет.";
}
} else {
echo "Ошибка чтения файла '" . $file . "'.";
}
?>
<br>
<form action="script2.php" method="POST">
<input type="text" name="item1"><br>
<textarea name="item2"></textarea><br>
<input type="submit" value="ok">
</form>
<!-- end -->
|
<?php
// скрипт script2.php к задаче N2
$file = 'data.txt';
if(file_exists($file) && is_writable($file)) {
if(isset($_POST['item1']) && isset($_POST['item2'])) {
$fp = fopen($file, "a");
if (!get_magic_quotes_gpc()) {
$_POST['item1'] = addslashes($_POST['item1']);
$_POST['item2'] = addslashes($_POST['item2']);
}
// Защищаем = и \r\n
$item1 = str_replace('=', '\\x3d', $_POST['item1']);
$item2 = str_replace('=', '\\x3d', $_POST['item2']);
fwrite($fp, $item1 . "=" . $item2 . "\r\n");
fclose($fp);
if(headers_sent()) {
// Если заголовки были отправлены значит уже что-то не то..
echo "Ошибка.";
} else {
header("Location: index.php?ok=1");
}
} else {
echo "Заполнены не все поля.";
}
} else {
echo "Ошибка записи в файл '" . $file . "'.";
}
?>
|
| |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:15)
| | Код компактный, хорошо читаемый, но не видно нигде htmlspecialchars(), а в файл могут запихать редирект или похищалку cookie. Мне не нравится использование шестнадцетиричного значения равно \x3d и отсутствия подробных коментариев на его счёт - это вынуждает лезть в справочник и смотреть, что же это за символ (а лазание в справочник - это лишнее время). | |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:12)
| |
<?php
// скрипт index.php к задаче N2
// Решение 002-002
# имя файла с данными
$filename = "data.txt";
# проверка существования файла
if (file_exists($filename)) {
# если файл существует...
# получим его содержимое в массив
$file = file($filename);
# проверим количество строк
if (count($file) !== 0) {
# выведем таблицу в цикле
echo("<table border=\"1\">");
foreach ($file as $line) {
# разбиваем строку
$line = explode("=", $line);
echo("<tr><td>".$line[0]."</td>");
echo("<td>".$line[1]."</td></tr>");
}
echo("</table>");
} # если строк нет, то ничего не выведется
} # если файла нет, ничего не выведется
?>
<!-- форма -->
<form action="script2.php" method="post">
<input type="text" name="field1" size="40"/><br />
<textarea name="field2" cols="30", rows="6"></textarea><br />
<input type="submit" />
</form>
<!-- end -->
|
<?php
// скрипт script2.php к задаче N2
# массив символов, подлежащих замене
$bad = array("\n", "\r", "=");
# проверка "магических" кавычек
if (get_magic_quotes_gpc()) {
# если включены, удаляем экранирование
# и заменяем "плохие" символы на пробел
$field1 = str_replace($bad, " ", stripslashes($_POST['field1']));
$field2 = str_replace($bad, " ", stripslashes($_POST['field2']));
} else {
# если выключены заменяем "плохие" символы на пробел
$field1 = str_replace($bad, " ", $_POST['field1']);
$field2 = str_replace($bad, " ", $_POST['field2']);
}
# строка для записи в файл
$data = $field1."=".$field2."\n";
# открытие файла
$file = fopen("data.txt", "at");
# запись в файл строки
fwrite($file, $data);
# закрытие файла
fclose($file);
# возвращаем пользователя назад
header("Location: index.php");
?>
|
| |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:19)
| | Прекрасная читабельность, однако также не используется htmlspecialchars(), и конструкцию
<?php
if (get_magic_quotes_gpc()) {
# если включены, удаляем экранирование
# и заменяем "плохие" символы на пробел
$field1 = str_replace($bad, " ", stripslashes($_POST['field1']));
$field2 = str_replace($bad, " ", stripslashes($_POST['field2']));
} else {
# если выключены заменяем "плохие" символы на пробел
$field1 = str_replace($bad, " ", $_POST['field1']);
$field2 = str_replace($bad, " ", $_POST['field2']);
}
?>
|
можно было бы исправить на
<?php
if (get_magic_quotes_gpc()) {
# если включены, удаляем экранирование
# и заменяем "плохие" символы на пробел
$_POST['field1'] = stripslashes($_POST['field1']);
$_POST['field1'] = stripslashes($_POST['field2']);
}
# если выключены заменяем "плохие" символы на пробел
$field1 = str_replace($bad, " ", $_POST['field1']);
$field2 = str_replace($bad, " ", $_POST['field2']);
?>
|
| |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:12)
| |
<!-- Задача N2 -->
<!-- Решение 002-003 -->
<!-- index.php -->
<html>
<head>
<title>index.php</title>
<meta content="text/html; charset=windows-1251" http-equiv=Content-Type>
</head>
<body>
<!-- Это шрифт. Так, для красоты. -->
<font face='Courier'>
<?php
$filename="./data.txt";
//Если файл существует
if ( file_exists($filename) )
{
//Чтение построчно в массив
$data=file($filename);
echo "<table width=500 align=center cellspacing=0 cellpadding=2 border=1>";
//Перебор массива $data
foreach($data as $content)
{
//Это - здоровая паранойя
//проверка на пустоту текущей строки
if($content==="")
{
continue;
}
//Разбиваем строку из файла на составляющие, а если в строке
//вообще символа "=" нет, переходим сразу к следующей (строке)
if(!$values=explode("=", $content))
{
continue;
}
echo "<tr>";
//Перебираем - это для универсальности кода
foreach($values as $text)
{
echo" <td valign=top>";
//Заменяем "безопасные строки" обратно
$text=str_replace("*#!equals!#*", "=", $text);
echo $text;
echo" </td>";
}
echo " </tr>";
}
echo "</table> ";
}
else
{
echo "Нет данных для отображения<br><br>";
}
?>
<br>
<b>Добавить:</b>
<form name='form' action='./script2.php' method='POST'>
TEXT:<br>
<input type=text name='text' size=20 value=''><br><br>
TEXTAREA:<br>
<textarea name='textarea' rows=5 cols=20></textarea><br><br>
<input type=submit name='action' value='GO'>
</form>
</font>
</body>
</html>
<!-- end of index.php-->
|
<!-- script2.php -->
<?php
//Это заголовок для кодировки
$header="
<html>
<head>
<title>script2.php</title>
<meta content=\"text/html; charset=windows-1251\"
http-equiv=Content-Type>
</head>
<body>
";
//Это массив с нежелательными и "безопасными" символами
$escape=array
(
"\n" => "",
"\r" => "",
"=" => "*#!equals!#*"
);
//Проверка на пустоту
if( empty($_POST['text']) || empty($_POST['textarea']) )
{
echo $header;
echo "Одно или оба поля пусты.<br>";
echo "<input type=button value='Назад' OnClick='javascript:history.back()'>";
exit;
}
//Попытка открыть файл
if(!$handle=fopen('./data.txt', 'at'))
{
echo $header;
echo "Не могу открыть файл.<br>";
echo "<input type=button value='Назад' OnClick='javascript:history.back()'>";
exit;
}
//Записываем две переменные в строку - чтобы не делать всё по два раза
$content=$_POST['text']."*#!divider!#*".$_POST['textarea'];
//Заменяем переводы строк на <br />
//и применяем как фильтр массив $escape
$content=nl2br($content);
$content=strtr($content, $escape);
//Разбиваем строку по константе *#!divider!#*, затем
//сворачиваем ее через "=" и добавляем в конец "\n"
$content=implode("=", explode("*#!divider!#*",
$content))."\n";
//Убираем теги и специальные символы HTML - защищаемся от XSS
$content=strip_tags($content);
$content=htmlspecialchars($content, ENT_QUOTES);
//Блокируем файл
flock($handle, LOCK_EX);
//Пишем в файл
if(fwrite($handle, $content) === FALSE)
{
echo $header;
echo "Не могу произвести запись в файл";
exit;
}
//Разблокируем и закрываем файл
flock($handle, LOCK_UN);
fclose($handle);
header("Location: ./index.php");
?>
<!-- end of script2.php-->
|
| |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:25)
| | Нет проверки на существование записей в файле data.txt, но и без неё всё прекрасно работает. Не смотря на некоторую громоздскость - код прекрасно читается. К достоинствам следует приписать то, что используется htmlspecialchars(), однако не очень удобно то, что применяется функция пред записью, в файл, а не при выводе в окно браузера - это может быть не очень удобно, особенно если текст будет редактироваться. | |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:12)
| |
<!--// Begin of index.php к задаче N2 -->
<!--// Решение 002-004 -->
<table border="1">
<?
$fn=array("<br>","","="); //вернем нужные символы
$rp=array('\n','\r',"="); //наши альтернативные символы
$filename="data.txt"; //чтобы не писать 2 раза
$file=fopen($filename,"r"); //открываем
$text=fread($file,filesize($filename)); //читаем
$text=explode("\r\n",$text); //разрезаем
for ($i=0;$i<sizeof($text)-1;$i++) { //зацикливаемся
$text[$i]=explode("=",$text[$i]); //двумерный массив удобен для дальнейшей обработки
echo"<tr><td>".str_replace($rp,$fn,$text[$i][0])."</td><td>".str_replace($rp,$fn,$text[$i][1])."</td></tr>"; //заменяем и печатаем
}
//форма:
?>
</table>
<form action=script2.php method=post>
<input type=text name=text1><br>
<textarea name=text2></textarea><br>
<input type=submit value="Записать">
</form>
<!--// end of index.php -->
|
<?
// Begin of script2.php к задаче N2
$fn=array("\n","\r","="); //проблемные символы
$rp=array('\n','\r',"="); //альтернативные сочетания символов
$text1 = str_replace($fn,$rp,$_POST['text1']); //заменяем
$text2 = str_replace($fn,$rp,$_POST['text2']);
$fp = fopen("data.txt", "a"); //открываем
fwrite($fp, "$text1=$text2\r\n"); //пишем
fclose($fp); //закрываем
header("Location: index.php"); //переезжаем
// end of script2.php
?>
|
| |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:34)
| | Хм... достаточно изящное решение, почему-то действительно никому в голову не пришло в прошлый раз использовать HTML-эквиваленты, хотя это практически промышленный стандарт. Хотя перед выводом в окно браузера не используется htmlspecialchars(), поэтому можно изменять проивольно дизайн, даже вводить дополнительные строки в таблице, похищать куки и т.п. | |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:12)
| |
<html>
<head>
<title>New document</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body>
<?
//скрипт index.php к задаче N2
// Решение 002-005
echo "<table>";
//открываем файл
$file = file("data.txt");
//делаем массив
foreach($file as $qk)
{
// разделяем =
list($text1,$text2) = explode("=", $qk);
// выводим данные
echo "<tr><td>".$text1."</td><td>".$text2."</td></tr>";
}
echo "</table>";
//выводим форму для добавления
?>
<br>
<form action=script2.php method=post>
<input type=text name=text1><br>
<textarea name=text2></textarea><br>
<input type=submit value="Записать">
</form>
</body>
</html>
|
<?php
//скрипт script2.php к задаче N2
// считываем переданные данные
$text1 = $_POST['text1'];
$text2 = $_POST['text2'];
// открываем файл для записи если его нет то создаем
$file = fopen("data.txt", "a");
// записываем данные в конец файла делаем переход строки
fwrite($file, "$text1=$text2\r\n");
// переходим на index.php
header("location: index.php");
?>
|
| |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:37)
| | а моего скрипта пока нет:( я его послал на меил.ру, т.к. на другой почтовый адрес у меня письмо не уходило | |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:37)
| | Минималистский стиль - очень наглядно и компактно, особенно следует отметить использование конструкции list() - число столцбов известно заранее и её использование оправдано, код с использованием list() становится легче читать. | |
|
|
|
|
|
|
|
для: cheops
(01.02.2006 в 18:20)
| | где-же мой скрипт? | |
|
|
|
|
|
|
|
для: FatBoy
(01.02.2006 в 14:12)
| | Я решил вместо оценок кода просто протестировать скрипты:
001
Не удаляет символы возврата коретки.
Не убивает HTML-теги.
data.txt
001=аыфа\x3dываыв
001=вава
вава
001=<hr>
|
002
Заменяет все символы на " ".
Не убивает HTML-теги.
002=ке ке
002=ке ке
002=<hr>
|
003
Не восстонавливае символы возврата коретки.
Искоренняет HTML-теги.
003=вапфывываав
003=ывфав*#!equals!#*выфавыфа
003=
|
004
Не убивает HTML-теги.
004=тест\r\nтест
004=тест=тест
004=<hr>
|
005
Скрипт вообще никак не реагирует на сибволы = и \n
Не убивает HTML-теги.
005=тест
тест
005=тест=тест
005=<hr>
|
| |
|
|
|
|
|
|
|
для: FatBoy
(31.01.2006 в 00:58)
| | Мои оценки данных скриптов следующие
N чит тонкс оригн
1 4 3 3
2 5 3 4
3 2 5 4
4 3 3 4
5 5 0 5
|
Читабельность выставлялась по пятибальной системе, тонкости столько сколько насчитал - оригинальность - это то насколько скрипт понравился.
Тонкости 001
Учитывается существование файлов
Учитывается =
Учитываются переводы строк
|
Тонкости 002
Учитывается существование файлов
Учитывается =
Учитываются переводы строк
|
Тонкости 003
Учитывается существование файлов
Учитывается =
Учитываются переводы строк
Используется htmlspecialchars() при выводе
Используется блокировка файлов
|
Тонкости 004
Учитывается =
Учитываются переводы строк
|
Тонкости 005
Учёт тонкостей не производится
|
| |
|
|
|
|
|
|
|
для: cheops
(03.02.2006 в 16:36)
| | где мой код?????????? | |
|
|
|
|
|
|
|
для: P@Sol
(03.02.2006 в 17:13)
| | Давайте тему в разном заведём. | |
|
|
|
|
|
|
|
для: FatBoy
(31.01.2006 в 00:58)
| | Cheops читает мои мысли, даже когда они ещё не пришли ко мне (оценки те же :)!
Пишу только недостатки. Всё, что не написано - нареканий не вызывает.
№1:
Мало комментариев. Строки покороче нужно сделать - длинные хуже воспринимаются. Шестнадцатиричные значения немного смущают.
№2:
Блок "if (magic_quotes)" нужно оптимизировать. Плохая фильтрация входящих данных.
№3:
Громоздко. Если бы не было оформления - было бы лучше. Идея с безопасными строками спорная. С одной стороны - хорошо, с другой - было бы лучше, если использовались мнемонические заменители.
№4:
Мало проверок.
№5:
Мало проверок. | |
|
|
|
|
|
|
|
для: Саня
(04.02.2006 в 00:02)
| | >Cheops читает мои мысли, даже когда они ещё не пришли ко мне
>(оценки те же :)!
Когда занимался наукой у нас ходила поговорка: всё о чём ты подумал уже придумали японцы :))) | |
|
|
|
|
|
|
|
для: cheops
(04.02.2006 в 01:24)
| | хм....потеряли мой скрипт :/ | |
|
|
|
|
|
|
|
для: P@Sol
(06.02.2006 в 13:28)
| | Начиная с задачи N3 действует автоматическая система регистрации ответов - теперь ничего не будет терятся - система либо обязательно зарегистрирует ответ, либо откажется его принимать, если время отведённое на решение закончилось. Приём заданий по задаче 3 закончилось - ответы по задаче 4 принимаются в форме http://www.softtime.ru/task/addthemeform.php?id_task=4 до четверга (в четверг подведение итогов и выкладывается новая задача). | |
|
|
|