|
|
|
| Не уверен, что еще принимаются решения по задачам PHP (http://www.softtime.ru/info/task.php?id_article=72). Но, так как я начинающий, то мне это интересно и полезно.
Единственно смущает, будет ли комментарий от Игоря Вячеславовича, все-таки времени-то многовато прошло...
Вот мой код:
<?php
##########################
#### Файл index.php ####
##########################
//Функция вывода элементов массива в строки таблицы
function arraytotable($massive)
{
//Создаем таблицу
echo "<table border=1 cellspacing=0 cellpadding=5 width=90%>";
//Проходим циклом по элементам массива
foreach($massive as $row)
{
//Заносим в массив левую и правую части строки
$pieces = explode("=", $row);
//Создаем новую строку
echo "<tr>";
//Создаем левую ячейку таблицы и вставляем первый элемент массива
echo "<td>$pieces[0]</td>";
//Создаем правую ячейку таблицы и вставляем второй элемент массива
echo "<td>$pieces[1]</td>";
//Закрываем строку таблицы
echo "</tr>";
}
// и закрываем таблицу
echo "</table><br><br>";
}
//Определяем в переменную имя файла
$fn = 'data.txt';
//Проверяем его существование
if(!file_exists($fn))
{
echo "В гостевой книге пока нет записей. Вы можете быть первым!";
}
else
{
//Читаем файл в массив
$arr = file($fn);
//Вызываем функцию
arraytotable($arr);
}
//Форма ввода данных
?>
<form action="script2.php" method="post">
Текстовое поле:<br>
<input type="text" name="txt" size=50 value=""><br>
Поле для комментария:<br>
<textarea name="area" cols=39 rows=5></textarea><br><br>
<input type="submit" name="btn" value="Отправить">
</form>
|
Второй скрипт:
<?php
##########################
### Файл script2.php ###
##########################
//Определяем в переменную имя файла
$fn = 'data.txt';
//Заносим в переменные данные из полей
$txt = $_POST['txt'];
$area = $_POST['area'];
//Удаляем ненужные символы = в данных и
//преобразовываем специальные символы в HTML сущности
$text = str_replace("=","",htmlspecialchars($txt));
$area = str_replace("=","",htmlspecialchars($area));
//Образуем результирующую строку
$result = "$txt=$area\r\n";
//Открываем файл записи в конец файла.
//Если не существует, то создается.
$fd = @fopen($fn, "ab");
//Блокируем файл
flock($fd, LOCK_EX);
//Записываем данные в файл
fwrite($fd, $result);
//Закрываем файл
fclose($fd);
//Возвращаемся к таблице с данными и форме
header("Location:index.php");
?>
|
| |
|
|
|
|
|
|
|
для: baston
(16.03.2010 в 20:35)
| | 1. Первое что бросается в глаза - это отсутствие обработки "магических кавычек", данные поступают по POST-каналу, и если режим магических кавычек включен (а часто так и бывает), то кавычки ' и " будут экранированы \' и \", т.е. данные будут искажены.
2. Немного неудобно то, что htmlspecialchars() используется перед записью в файл, а не после. Т.е. если нужно будет отредактировать информацию в исходном виде - потребуется устранять последствия работы htmlspecialchars() или редактировать прямо так с HTML-эквивалентами.
3. Если в текстовую область поместить переводы строки - скрипт работает не корректно.
Попробуете исправить с учетом замечаний ;-)? | |
|
|
|
|
|
|
|
для: cheops
(17.03.2010 в 00:54)
| | Для И.В. (cheops):
Исправил :)
1. Добавил в файл script2.php функцию проверки на активность магических кавычек.
2. Использую htmlspecialchars() непосредственно при выводе в таблицу.
3. Не уверен на 100%, но добавил trim() для переводов строк. Вроде работает (по-крайней мере, в результирующем файле data.txt нет пустых строк).
Для Trianon:
Сделал проще (на мой взгляд). Я просто в результирующий файл записываю данные в таком виде:
text1|=|text2
В этом случае, нет нужды и удалять знаки равенства, и соответственно разделяем подстроки уже по разделителю |=|
Вот итоговые скрипты:
<?php
##########################
### INDEX.PHP ###
##########################
//Функция вывода элементов массива в строки таблицы
function arraytotable($massive)
{
//Создаем таблицу
echo "<table border=1 cellspacing=0 cellpadding=5 width=90%>";
//Проходим циклом по элементам массива
foreach($massive as $row)
{
//Заносим в массив левую и правую части строки
$pieces = explode("|=|", $row);
//Создаем новую строку
echo "<tr>";
//Создаем левую ячейку таблицы и вставляем первый элемент массива
echo "<td>".htmlspecialchars($pieces[0])."</td>";
//Создаем правую ячейку таблицы и вставляем второй элемент массива
echo "<td>".htmlspecialchars($pieces[1])."</td>";
//Закрываем строку таблицы
echo "</tr>";
}
// и закрываем таблицу
echo "</table><br><br>";
}
//Определяем в переменную имя файла
$fn = 'data.txt';
//Проверяем его существование
if(!file_exists($fn))
{
echo "В гостевой книге пока нет записей. Вы можете быть первым!";
}
else
{
//Читаем файл в массив
$arr = file($fn);
//Вызываем функцию
arraytotable($arr);
}
//Форма ввода данных
?>
<form action="script2.php" method="post">
Текстовое поле:<br>
<input type="text" name="txt" size=50 value=""><br>
Поле для комментария:<br>
<textarea name="area" cols=39 rows=5></textarea><br><br>
<input type="submit" name="btn" value="Отправить">
</form>
|
<?php
##########################
### SCRIPT2.PHP ###
##########################
## Функция обработки "магических кавычек" (удаление слешей)
function delslashes($val)
{
//Получаем необработанные данные из поля без крайних пробелов
$result = trim($_POST[$val]);
//Удаляем переводы строк
$result = trim($result, '\r\n');
//Если ф-я Magic Quotes активна, то удаляем слеши
if(get_magic_quotes_gpc()) $result = stripslashes($result);
return $result;
}
//Заносим в переменные данные из полей
$txt = delslashes("txt");
$area = delslashes("area");
//Образуем результирующую строку
$result = "$txt|=|$area\n";
//Определяем в переменную имя файла
$fn = 'data.txt';
//Открываем файл записи в конец файла.
//Если не существует, то создается.
$fd = @fopen($fn, "at");
//Блокируем файл
flock($fd, LOCK_EX);
//Записываем данные в файл
fwrite($fd, $result);
//Закрываем файл
fclose($fd);
//Возвращаемся к таблице с данными и форме
header("Location:index.php");
?>
|
| |
|
|
|
|
|
|
|
для: baston
(17.03.2010 в 14:35)
| | >3. Не уверен на 100%, но добавил trim() для переводов строк. Вроде работает (по-крайней мере, в результирующем файле data.txt нет пустых строк).
Так Вы вместе "из купели вместе с водой ребенка выплеснули".
Суть в том, что неплохо было бы сделать так, чтобы скрипт мог спокойно работать с многострочным текстом, без искажения данных и нарушений логики.
>Для Trianon:
>Сделал проще (на мой взгляд). Я просто в результирующий файл записываю данные в таком виде:
>text1|=|text2
>В этом случае, нет нужды и удалять знаки равенства, и соответственно разделяем подстроки уже по разделителю |=|
Нет. Это не решение.
Теперь внутрь текста невозможно записать разделитель |=|
Принципиально ничего не изменилось.
Даже если Вы придумаете суперпупермегасложный разделитель, я отвечу, что не получится его применить в тексте.
Подсказка. Разделитель может быть простым. А решение - на файловом уровне совместимым с тем, которое требуется исходными условиями. | |
|
|
|
|
|
|
|
для: Trianon
(17.03.2010 в 15:05)
| | >>3. Не уверен на 100%, но добавил trim() для переводов строк. Вроде работает (по-крайней мере, в результирующем файле data.txt нет пустых строк).
>
>Так Вы вместе "из купели вместе с водой ребенка выплеснули".
>Суть в том, что неплохо было бы сделать так, чтобы скрипт мог спокойно работать с многострочным текстом, без искажения данных и нарушений логики.
Тут загвоздка в том, что браузер не видит таких переводов строк как \n \r, а теги br заменяются функцией htmlspecialchars()... | |
|
|
|
|
|
|
|
для: baston
(17.03.2010 в 17:18)
| | >Тут загвоздка в том, что браузер не видит таких переводов строк как \n \r, а теги br заменяются функцией htmlspecialchars()...
Значит нужно написать так, чтобы не заменялись. | |
|
|
|
|
|
|
|
для: baston
(17.03.2010 в 17:18)
| | Дмитрий! По первому вашему замечанию о многострочных данных решил так:
В скрипте script2.php в функции удаления слешей я добавил выражение по замене переводов строк на тег br:
function delslashes($val)
{
//Получаем необработанные данные из поля без крайних пробелов
$result = trim($_POST[$val]);
//Если в строке есть переводы строк, то заменяем их на теги <br>
$result = str_replace("\r\n", "<br>", $result);
//Если ф-я Magic Quotes активна, то удаляем слеши
if(get_magic_quotes_gpc()) $result = stripslashes($result);
return $result;
}
|
В скрипте index.php я тоже изменил логику и сделал так (создал второй массив из строк второй части и потом добавляю тег br для вывода в браузер в таблицу):
foreach($massive as $row)
{
//Заносим в массив левую и правую части строки
$pieces = explode("=", $row);
$second = explode("<br>", $pieces[1]);
//Создаем новую строку
echo "<tr>";
//Создаем левую ячейку таблицы и вставляем первый элемент массива
echo "<td>".htmlspecialchars($pieces[0])."</td>";
echo "<td>";
for($i=0; $i<count($second); $i++)
{
//Создаем правую ячейку таблицы и вставляем второй элемент массива
echo htmlspecialchars($second[$i])."<br>";
}
echo "</td>";
//Закрываем строку таблицы
echo "</tr>";
}
|
Таким образом мы решили проблему многострочных строк :)
Теперь буду думать над знаком =. | |
|
|
|
|
|
|
|
для: baston
(17.03.2010 в 17:55)
| | теперь Вам текстовую строку <br> не ввести. | |
|
|
|
|
|
|
|
для: Trianon
(17.03.2010 в 18:31)
| | Дмитрий, вы писали:
>...А решение - на файловом уровне совместимым с тем, которое требуется исходными условиями.
Не могли бы вы дать больше подсказок? Перебрал практически все функции по работе с файлами и строками - ничего не подходит.
Может не там ищу?
Но я не использую функции, которые удаляют html-теги, типа fgetss() или strip_tags(), так как это противоречило бы правилу "пользователь может ввести что-угодно, а мы выводим только допустимое".
Спасибо. | |
|
|
|
|
|
|
|
для: baston
(18.03.2010 в 13:41)
| | Как нетрудно предположить, исходные условия не предполагают применение знака равенства во вводимых полях. И хранение многострочных данных тоже не предполагают.
Грубо говоря, в файле на каждой строке может (и должен) быть один и только один символ = . Разделяющий поля в записи.
Остается лишь придумать такой расширенный синтаксис строк, в котором два и более символа = описывают все оставшиеся случаи. | |
|
|
|
|
|
|
|
для: Trianon
(18.03.2010 в 13:54)
| | Придумал так.
1) При записи данных из полей ввода в файл:
- заменяю знаки = на их HTML сущность (=).
2) При выводе в браузер из файла:
- ищу регуляркой нужные мне части из строки;
- декодирую каждую часть (до знака = и после), чтобы получить из сущности натуральный знак =;
- вставляю части в ячейки таблицы (уже вновь кодированные, но знак = не кодируется).
В итоге думаю, что эта часть задачи решена :)
По многострокам пока не соображу как можно сделать. Думаю, что аналогично, но боюсь запутаться.
Вот результат (прошу покритиковать мой способ). Да, если мы вводим в поля html-cущность знака =, то она преобразуется в знак =.
##########################
### SCRIPT2.PHP
##########################
//Функция обработки "магических кавычек" (удаление слешей)
function delslashes($val)
{
//Получаем необработанные данные из поля без крайних пробелов
$result = trim($_POST[$val]);
//Если в строке есть переводы строк, то заменяем их на теги <br>
$result = str_replace("\r\n", "<br>", $result);
//Если в строке встречаются знаки =, то заменяем их HTML-сущностью (=)
$result = str_replace("=", "=", $result);
//Если ф-я Magic Quotes активна, то удаляем слеши
if(get_magic_quotes_gpc()) $result = stripslashes($result);
return $result;
}
//Заносим в переменные данные из полей
$txt = delslashes("txt");
$area = delslashes("area");
//Образуем результирующую строку
$result = "$txt=$area\r\n";
//Определяем в переменную имя файла
$fn = 'data.txt';
//Открываем файл записи в конец файла.
//Если не существует, то создается.
$fd = @fopen($fn, "at");
//Блокируем файл
flock($fd, LOCK_EX);
//Записываем данные в файл
fwrite($fd, $result);
//Закрываем файл
fclose($fd);
//Возвращаемся к таблице с данными и форме
header("Location:index.php");
|
##########################
### INDEX.PHP
##########################
//Функция вывода элементов массива в строки таблицы
function arraytotable($massive)
{
//Создаем таблицу
echo "<table border=1 cellspacing=0 cellpadding=5 width=90%>";
//Проходим циклом по элементам массива
foreach($massive as $row)
{
//Шаблон поиска частей строки
$pattern = "#((^[^=]+)={1}(.+))#i";
//Заносим в переменную результат поисков
$res = preg_match($pattern, $row, $arr);
//Получаем для вывода в браузер строки с декодированным знаком =
$left = html_entity_decode($arr[2]);
$right = html_entity_decode($arr[3]);
//Создаем новую строку
echo "<tr>";
//Создаем левую ячейку таблицы и вставляем первый элемент массива
echo "<td>".htmlspecialchars($left)."</td>";
//Создаем правую ячейку таблицы и вставляем второй элемент массива
echo "<td>".htmlspecialchars($right)."</td>";
//Закрываем строку таблицы
echo "</tr>";
}
// и закрываем таблицу
echo "</table><br><br>";
}
//Определяем в переменную имя файла
$fn = 'data.txt';
//Проверяем его существование
if(!file_exists($fn))
{
echo "В гостевой книге пока нет записей. Вы можете быть первым!";
}
else
{
//Читаем файл в массив
$arr = file($fn);
//Вызываем функцию
arraytotable($arr);
}
//Форма ввода данных
?>
<form action="script2.php" method="post">
Текстовое поле:<br>
<input type="text" name="txt" size=50 value=""><br>
Поле для комментария:<br>
<textarea name="area" cols=39 rows=5></textarea><br><br>
<input type="submit" name="btn" value="Отправить">
</form>
|
| |
|
|
|
|
|
|
|
для: baston
(18.03.2010 в 17:27)
| | Бесполезно. | |
|
|
|
|
|
|
|
для: Trianon
(18.03.2010 в 22:26)
| | Дмитрий, почему?
Знак = не теряется в этом случае. | |
|
|
|
|
|
|
|
для: baston
(18.03.2010 в 23:44)
| | ага.
зато теряется такая вот строка из пяти символов:
и такая - из четырех:
| |
|
|
|
|
|
|
|
для: Trianon
(19.03.2010 в 02:03)
| | Верно. Я об этом и указал в своем сообщении выше:
>Да, если мы вводим в поля html-cущность знака =, то она преобразуется в знак =.
Про переводы строк я еще не придумал как обойти.
Дмитрий, хорошо. А вы можете показать конкретный способ решения этой проблемы? Просто неделю бьюсь и видимо не в том направлении. Ну, нет у меня опыта...
Буду благодарен. | |
|
|
|
|
|
|
|
для: baston
(19.03.2010 в 07:27)
| |
<?php
$esc_pattern = "
(?i: # начало эскейпа
== # эскейп
( # начало кода
[0-9A-F] # Шестнадцатеричная цифра
{2} # дважды
) # конец кода
) # конец эскейпа
";
$field_pattern = "
# начало строки
( # начало поля
(?: # начало повтора
($esc_pattern)# эскейп_код
| # либо
([^=]*) # строка любых символов кроме =
) # конец повтора
* # произвольное число раз
) # конец поля
";
$fld1="Cпасибо, =Вася=!";
$fld2="C =новым= годом!
Всегда =Ваша=,
крыша.";
echo "<pre>";
echo "-0-\r\n";
echo "$fld1 \r\n";
echo "$fld2 \r\n";
$fld1enc = str_replace(array('=', chr(0), chr(0xD), chr(0xA)),
array('==3D','==00', '==0D','==0A'),
$fld1);
$fld2enc = str_replace(array('=', chr(0), chr(0xD), chr(0xA)),
array('==3D','==00', '==0D','==0A'),
$fld2);
echo "-1-\r\n";
echo "$fld1enc \r\n";
echo "$fld2enc \r\n";
$text = "$fld1enc=$fld2enc";
echo "-2-\r\n";
echo "$text \r\n";
$res = preg_match("/^$field_pattern/x", $text, $matches);
$len1 = $res ? strlen($matches[0]) : 0;
$fld1enc = $matches[0];
if(@$text[$len1] != '=') return '-1 -- no field separator';
if(@$text[$len1+1] == '=') return '-2 -- internal parse error';
$fld2enc = substr($text, $len1+1);
echo "-3-\r\n";
echo "$fld1enc \r\n";
echo "$fld2enc \r\n";
$res = preg_match("/^$field_pattern/x", $fld2enc, $matches);
$len2 = $res ? strlen($matches[0]) : 0;
if($len2 != strlen($fld2enc)) return '-3 -- internal parse error';
$fld1 = preg_replace("/$esc_pattern/xe", 'chr(hexdec("\\1"))', $fld1enc);
$fld2 = preg_replace("/$esc_pattern/xe", 'chr(hexdec("\\1"))', $fld2enc);
echo "-4-\r\n";
echo "$fld1 \r\n";
echo "$fld2 \r\n";
echo "---\r\n";
?>
|
| |
|
|
|
|
|
|
|
для: Trianon
(19.03.2010 в 21:58)
| | Да-а-а...
Дмитрий, до такого кода я ни в жизнь бы не додумался на том этапе развития в PHP, на котором я сейчас нахожусь.
Но, спасибо за урок!
Я вот попроще сделал (без учета многострочного ввода). Зато не надо думать о "паразитных" символах. Вытаскиваем нужные части строк и всех делов.
<?php
##########################
### INDEX.PHP
##########################
//Функция вывода элементов массива в строки таблицы
function arraytotable($massive)
{
//Создаем таблицу
echo "<table border=1 cellspacing=0 cellpadding=5 width=90%>";
//Проходим циклом по элементам массива
foreach($massive as $row)
{
//Находим позицию последней открывающей скобки
$start = mb_strrpos($row, "(", "UTF-8");
//Находим позицию последней закрывающей скобки
$end = mb_strpos($row, ")", $start+1, "UTF-8");
//Находим позицию разделяющего цифры двоеточия
$dotdot = mb_strpos($row, ":", $start+1, "UTF-8"); //позиция до двоеточия
//Вытаскиваем цифры после скобки и до двоеточия
$lnum = mb_substr($row, $start+1, $dotdot - $start-1, "UTF-8");
//Вытаскиваем цифры после двоеточия и до закрывающей скобки
$rnum = mb_substr($row, $dotdot+1, $end - $dotdot-1, "UTF-8");
//Вытаскиваем текст левой части строки
$lstr = mb_substr($row, 0, $lnum, "UTF-8");
//Вытаскиваем текст правой части строки
$rstr = mb_substr($row, $lnum+1, $start - $lnum-1, "UTF-8");
//Создаем новую строку
echo "<tr>";
//Создаем левую ячейку таблицы и вставляем первый элемент массива
echo "<td>".htmlspecialchars($lstr)."</td>";
//Создаем правую ячейку таблицы и вставляем второй элемент массива
echo "<td>".htmlspecialchars($rstr)."</td>";
//Закрываем строку таблицы
echo "</tr>";
}
// и закрываем таблицу
echo "</table><br><br>";
}
//Определяем в переменную имя файла
$fn = 'data.txt';
//Проверяем его существование
if(!file_exists($fn))
{
echo "В гостевой книге пока нет записей. Вы можете быть первым!";
}
else
{
//Читаем файл в массив
$arr = file($fn);
//Вызываем функцию
arraytotable($arr);
}
//Форма ввода данных
?>
<form action="script2.php" method="post">
Текстовое поле:<br>
<input type="text" name="txt" size=50 value=""><br>
Поле для комментария:<br>
<textarea name="area" cols=39 rows=5></textarea><br><br>
<input type="submit" name="btn" value="Отправить">
</form>
|
<?php
##########################
### SCRIPT2.PHP
##########################
//Функция обработки "магических кавычек" (удаление слешей)
function delslashes($val)
{
//Получаем необработанные данные из поля без крайних пробелов
$result = trim($_POST[$val]);
//Если в строке есть переводы строк, то заменяем их на теги <br>
//$result = str_replace("\r\n", "<br>", $result);
//Если ф-я Magic Quotes активна, то удаляем слеши
if(get_magic_quotes_gpc()) $result = stripslashes($result);
return $result;
}
//Заносим в переменные данные из полей
$txt = delslashes("txt");
//Вычисляем длину строки текстового поля
$ltxt = mb_strlen($txt, "UTF-8");
$area = delslashes("area");
//Вычисляем длину строки комментария
$larea = mb_strlen($area, "UTF-8");
//Образуем результирующую строку и в конец
//строки записываем данные по длинам строк в
//формате (длина_строки:длина_комментария)
$result = "$txt=$area($ltxt:$larea)\n";
//Определяем в переменную имя файла
$fn = 'data.txt';
//Открываем файл записи в конец файла.
//Если не существует, то создается.
$fd = @fopen($fn, "at");
//Блокируем файл
flock($fd, LOCK_EX);
//Записываем данные в файл
fwrite($fd, $result);
//Закрываем файл
fclose($fd);
//Возвращаемся к таблице с данными и форме
header("Location:index.php");
?>
|
| |
|
|
|
|
|
|
|
для: baston
(19.03.2010 в 22:42)
| | вот поэтому я и написал "бесполезно".
Какая разница, какой будет код?
Я предложил подумать над алгоритмом.
И подсказок дал вполне достаточно.
Ваш вариант с разметкой тоже допустим. Достоинство - отсутствие последовательного разбора массового потока данных. Индексную часть, конечно, разобрать придется.
Я не понял, правда, зачем нужно было индекс запинывать в хвост строки, а на в начало.
Не потребовался бы поиск скобки.
Кстати проблему многострочных данных таким образом тоже можно решить - Вы просто не стали думать..
Главный же недостаток - отсутствие портабельности на уровне формата файла с Хеопсовой задачей. | |
|
|
|
|
|
|
|
для: Trianon
(20.03.2010 в 00:35)
| | "Я не волшебник. Я только учусь" (C).
При всем к вам уважении и с благодарностью, подсказки меня только запутывали больше. Но здесь, я думаю, проблема не в ваших подсказках, а в моих пока небольших познаниях и слабой логике. Все-таки я не программист...
Решил в конец записывать индекс потому что мыслю шаблонно, увы.
Про многостроки решил было пока не думать, следовало решить основную задачу - ввод любых данных от пользователя не разбирая, а сохраняя. Теперь буду думать и над этим.
Вы написали:
>Главный же недостаток - отсутствие портабельности на уровне формата файла с Хеопсовой >задачей.
Вот даже такое простое предложение я не могу понять. Как говориться, слова понимаю, но связать в единую логику для себя никак...
Мне бы попроще разьяснить, что вы имели в виду? Переносимость для других операционок?
Спасибо. | |
|
|
|
|
|
|
|
для: baston
(20.03.2010 в 08:31)
| | >Главный же недостаток - отсутствие портабельности на уровне формата файла с Хеопсовой >задачей.
>Мне бы попроще разьяснить, что вы имели в виду?
Я имею в виду то, что файл вида
Москва=Россия
Киев=Украина
Минск=Беларусь
|
, подготовленный программами согласно исходным условиям задачи N2,
не будет корректно отображен в виде таблицы Вашим скриптом, ожидающим индекс в конце каждой строки. | |
|
|
|
|
|
|
|
для: Trianon
(19.03.2010 в 21:58)
| | Trianon, а разве нельзя проще?
Перед сохранением в файл заменяем символы & и = на их html эквиваленты, переводы строк экранируем. При выводе, заменяем html эквиваленты = и & на соответствующие символы, переводы строк разэкранируем и заменяем на <br>.
Для примера, сделал в одном файле, отчего получилось несколько громоздко, за то удобнее проверить.
<?php
function escape ($str) {
return str_replace(
array('&', '=', "\n", "\r"),
array('&', '=', "\\n", "\\r"),
$str
);
}
function unescape ($str) {
return nl2br(htmlspecialchars(
str_replace(
array('=', '&', "\\n", "\\r"),
array('=', '&', "\n", "\r"),
$str
)
));
}
$filename = 'data.txt';
$error = '';
if ($_POST) {
if (get_magic_quotes_gpc()) {
$_POST['fld1'] = stripslashes($_POST['fld1']);
$_POST['fld2'] = stripslashes($_POST['fld2']);
}
if ($_POST['fld1'] === '' or $_POST['fld2'] === '')
$error = 'Нужно заполнить все поля.';
else {
$fp = fopen($filename, 'a');
fwrite($fp, escape($_POST['fld1']).'='.
escape($_POST['fld2'])."\n"
);
fclose($fp);
header('Location: '.$_SERVER['PHP_SELF']);
exit;
}
}
if (file_exists($filename) and filesize($filename)) {
$messages = file($filename, FILE_IGNORE_NEW_LINES);
$rows = '';
$count = count($messages);
for ($i=0; $i < $count; $i++) {
$rows .= '<tr><td>';
$rows .= implode(
'</td><td>',
array_map('unescape', explode('=', $messages[$i]))
);
$rows .= '</td></tr>';
}
}
?>
<html>
<head>
<title>Задача №2</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body>
<table border="1">
<tr><td><b>fld1</b></td><td><b>fld2</b></td></tr>
<?php
if (isset($rows))
echo $rows;
else
echo '<tr><td colspan="2">Записей нет.</td></tr>';
?>
</table><br>
<?php echo $error ? '<b style="color: #800;">'.$error.'</b><br>' : '' ?>
<form action="" method="post">
<b>fld1</b><br><input type="text" name="fld1"><br>
<b>fld2</b><br><textarea name="fld2"></textarea><br><br>
<input type="submit" value="Отправить">
</body>
</html>
|
| |
|
|
|
|
|
|
|
для: Drago
(20.03.2010 в 02:10)
| | Можно, конечно.
Но совместимость с файлами исходных условий задачи будет утрачена. | |
|
|
|
|
|
|
|
для: Trianon
(20.03.2010 в 11:04)
| | Не совсем понял почему вы так решили. В моем решении как и используется формат файла из исходных условий задачи.
При этом, text1, text2, text3, text4 могут содержать любые символы. В том числе знаки "=" и переводы строк. | |
|
|
|
|
|
|
|
для: Drago
(20.03.2010 в 11:35)
| | >Не совсем понял почему вы так решили. В моем решении как и используется формат файла из исходных условий задачи.
>text1=text2
>text3=text4
>При этом, text1, text2, text3, text4 могут содержать любые символы. В том числе знаки "=" и переводы строк.
Всю обедню портит вот этот массив: array('&', '=', "\\n", "\\r"),
достаточно написать
&=так кодируется амперсанд
==так кодируется знак равенства
\r=так кодируется CR
\n=так кодируется LF
|
и несовместимость проявится. | |
|
|
|
|
|
|
|
для: Trianon
(20.03.2010 в 12:58)
| | Спасибо, теперь понял, что вы имели ввиду.
Также, увидел что экранирование одних "\n" и "\r" - не выход и лучше экранировать всю строку функцией addslashes().
Однако, разве ваш вариант не хранит строки в обработанном виде?
То есть, на сколько я понял, в файле, у вас, получается должна лежать запись вида:
Cпасибо, ==3DВася==3D!=C ==3Dновым==3D годом!==0D==0A Всегда =3DВаша==3D,==0D==0A крыша.
|
Тогда, если файл будет следующего содержания:
==3D=так кодируется знак равненства
==0D==0A =а так символы перевода строки
|
Что выведет ваш скрипт? | |
|
|
|
|
|
|
|
для: Drago
(20.03.2010 в 13:42)
| | Исходный формат предполагал отсутствие значимых символов '=' и переводов строк в рабочем файле.
PS. Вы можете упрекнуть меня в том, что, строго говоря, отсутствие знаков равенства предполагалось лишь в левой части текста.
Ну так не всё ж мне решать задачки. Я оставляю пространство и для чужих решений. :)
Строгое решение задачи в общем случае невозможно.
Возможно лишь приближение к нему - через жертву некоторого множества исключений, которое новым скриптом будет отображаться не так, как старым.
Этот факт "невозможность строгого решения" - следствие непродуманности структуры данных на этапе проектирования.
PPS. Впрочем, нет.
Можно сделать практически строгое решение. С некоторой потерей совместимости, но уже в обратную сторону.
Оно, правда, будет не самым быстрым. И настолько запутанным, что в реальной жизни овчинка перестанет стоит выделки абсолютно, но тем не менее. | |
|
|
|
|
|
|
|
для: Trianon
(20.03.2010 в 13:47)
| | > Вы можете упрекнуть меня в том, что, строго говоря, отсутствие знаков равенства предполагалось лишь в левой части текста.
Хочу упрекнуть вас несколько в другом. :)
Если Исходный формат предполагал отсутствие значимых символов '=' и переводов строк в рабочем файле., то почему сделали такое замечание: Теряются знаки равенства в исходных тексте и комментарии.?
И второе, утверждая что предложенные решения не совместимы с файлами исходных условий задачи, вы предложили точно такой же вариант решения, не совместимый с файлами исходных условий задачи.
В остальном согласен. :) | |
|
|
|
|
|
|
|
для: Drago
(20.03.2010 в 15:52)
| | почему же он несовместим?
Строки, порожденные скриптами, построенными по исходным условиям, и не содержащие = и переносов строк в данных, обрабатываются моим вариантом переносимым образом.
>И второе, утверждая что предложенные решения не совместимы с файлами исходных условий задачи, вы предложили точно такой же вариант решения, не совместимый с файлами исходных условий задачи.
Не надо. Я говорил о несовместимости про решения, которые затрагивали символы ни коим образом не вовлеченные в исходный формат хранения. | |
|
|
|
|
|
|
|
для: Trianon
(19.03.2010 в 21:58)
| | Дмитрий, а вы не могли пояснить один момент из регулярок, которые используете.
и
Что это?
Знак вопроса является модификатором для поиска необязательно текста.
А что он у вас в вашем варианте означает, не могу понять... Поясните пожалуйста.
По-крайней мере честно пытался найти ответ в регулярках, но увы...
Интересуют только указанные части вашей регулярки.
Спасибо. | |
|
|
|
|
|
|
|
для: baston
(24.03.2010 в 13:21)
| | Антон, Вы пытаетесь рассматривать отдельные символы вне контекста, в котором они применены.
Отсюда и неясности.
Знак вопроса является модивикатором необязательности только после квантификатора.
А в этом контексте это часть синтакстса незахватывающей маски - маски, которая не порождает элемент выходного массива.
В PCRE в этот синтаксис можно встраивать модификаторы шаблона для подмаски. В частности i поставлен затем, чтобы сделать отлов шестнадцатеричных вставок регистронезависимым. | |
|
|
|
|
|
|
|
для: Trianon
(24.03.2010 в 21:15)
| | Спасибо.
Я изучал брошюру "Регулярные выражения" (не Фридла) и там были описаны варианты некоторых незахватывающих масок. Что-то типа: ?< (поиск назад...).
А об этом варианте (?:) я не знал. Теперь буду знать. И нашел допинфу об этом. | |
|
|
|
|
|
|
|
для: baston
(25.03.2010 в 08:14)
| | Да уж, труд Фридла даже по сильной задумчивости брошюрой не назовешь.
Тем не менее читается он достаточно легко, особенно если не спешить.
А эффект дает весьма ощутимый.
Я не так давно страдал стойкой идиосинкразией к регулярным выражениям.
Вылечился только благодаря Фридлу. И Хеопсу, который мне его посоветовал. | |
|
|
|
|
|
|
|
для: Trianon
(25.03.2010 в 10:05)
| | Дмитрий, со зряплаты думаю купить. Дороговато, даже для меня, но что делать...
Могу читать только бумажные книги.
Брошюра была от Бена Форта из серии "10 минут на урок". Легкая и простая для начала изучения. Теперь вижу, что ее мне мало было. | |
|
|
|
|
|
|
|
для: baston
(25.03.2010 в 13:04)
| | Книга Дж.Фридла доступна для скачивания с портала.
Я в свое время скачал и распечатал. | |
|
|
|
|
|
|
|
для: baston
(25.03.2010 в 08:14)
| | Введите в строку формы как отреагирует обработчик ? | |
|
|
|
|
|
|
|
для: oliss
(25.03.2010 в 10:14)
| | А что там за баг?
По листингу (19.03.2010 в 22:42) подвоха не нашел.
Может, правда, невнимательно искал... | |
|
|
|
|
|
|
|
для: oliss
(25.03.2010 в 10:14)
| | Да, ошибка вывалится и некорректность в таблице.
Согласен, что код нехорош с точки зрения работоспособности в любых ситуациях. Сам недоволен.
Я учусь лишь только. Спасибо за выявленную ошибку. Изобретать велосипед не буду, а возьму на вооружение ваши наработки и при необходимости буду решать. | |
|
|
|
|
|
|
|
для: baston
(25.03.2010 в 16:17)
| | Не дам решения ; )
Решите сами ,как получится,налейте себе ( ? ) грамм коньяка ; ) ) ) | |
|
|
|
|
|
|
|
для: oliss
(25.03.2010 в 17:02)
| | Ваши наработки, опубликованные выше. :)
Только не удаляйте, пользуясь своим служебным положением (если такое в ваших силах). | |
|
|
|
|
|
|
|
для: Trianon
(17.03.2010 в 15:05)
| | >Нет. Это не решение.
>Теперь внутрь текста невозможно записать разделитель |=|
>Принципиально ничего не изменилось.
Я бы предложил принудительно менять введенный пользователем = на ==
А в качестве разделителя по прежнему использовать |=|. Таким образом |=| будет разделителем, а введенный пользователем |=| превратится в |==| (а введенный пользоватиелем |==| превратится в |====| ;)
А перевод строки можно подменять, например, на #=#. Алгоритм тот же | |
|
|
|
|
|
|
|
для: skykub
(21.04.2010 в 11:22)
| | как отличить перевод строки от хвостового и начального # ? | |
|
|
|
|
|
|
|
для: baston
(16.03.2010 в 20:35)
| | И еще одно замечание.
Теряются знаки равенства в исходных тексте и комментарии.
Попробуйте сделать так, чтоб не терялись.
Это трудно, но возможно. | |
|
|
|
|
|
|
|
для: Trianon
(17.03.2010 в 00:59)
| | Дмитрий, у меня родилась еще одна идея :) Вот же неугомонный!
А что, если нам делить строку не по разделителю, а по позиции?
Это значит, мы определяем длину строки в каждом поле (не будем принимать во внимание многострочность). Эти данные (например в таком виде - 12:16) мы заносим в конец каждой строки через определенный разделитель (собственно, это не важно).
Далее мы считываем эти цифры и соответственно делим строку: первая часть равна первым цифрам, вторая часть - вторым.
Таким образом, нам совершенно не важно что используется в качестве разделителя и мы ничего таким образом не теряем.
Как на ваш взгляд? | |
|
|
|
|