Добро пожаловать!
Здесь вы можете найти ответ на интересующий вас вопрос в отрасли сайтостроения, познакомится ближе с web технологиями и web стандартами.

Статьи

FAQические задачи

Изначально, я задумывал эту статью для рассмотрения наиболее частых вопросов, которые возникают у читателей при написании PHP-кода. Но потом решил немного изменить направление, так как часто возникающие вопросы не всегда интересны и могут не привлечь внимание основной массы web-кодеров. Более предпочтительно, на мой взгляд, будет объяснить решение интересных задач, с которыми ко мне обращаются читатели.

Задача №1

Имеется две даты, требуется вычислить, сколько дней в промежутке между ними. Также, эта задача интерпретировалась как вычисление количества дней, которые остались до определенной даты. Например, отсчет дней до наступления Нового года. На первый взгляд, довольно не просто заниматься вычислением количества дней в промежутке между датами, которые указаны, к примеру, так: 24.04.07 и 31.12.07. Тут нужно учитывать очень большое количество мелочей. Но все это решается простым применением функции mktime(). С ее помощью можно получить указанную дату в виде количества секунд. Далее с этим огромным сплошным числом можно будет запросто проводить арифметические операции. В нашем случае это будет вычитание.

Рассмотрим код, который определяет, сколько осталось дней до 31-го декабря 2007-го года:

<?php
$today 
date'd.m.Y' ); // сегодняшняя дата
$need_date '31.12.2007'// требуемая дата

// получаем массив со значениями дня, месяца и года
$need explode'.'$need_date );
// перевод в кол-во секунд
$begin mktime000date('m'), date('d'), date('Y'));
$end mktime000$need[1], $need[0], $need[2] );
// количество дней
$days_num round( ($end $begin) / 84600 ) ;
// вывод результата
echo '<b><font size=5><font color=red>'.$today.
     
'</font> - <font color=green>'.$need_date.
     
'</font> = <font color=blue>'.$days_num.
     
'</font></font></b>';
?>

На рисунке 1 показан результат работы этого скрипта. У нас есть два даты, сегодняшняя и дата, которую мы ожидаем. После того как мы перевели их в секунды, функцией mktime(), можно получить разницу. Полученное значение нужно преобразовать в количество дней. Для этого достаточно разделить результат на 84600 (количество секунд в одном дне). В некоторых случаях, число будет дробным, для этого мы делаем округление с помощью функции round().

Задача №2

У одних эта задача возникала сразу, как только они справлялись с задачей №1, другие сталкивались с ней в иных примерах. Задача состоит в том, чтобы в зависимости от количества оставшихся дней корректно выводить слово «день». Например, правильно сказать: «осталось 3 дня», но если дней будет пять, то в результате получится «осталось 5 дня». Учет всех комбинаций можно автоматизировать, подставляя верный вариант строки. Код, который выполняет проверку:

<?php
//количество дней
$remaind 1;

$m10 $remaind 10//получение последней цифры числа
$m100 $remaind 100//получение двух последних цифр

//значение строки по умолчанию
$str ' дней';

//если заканчивается на 1, но предыдущая цифра не равна единице
if ( ($m10 == 1) && ($m100 != 11) )
$str ' день';
//если заканчивается на 2, 3, или 4, но предыдущая не 1
if ( (($m10 == 2) || ($m10 == 3) || ($m10 == 4))
&& (
$m100 != 12) && ($m100 != 13) && ($m100 != 14) )
$str ' дня';

echo 
$remaind.$str.'<br />';
?>

Всего может быть три варианта: «день», «дней» или «дня». Изначально мы устанавливаем значение как «дней», потому как оно будет использоваться в большинстве случаев. Затем идет проверка, если последняя цифра равна 2, 3 или 4, а предпоследняя цифра – это не единица, то строка должна быть - «дня». Проверка предпоследней цифры обеспечивает, чтобы выводило, например, «23 дня», но «113 дней». В случае, если последняя цифра равна 1, а предшествующая любой другой или ее вовсе нет, то результатом будет строка «день». Например, «1 день» или «131 день», но «211 дней».

Задача №3

Пользователь имеет три поля для ввода: начало ссылки, конец ссылки и их количество, которое нужно сгенерировать. Допустим, введены значения: начало – "http://localhost/file", конец – ".zip", количество – 100. При таких значениях должен создаваться txt-файл, каждая строка которого представляет из себя ссылки вида:

http://localhost/file001.zip
http://localhost/file002.zip
............................
http://localhost/file100.zip

Важным правилом есть заполнение нулями в начале имени файла. То есть, если бы количество ссылок было 1000, они имели бы вид: file0001.zip и т.д. Если бы не этот момент, то все решалось бы в одном цикле. Данная задача требует выполнения цикла while() вложенного в тело цикла for().

