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

Форум PHP

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

 

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

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

тема: ***** ЗАДАЧА N1 *****
 
 автор: FatBoy   (29.01.2006 в 21:18)   письмо автору
 
 

Задача N1.(Категория 1) Простая запись данных в файл.

Условие:
Написать скрипт-обработчик script1.php, который заносит
построчно в файл data.txt данные с разделителем '=',
полученные из формы index.html и возвращает пользователя
обратно в index.html.
Примечание:
Форма содержит 1 поле ввода text и 1 поле ввода textarea.
В итоге получаем data.txt:
text1=text2
text3=text4
...
---------------------------------


Вопросы не задаем. В условии достаточно информации для решения.
Если по вашему мнению необходимо внести в решение что-то не
описанное в условии - внесите с пояснениями для чего.

Все желающие пишут свои варианты решения (2 файла - index.html
и script1.php) и отправляют их на e-mail: fatboy@hotmail.kg.
В заголовке письма пишется "Решение задачи N1".
В теле письма:


<!-- index.html -->
<!-- Задача N1 -->
<!-- Фамилия, Имя, Ник -->
...
полное решение с комментариями и пояснениями
...
<!-- end -->

<?php
// скрипт к задаче N1
...
полное решение с комментариями и пояснениями
...
?>



Вложения не допускаются. Все решения будут проиндексированы
и выложены через 12-18 часов на форуме (без указания авторства) для
обсуждения. Обсуждение длится сутки, потом выкладываются
Ники авторов.

PS. Постараюсь не упустить тему на 2 страницу.

   
 
 автор: cheops   (30.01.2006 в 00:06)   письмо автору
 
   для: FatBoy   (29.01.2006 в 21:18)
 

Слишком много вопросов - все убрал. В этой теме обсуждаем только решение данной конкретной задачи. Все организацинные вопросы давайте в отдельной теме решать и в разделе "Разное". Тему закрываю до обозначенного времени.

   
 
 автор: FatBoy   (30.01.2006 в 14:41)   письмо автору
 
   для: FatBoy   (29.01.2006 в 21:18)
 

Для начала общее замечание для всех участников:
Я проверил все решения. Для этого я копировал все между <!-- index.html --> и <!-- end --> в index.html, а все между <?php и ?> в script1.php, а после искал файл data.txt и смотрел, что там есть. Поэтому встречались в HTML комментарии из PHP и наоборот. БУДТЕ ВНИМАТЕЛЬНЫ! и постарайтесь не переименовывать ничего.
И еще не забывайте подписываться: ФИО и НИК (имеется в виду SOFTTIME-овский)

   
 
 автор: FatBoy   (30.01.2006 в 15:16)   письмо автору
 
   для: FatBoy   (30.01.2006 в 14:41)
 

Вообще-то в данной задаче несмотря на кажущуюся простоту есть 5 моментов, на которые надо обратить внимание. Какие-то критичны, какие-то не очень, а про какие-то надо хотя бы знать (на будущее). Попробуйте перечислить ЭТИ 5 тонкостей!

   
 
 автор: FatBoy   (30.01.2006 в 14:43)   письмо автору
 
   для: FatBoy   (29.01.2006 в 21:18)
 


<!-- index.html --> 
<!-- Задача N1 --> 
<!-- Решение 001-001 --> 
<html>
<head>
<title>Задача N1</title>
</head>
<body>
<!-- форма. данные передаются методом "post" -->
<form action="script1.php" method="post">
<!-- поле text -->
<!-- визуальный размер установлен в 40 символов -->
<input type="text" name="text" size="40"><br
/>
<!-- поле textarea -->
<!-- длина - 30 символов, ширина - 5 символов -->
<textarea name="textarea" cols="30"
rows="5"></textarea><br />
<!-- кнопка посыла запроса -->
<input type="submit">
</form>

</body>
</html> 
<!-- end --> 



