Pull to refresh

Набор PHP-функции для создания user-friendly интерфейса на русском языке

Reading time7 min
Views1.3K
Почти в каждом своем проекте я использую набор функций, которые делают сайт чуточку приятнее для глаза и удобнее для восприятия. Эти функции я частично позаимствовал в разных местах и частично написал сам. Наверняка, многие используют подобные, но я решил все же поделиться — возможно, кому-то они будут полезны.

Они умеют склонять существительные по числовому признаку, выводить дату с нормальными русскими названиями месяцев и выводить дату в удобочитаемом человекопонятном виде (вчера, позавчера, 2 дня 3 часа и 2 минуты назад, через 1 год и 2 месяца и т.д.).

Использовать их можно примерно так:
<acrnonym title="<?php print r_date($timestamp'j M Y в H:i'false); ?>"><?php print human_date($timestamp2false);?></acronym>
<acrnonym title="<?php print r_date($timestamp'j M Y в H:i'); ?>"><?php print human_date($timestamp);?></acronym>


Это вернет примерно такой результат:
<acrnonym title="2 января 2009 в 23:39">1 день назад</acronym>
<acrnonym title="2 января в 23:39">Вчера</acronym>

(Хабр обрезает тег <acronym>)

И вот так:
<?php
$count 
10;
printf('%d %s'$countdeclension($count, array('комментарий''комментария''комментариев')));
?>


Это вернет:
10 комментариев

Собственно, функции:

<?php

/** 
* Склонение существительных по числовому признаку
*
* @var integer    Число, по которому производится склонение
* @var array    Массив форм существительного
* @return string Существительное в нужной форме

* Например:
* $count = 10;
* sprintf('%d %s', $count, declension($count, array('комментарий', 'комментария', 'комментариев')));
*
* Возвращает:
* 10 комментариев
*/
function declension($number$words) {
    
$number abs($number);
    if (
$number 20$number %= 10;
    if (
$number == 1) return $words[0];
    if (
$number >= && $number <= 4) return $words[1];
    return 
$words[2];
}

/** 
* Приводит дату к заданному формату с учетом русских названий месяцев
*
* В качестве параметров функция принимает все допустимые значения функции date(),
* но символ F заменяется на русское название месяца (вне зависимости от локали),
* а символ M — на русское название месяца в родительном падеже
*
* @var integer    Unix-timestamp времени 
* @var string    Формат даты согласно спецификации для функции date() с учетом замены значения символов F и M
* @var boolean    Флаг отсекания года, если он совпадает с текущим
* @return string Отформатированная дата
*/
function r_date($time ''$format 'j M Y'$cut_year true) {
    if(empty(
$time)) $time time();
    if(
$cut_year && date('Y') == date('Y'$time)) $format preg_replace('/o|y|Y/'''$format);
    
$month abs(date('n'$time)-1);
    
$rus = array('января''февраля''марта''апреля''мая''июня''июля''августа''сентября''октября''ноября''декабря');
    
$rus2 = array('январь''февраль''март''апрель''май''июнь''июль''август''сентябрь''октябрь''ноябрь''декабрь');
    
$format preg_replace(array("'M'""'F'"), array($rus[$month], $rus2[$month]), $format);
    return 
date($format$time);
}


/** 
* Выводит дату в приблизительном удобочитаемом виде (например, "2 часа и 13 минут назад")
*
* Необходимо наличие функции declension() для корректной работы
*
* @var integer    Unix-timestamp времени 
* @var integer    Степень детализации
* @var boolean    Флаг использования упрощенных названий (вчера, позавчера, послезавтра)
* @var string    Формат даты с учетом замены значения символов F и M, если объявлена функция r_date()
* @return string Отформатированная дата
*/
function human_date($timestamp$granularity 1$use_terms true$default_format 'j M Y') {
    
$curtime time();
    
$original $timestamp;
    
$output '';
    if(
$curtime >= $original) {
        
$timestamp abs($curtime $original);
        
$tense 'past';
    } else {
        
$timestamp abs($original $curtime);
        
$tense 'future';
    }
    
$units = array('years' => 31536000,
                 
'weeks' => 604800
                 
'days' => 86400
                 
'hours' => 3600
                 
'min' => 60
                 
'sec' => 1);
    
$titles = array('years' => array('год''года''лет'),
                 
'weeks' => array('неделя''недели''недель'), 
                 
'days' => array('день''дня''дней'), 
                 
'hours' => array('час''часа''часов'), 
                 
'min' => array('минута''минуты''минут'), 
                 
'sec' => array('секунда''секунды''секунд'));
    foreach (
$units as $key => $value) {
        if (
$timestamp >= $value) {
            
$number floor($timestamp $value);
            
$output .= ($output ? ($granularity == ' и ' ' ') : '') . $number .' 'declension($number$titles[$key]);
            
$timestamp %= $value;
            
$granularity--;
        }
    }
    if(
$tense == 'future') {
        
$output 'Через '.$output;
    } else {
        
$output .= ' назад';
    }
  if(
$use_terms) {
      
$terms = array('Через 1 день' => 'Послезавтра',
                     
'1 день назад' => 'Вчера',
                     
'2 дня назад' => 'Позавчера'
                     
);
      if(isset(
$terms[$output])) $output $terms[$output];
  }
  return 
$output $output : (function_exists('r_date') ? r_date($original$default_format) : date($default_format$original));
}
?>


Надеюсь, кому-нибудь они пригодятся.
Tags:
Hubs:
Total votes 59: ↑49 and ↓10+39
Comments26

Articles