Код решения:

<?php
// форма для ввода параметров
echo '<form action=linker.php method=POST>
      Начало: <input type=text name=begin value='
.
      (!empty(
$_POST["begin"])?$_POST["begin"]:"http://localhost/file").
     
' size=55><p>
      Конец: <input type=text name=end value='
.
      (!empty(
$_POST["end"])?$_POST["end"]:".zip").
     
' size=10><p>
      Кол-во: <input type=text name=kolvo value='
.
      (!empty(
$_POST["kolvo"])?$_POST["kolvo"]:"10").
     
' size=10><br/><p>
      <input type=submit value=Создать>
      </form>'
;

//если переданы все параметры
if ( !empty($_POST['begin']) && !empty($_POST['end']) && !empty($_POST['kolvo']) )
{
  
// запись текстового файла
  
$fp fopen'linker.txt''w' );

  for ( 
$i=1$i<=$_POST['kolvo']; $i++ ) {
    
$str ''.$i;
    
// вложенный цикл для заполнения нулями
    
while (strlen($str) != strlen($_POST['kolvo'])) $str '0'.$str;
    
// запись ссылки в файл
   
fwrite($fp$_POST['begin'].$str.$_POST['end'].chr(13).chr(10));
  }

  
// закрыть файл
  
fclose$fp );
  
// вывод ссылки на текстовый файлы
  
echo '<p align=center><font color=red size=4>Файл 
        <a href="linker.txt">linker.txt</a> успешно записан!</font></p>'
;
}
?>

Вывод формы показан на рисунке 2. После выполнения создается или перезаписывается (если он уже существует) текстовый файл с именем linker.txt. В нем будут записаны все сгенерированные ссылки.

Задача №4

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

Несмотря на то, что задача вызывает немалые затруднения, код ее решения довольно компактный. Создайте текстовый файл данных links.txt, в котором будут храниться ссылки для случайных переходов. Теперь создайте скрипт с именем links.php и напишите в нем такой код:

<?php
$path 
file('links.txt'); // получение массива строк

$min 0//начальная строка
$max count($path)-1// конечная строка

$num rand($min$max); // случайная строка в пределах файла

header('Location:'.$path[$num]); // переход по указанной ссылке
?> 

Задача №5

У нас есть массив. Как можно отправить и затем, без всяких изменений извлечь его для дальнейшей работы. Такой вопрос возникал в самых разных задачах, причем до неприличия часто :). Хотя, должен отметить, об этой возможности не рассказывалось ни в одной из моих статей. Сейчас будем заполнять этот пробел :). В PHP для такой «консервации» массивов существует две полезные функции. Функция serialize() преобразовывает массив в строку, после чего с помощью функции unserialize() можно получить опять полноценный массив. Для примера представлю решение одной из задач. Запись и извлечение массива из cookie. Код скрипта serial.php:

<?php
//открытие массива из cookie
if ( !empty($_POST['open']) && !empty($_COOKIE['array']) ) {
  
//преобразование массива из строки
  
$mass unserialize($_COOKIE['array']);
  
//вывод содержимого массива на экран
  
foreach($mass as $key => $value) echo $value.'<br/>';
}

// сохранение массива в cookie
if ( !empty($_POST['save']) ) {
  
//инициализируем массив разными значениями
  
$mass['key1'] = 'key 1';
  
$mass['key2'] = 'key 2';
  
$mass['key3'] = 'key 3';
  
$mass['key4'] = 'key 4';
  
// преобразование массив в строку
  
$cookie_arr serialize($mass);
  
// запись cookie
  
setcookie('array'$cookie_arrtime()+86400);
}

// вывод формы для выбора действия
echo '<form action="serial.php" method="POST">
      <input type=submit value="Сохранить массив" name="save" />
      <input type=submit value="Открыть массив" name="open" />
      </form>'
;
?> 

Форма выполняющая все действия показана на рисунке 3. При нажатии на кнопку «Сохранить массив», мы совершаем преобразование массива в строку, которую в дальнейшем записываем в cookie на 1 день (84600 секунд). Нажимая кнопку "Открыть массив", мы считываем строку из cookie. С помощью обратной функции unserialize() мы получаем массив из строки. После этого можно для проверки вывести массив на экран.

Заключение

Заметьте, что эта статья была составлена не мной, а читателями и ее содержание определялось исключительно ими же. Это значит, что здесь мог быть рассмотрен и ваш вопрос. В дальнейшем, при скоплении подборки интересных задач, возможно выйдет продолжение разбора читательских "траблов" :). Свои вопросы, идеи, пожелания и все остальное (кроме спама :)), можете направлять на e-mail: heel@heel.org.ua. Также это можно сделать у меня на сайте: www.HeeL.org.ua.

Источник: http://www.heel.org.ua
Автор: Сергей Парижский