<?php 
// скрипт к задаче N1 
// имя файла, куда производится запись
$filename "data.txt";
// проверка существования файла
if (file_exists($filename)) {
  
// если файл существует - открываем его
  
$file fopen($filename"a");
} else {
  
// если файл не существует - создадим его
  
$file fopen($filename"w");
}
// данные из поля text
$text $_POST['text'];
// данные из поля textarea
// все переводы строки заменяются на пробелы
// "\r\n" - перевод строки в windows
$textarea str_replace("\r\n"" ",
$_POST['textarea'])."\r\n";
// формируем строку для записи в файл
$result $text."=".$textarea;
// записываем строку в файл
fwrite($file$result);
// закрываем файл
fclose($file);
// направляем пользователя на страницу с формой
header("Location: index.html");
?>

   
 
 автор: cheops   (30.01.2006 в 14:51)   письмо автору
 
   для: FatBoy   (30.01.2006 в 14:43)
 

Достоинства: хорошо комментирован
Недостатки: теряется форматирование в текстовой области textarea - в скрипте удаляются переводы строк, причём только Windows-переводы, при вводе UNIX пользователя и Mac-пользователя - переводы строк останутся. Лучше было экранировать переводы строк при помощи addcslashes(). Ну это так придраться было не к чему :))), ведь в условиях задачи ничего не говорится об дальнейшем использовании файла - может мы будем искать в нём отдельные слова - тогда переводы строк за даром не сдались... Однако при выводе в окно браузера или при редакрировании файла - это недостаток.

   
 
 автор: Artem S.   (30.01.2006 в 15:24)   письмо автору
 
   для: cheops   (30.01.2006 в 14:51)
 

Добавлю
Нет нужды применять file_exists, так как режим "a" сам может создать файл.

   
 
 автор: neudor   (30.01.2006 в 15:22)   письмо автору
 
   для: FatBoy   (30.01.2006 в 14:43)
 


if (file_exists($filename)) { 
  // если файл существует - открываем его 
  $file = fopen($filename, "a"); 
} else { 
  // если файл не существует - создадим его 
  $file = fopen($filename, "w"); 
}

Лишняя проверка file_exists, т.к. если файл не существуе, попытка открытия его с флагом "a" сама создаст пустой.

   
 
 автор: FatBoy   (30.01.2006 в 14:46)   письмо автору
 
   для: FatBoy   (29.01.2006 в 21:18)
 

<!-- index.html --> 
<!-- Задача N1 --> 
<!-- Решение 001-002 --> 

<form name="form1" method="post"
action="script1.php">
<input type="text" name="name">
<p><textarea cols=45 rows=5
name="endl"></textarea></p>
<p><input type="submit" name="Submit"
value="GO!!!"></p>
</form>

<!-- end -->



<!-- Скрипт script1.php --> 

<?
//получение данных из формы index.html
$a htmlspecialchars(trim($_POST['name']));
$b htmlspecialchars(trim($_POST['endl']));
//Проверка существовани файла
if (file_exists("data.txt")) $fp = @fopen("data.txt",'a');
else 
$fp = @fopen("data.txt",'w');
flock($fpLOCK_EX); // блокировка файла на запись
$data $a."=".$b."\r\n"// формируемая стора
if (fwrite($fp$data)) //проверка на запись
    
{
        
flock($fpLOCK_UN); //Снятие блокировки на запись
        
fclose($fp); //Закрытие файла
        
echo "<HTML><HEAD><META HTTP-EQUIV = 'Refresh' CONTENT='3;
URL=index.html'></HEAD></HTML>"
//перенаправление на
index.html
    
}
else exit(
"Ошибка при обращении к файлу data.txt"); // Если не удалось записать стоку то ошибка...
?>

   
 
 автор: cheops   (30.01.2006 в 14:55)   письмо автору
 
   для: FatBoy   (30.01.2006 в 14:46)
 

По сравнению с предыдущим вариантом не учитываются перводы строк, например, если пользователь введёт
text3\r\ntext20=text21

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

   
 
 автор: FatBoy   (30.01.2006 в 14:48)   письмо автору
 
   для: FatBoy   (29.01.2006 в 21:18)
 


<!-- Задача N1 -->
<!-- Решение 001-003 -->
<!-- index.html -->

<!--
#В файле index.html создается форма с именем form,
#которая передает две переменные text и textarea
#в файл script1.php
-->

<html>
<head>
<title>index.php</title>
<meta content="text/html; charset=windows-1251" 
http-equiv=Content-Type>
</head>
<body>

   <form name='form' action='./script1.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>
   
</body>
</html>

<!-- end of index.html-->



<!-- script1.php -->
<?php

//Создание переменной с заголовком (для определения кодировки)
$header="
<html>
<head>
<title>script1.php</title>
<meta content=\"text/html; charset=windows-1251\" 
http-equiv=Content-Type>
</head>
<body>
"
;

//Проверка - заполнены ли поля text и textarea
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;
}

//Замена символов перевода строки ("\r\n") в поле textarea на константу ("*#!return!#*")
$_POST['textarea']=str_replace("\r\n""*#!return!#*"
$_POST['textarea']);

//Замена символов "=" на константу в поле textarea
$_POST['textarea']=str_replace("=",
"*#!equals_in_textarea!#*"
$_POST['textarea']);

//Замена символов "=" на константу в поле text
$_POST['text']=str_replace("=""*#!equals_in_text!#*"
$_POST['text']);

//Формирование строки для записи в файл
$content=$_POST['text']."=".$_POST['textarea']."\n";

//Попытка записи
if(fwrite($handle$content) === FALSE)
{
     echo 
$header;
     echo 
"Ну могу произвести запись в файл";
     exit;
}

//Redirecting...
header("Location: ./index.html");
?>
<!-- end of script1.php-->

   
 
 автор: cheops   (30.01.2006 в 15:00)   письмо автору
 
   для: FatBoy   (30.01.2006 в 14:48)
 

Хм... вот что я называю здоровой параноей :))) Однако не учитывается UNIX-перевод строки \n и Mac-перевод строки \n\r. Правда, если в скрипте, который будет испльзовать data.txt будут использоваться только \r\n - это не имеет значение.

   
 
 автор: Artem S.   (30.01.2006 в 15:51)   письмо автору
 
   для: cheops   (30.01.2006 в 15:00)
 

>> Однако не учитывается UNIX-перевод строки \n ...
хеопс ты не обратил внимание на атрибут 'at', этим всем теперь занимается php

Пример хороший, вот только что грамозкий ;)

   
 
 автор: cheops   (30.01.2006 в 18:18)   письмо автору
 
   для: Artem S.   (30.01.2006 в 15:51)
 

А да просмотрел, именно поэтому сам параметром t не пользуюсь - очень легко из вида опустить.

PS Кстати, для промышленного применения и для работы в команде компактность скрипта и его прозрачность действительно имеет большое значение. Пренебрегать ею допускается только если необходимо обеспечить повышенную защиту и/или скорость работы.

   
 
 автор: Саня.   (30.01.2006 в 17:08)
 
   для: cheops   (30.01.2006 в 15:00)
 

Это что же? У каждой ОС свой символ перевода строки? У windows - "\r\n", у *nix - "\n", у mac - "\n\r"; а у альфы перевод строки случайно не "\n\r\n"? :))

P. S.
Что за дела? "Ошибка идентификации, попробуйте ещё раз, возможно ваша регистрация ещё не подтверждена"

   
 
 автор: Artem S.   (30.01.2006 в 18:16)   письмо автору
 
   для: Саня.   (30.01.2006 в 17:08)
 

Перевожу:

Саня:
Это что же? У каждой ОС свой символ перевода строки? У windows - "\r\n", у *nix - "\n", у mac - "\n\r"; а у альфы перевод строки случайно не "\n\r\n"? :))

P. S.
Что за дела? "Ошибка идентификации, попробуйте ещё раз, возможно ваша регистрация ещё не подтверждена"

   
 
 автор: FatBoy   (30.01.2006 в 14:50)   письмо автору
 
   для: FatBoy   (29.01.2006 в 21:18)
 

Я немного отступил от поставленной задачи, у меня два файла -
index.php (не html - вот это и есть отступление) и script1.php


<!-- index.php -->
<!-- Задача ? 1 -->
<!-- Решение 001-004 -->
<?
////////////////////////////////////////
//                                                                        //
//  Скрипт к задаче 1 на http://softtime.ru  //
//                                                                       //
////////////////////////////////////////
//Стартуем сессию
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

        <head>
                <meta http-equiv="content-type"
content="text/html;charset=windows-1251">
                <meta name="generator" content="Adobe
GoLive">
                <title>Решение задачи 1</title>
                <style type="text/css" media="screen"><!--
td { font-size: 10px; font-family: Verdana; font-weight: bold; padding: 5px;
border: solid 1px #666 }
input  { font-size: 10px; font-family: Verdana; font-weight: bold; border: solid
1px #666 }
textarea { font-size: 10px; font-family: Verdana; font-weight: bold; border:
solid 1px #666 }
--></style>
        </head>

        <body bgcolor="#ffffff">
        <div align="center">
                        <form  action="script1.php"
method="post" >
                                                <table width="400"
border="0" cellspacing="0" cellpadding="0">
<?
//Небольшое отступление от поставленной задачи - я сделал вывод сообщения о том что заполнены не все поля ввода
//Сделал это через сессию 
//Файл обработчик увидев пустое поле ввода, записывает в сессию сообщение об ошибке и посылает юзера обратно
//А здесь если сообщение об ошибке в сессии определено , оно показывается пользователю
if(!empty($_SESSION['mess']))
{
                
$mess $_SESSION['mess'];
                
//Сообщение об ошибке уничтожается, чтобы не показалось в следующий раз
                
$_SESSION['mess'] = "";
                echo 
'<tr><td colspan="2"><font
color="red">'
.$mess.'</font></td></tr>';
}
?>
                                                        <tr>
                                                                <td>Поле
ввода текста типа text</td>
                                                                <td
valign="top"><input type="text" name="val1"
size="20"></td>
                                                        </tr>
                                                        <tr>
                                                                <td>Поле
ввода текста типа textarea</td>
                                                               
<td><textarea name="val2" rows="4"
cols="20"></textarea></td>
                                                        </tr>
                                                        <tr>
                                                                <td
colspan="2" align="center" valign="top"><input
type="submit"  value="Послать"></td>
                                                        </tr>
                                                </table>
                                        </form>
                </div>
        </body>

</html>
<!--end -->



<?php
//////////////////////////////////////////
//                                                                           //
// Скрипт к задаче 1 на http://sofftime.ru      //
//                                                                           //
//////////////////////////////////////////
//Стартанули сессию
session_start();
//Проверили заполненность полей ввода
if((empty($_POST['val1']))||(empty($_POST['val2'])))
{
                
$_SESSION['mess'] = "Вы заполнили не все поля";
                
header("Location: ".$_SERVER['HTTP_REFERER']);
                exit();
}
//Проверили наличие файла data.txt
//Если его нет открываем файл с флагом "w"  - создание нового файла и запись данных
if(!file_exists("data.txt"))
{
                
$f fopen("data.txt""w");
}
//Если он есть открываем файл с флагом "a" - добавление данных в конец файла
else
{
                
$f fopen("data.txt""a");
}
//Пишем в файл данные
fputs($f$_POST['val1']."=".$_POST['val2']."\n");
//Закрываем файл
fclose($f);
//Шлюм юзера туда откуда он пришел
header("Location: ".$_SERVER['HTTP_REFERER']);
?>

   
 
 автор: FatBoy   (30.01.2006 в 14:51)   письмо автору
 
   для: FatBoy   (29.01.2006 в 21:18)
 


<!-- index.htm -->
<!-- Задача 1 -->
<!-- Решение 001-005 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
 <head>
  <title>Задача 1.</title>
 </head>
 <body>
  <form action="script1.php" method="post">
   <input type="text" name="text"
size="35"><br>
   <textarea name="textarea" WRAP="virtual"
COLS="26" ROWS="3"></TEXTAREA><br>
   <input name="submit" value="Отправить"
type="submit">
  </form>
 </body>
</html>
<!-- end -->



<!-- script1.php -->
<?

//
// Проверяем заполнены ли поля, если нет, то присваевываем переменной значение <none>.
// Это сделано потому, что в условии не сказано, что поля должны заполняться обязательно.
//

if(!$_POST["text"])
{
        
$_POST["text"] = "<none>";
}
if (!
$_POST["textarea"])
{
        
$_POST["textarea"] = "<none>";
}


$filename "bd.txt"// имя файла в который будут записываться данные, в последствии переменную можно вынести в конфигурационный файл
$fp fopen($filename,"a"); // открытие файла на добавление, если файла не существует, то  он создается

//
//Если не удалось открыть файл, выводим сообщение об ошибке и ссылку на страницу с формой
//

if (!$fp)
{
        echo 
"Не удалось открыть файл!<br>";
        echo 
"<a href=index.htm>Назад</a>";
        exit;
}

$text =
$_POST["text"]."=".$_POST["textarea"]."\n";
// составляем строку
fwrite($fp,$text); // записываем строку в файл

fclose($fp); //закрываем файл

print "<script>window.location.href='index.htm'</script>";
//переходим на index.htm
?>
<!-- end -->


PS. от FatBoy Cheopsу - в этой задаче были комментарии "слэш-звездочка" - они не отобразились по итогу - заменил на "//" (хотя именно здесь надо было показать ошибку)

   
 
 автор: Loki   (30.01.2006 в 16:30)   письмо автору
 
   для: FatBoy   (30.01.2006 в 14:51)
 

В скрипте логическая ошибка:
в случае если в поля будут введены нули, то в файле окажется

<none>=<none>


А вообще забавная развлекалочка:)
предлагаю следующей темой сделать вывод на экран "Hello world!". Посмотрим какие народ задействует технологии:))))

   
 
 автор: FatBoy   (30.01.2006 в 14:58)   письмо автору
 
   для: FatBoy   (29.01.2006 в 21:18)
 


<!-- index.html -->
<!-- Задача N1 -->
<!-- Решение 001-006 -->
На index.html расположена форма отправки данных.  Script1.php
обрабатывает данные и записывает в файл data.txt
<!-- end -->

<html>     // содержит форму для отправки данных
<head>
<title>index.html</title>
</head>
<body>
<form action="script1.php" method="post">
<input type="text" name="text1">     // поле для ввода
<br>
<textarea name="text2"></textarea>   // текстовое поле
<br>
<input type="submit" value="Send">   // кнопка отправки
</form>
</body>
</html>



<?php
$text1 
$_POST['text1'];  // считываем переданные данные
$text2 $_POST['text2'];
$file fopen("data.txt""a");  // открываем файл для дозаписи (если файла data.txt не существует создаем его)
fwrite($file$text1." = ".$text2.""); // записываем данные в конец файла
header("location: index.html");  // возвращаемся на index.html
?>

   
 
 автор: cheops   (30.01.2006 в 15:04)   письмо автору
 
   для: FatBoy   (30.01.2006 в 14:58)
 

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

   
 
 автор: PantiL   (30.01.2006 в 16:52)   письмо автору
 
   для: cheops   (30.01.2006 в 15:04)
 

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

А на самом деле интересно сколько решения есть у такой простецкой задачки

   
 
 автор: cheops   (30.01.2006 в 18:22)   письмо автору
 
   для: PantiL   (30.01.2006 в 16:52)
 

Тоже старался это подчеркнуть, именно поэтому мне больше всего понравилось последнее решение - я бы тоже пренебрёг защитой, так как скрипт очень смахивает на скрипт из системы администрирования, а администратор вряд ли будет что-либо ломать. В условиях задачи ничего не говорится о том, чтобы обходить такие ньюансы как переводы строк и знаки равно. Тем не менее следует учитывать, что эта тему будет темой ответов на первую задачу.

   
 
 автор: cheops   (30.01.2006 в 18:32)   письмо автору
 
   для: FatBoy   (29.01.2006 в 21:18)
 

Продолжение в теме http://www.softtime.ru/forum/read.php?id_forum=1&id_theme=12366. Слишком длинная эта тема получается.

   
Rambler's Top100
вверх

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