Форум программистов, компьютерный форум, киберфорум
Наши страницы
PHP
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.84/266: Рейтинг темы: голосов - 266, средняя оценка - 4.84
Даниэль
0 / 0 / 0
Регистрация: 21.08.2014
Сообщений: 5
#1

Обмен готовыми решениями

02.07.2008, 12:02. Просмотров 48054. Ответов 91
Метки нет (Все метки)

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?PHP 
echo getfilesize($_GET['name']); 
 
// Функция для определения размера 
function getfilesize($filename) 
{ 
  // Проверяем, существует ли файл 
  if(!file_exists($filename)) return "файл не существует"; 
  // Определяем размер файла 
  $filesize = filesize($filename); 
  // Если размер файл превышает 1024 байта, 
  // пересчитываем размер в Кбайты 
  if($filesize > 1024) 
  { 
    $filesize = (float)($filesize/1024); 
    // Если размер файл превышает 1024 Кбайта, 
    // пересчитываем размер в Мбайты 
    if($filesize > 1024) 
    { 
      $filesize = (float)($filesize/1024); 
      // Округляем дробную часть до 
      // первого знака после запятой 
      $filesize = round($filesize, 1); 
      return $filesize." Мб"; 
    } 
  } 
  else 
  { 
    return $filesize." байт"; 
  } 
} 
?>
Взято с [Ссылка удалена!]

 Комментарий модератора 
Если хотите поделиться готовыми решениями, то выкладывайте их в эту тему, а не ссылки на Ваш форум и сайт
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.07.2008, 12:02
Ответы с готовыми решениями:

Обсуждение класса постраничной навигации из темы "Обмен готовыми решениями"
Выделено из темы: http://www.cyberforum.ru/php/thread158262-page2.html Para...

Обмен между php и javascript
$.ajax({ url: './', type: 'POST', data: {reg_login:...

обмен данными между серверами
Всем доброго времени суток! Пишу дипломную работу, тема - модуль обмена...

Обмен сообщениями
Как отправить сообщение через свой сайт в браузер тому кто на сайте (без...

Обмен сообщениями (новичек)
Вопрос такой: как грамотно организовать обмен сообщениями между пользователями,...

91
Para bellum
Эксперт PHP
4032 / 3007 / 958
Регистрация: 06.01.2011
Сообщений: 8,827
24.04.2015, 18:40 #41
Ссылка на исходный класс, который адаптирован под bootstrap: Обмен готовыми решениями
Но для тех, кто столкнётся с вопросом, который озвучил VLK, решил доработать. Немного переделал класс навигации:
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
<?php
    /*
    * Класс для генерации постраничной навигации
    */
    class Pagination
    {
        /**
        * 
        * @var Активных ссылок навигации на страницу.
        * Т.е. ссылок, помимо текущей (активной) ссылки и ссылок влево-вправо.
        * 
        */
        private $max = 6;
        
        /**
        * 
        * @var Ключ для GET, в который пишется номер страницы
        * 
        */
        private $index = 'page';
        
        /**
        * 
        * @var Текущий GET-запрос
        * 
        */
        private $query;
        
        /**
        * 
        * @var Текущая страница
        * 
        */
        private $current_page;
        
        /**
        * 
        * @var Общее количество записей
        * 
        */
        private $total; 
        
        /**
        * 
        * @var Записей на страницу
        * 
        */
        private $limit;
        
        /**
        * 
        * @var Массив с классами для элементов
        * 
        */
        private $classes = [
            'ul' => 'pagination',
            'li' => null,
            'a'  => null
        ];
        
        /**
        * Запуск необходимых данных для навигации
        * @param integer $total - общее количество записей
        * @param integer $limit - количество записей на страницу
        * 
        * @return
        */
        public function __construct( $total, $limit, array $classes=[] )
        {
            # Устанавливаем общее количество записей
            $this->total  = $total;
            
            # Устанавливаем количество записей на страницу
            $this->limit  = $limit;
            
            # Устанавливаем количество страниц
            $this->amount = $this->amount();
            
            # Вызываем метод установки текущей страницы
            $this->setCurrentPage();
            
            # Вызываем метод установки текущего GET-запроса
            $this->setQueryString();
            
            # Заполняем массив классов
            $this->classes = array_merge( $this->classes, $classes );
        }
        
        /**
        *  Для вывода ссылок
        * 
        * @return HTML-код со ссылками навигации
        */
        public function get()
        {
            # Для записи ссылок
            $pagination = null;
            
            # Получаем ограничения для цикла
            $limits = $this->limits();
 
            # Генерируем ссылки
            for($page=$limits[0]; $page<=$limits[1]; $page++)
            {
                # Формируем статус ссылки
                $status = $page == $this->current_page ? 'active' : null;
                    
                # Заносим ссылку
                $pagination .= $this->generateHtml($page, null, null, $status);
            }
            
            # Если текущая страница не первая
            if($this->current_page > 1){
                # Создаём ссылку "Предыдущая"
                $pagination = $this->generateHtml($this->current_page - 1, '&lt;', 'Предыдущая') . $pagination;
                
                # Создаём ссылку "Первая"
                $pagination = $this->generateHtml(1, '&lt;&lt;', 'Первая') . $pagination;
            }
            
            # Если текущая страница не первая
            if($this->current_page < $this->amount){
                # Создаём ссылку "Следующая"
                $pagination .= $this->generateHtml($this->current_page + 1, '&gt;', 'Следующая');  
                
                # Создаём ссылку "Следующая"
                $pagination .= $this->generateHtml($this->amount, '&gt;&gt;', 'Последняя');  
            }
            
            # Оборачиваем ссылки
            $pagination = '<ul class="'. $this->classes['ul'] .'">'. $pagination .'</ul>';
 
            # Возвращаем ссылки
            return $pagination;
        }
        
        /**
        * Для получения, откуда начинать выборку
        * 
        * @return integer
        */
        public function skip(){
            return 
                $this->current_page * $this->limit - $this->limit;
        }
        
        /**
        * Для получение ограничения выборки
        * 
        * @return integer
        */
        public function take(){
            # Получаем, откуда начинаем
            $skip = $this->skip();
            
            # Возвращаем ограницение
            return
                $skip + $this->limit > $this->total ? $this->total - $skip : $this->limit;
        }
        
        /**
        * Для генерации HTML-кода ссылки
        * @param string $query - текущий GET-запрос
        * @param integer $page - номер страницы
        * 
        * @return
        */
        private function generateHtml( $page, $text=null, $title=null, $status=null ){
            # Если текст ссылки не указан
            if( is_null($text) )
                # Указываем, что текст - цифра страницы
                $text = $page;
            
            # Формируем ссылку
            $query = $this->index .'='. $page;
            
            # Формируем строку запроса (после вопроса)
            $query = $this->query ? $this->query .'&'. $query : $query;
            
            # Формируем класс для элемента списка
            $li_class = trim( $this->classes['li'] .' '. $status );
            
            # Формируем HTML код ссылки и возвращаем
            return 
                '<li'. ($li_class ? ' class="'. $li_class.'"' : null) .'>
                     <a href="?'. $query .'" '. ($this->classes['a'] ? 'class="'. $this->classes['a'] .'" ' : null) .'title="'. $title .'">'. $text .'</a>
                 </li>';
        }
        
        /**
        *  Для получения, откуда стартовать вывод ссылок
        * 
        * @return массив с началом и концом отсчёта
        */
        private function limits()
        {
            # Вычисляем ссылки слева (чтобы активная ссылка была посередине)
            $left = $this->current_page - round($this->max / 2, 0, PHP_ROUND_HALF_DOWN);
 
            # Вычисляем начало отсчёта
            $start = $left > 0 ? $left : 1;               
 
            # Если впереди есть как минимум $this->max страниц
            if($start + $this->max <= $this->amount)
                # Назначаем конец цикла вперёд на $this->max страниц или просто на минимум
                $end = $start >= 1 ? $start + $this->max : $this->max;
            else{
                # Конец - общее количество страниц
                $end = $this->amount;
 
                # Начало - минус $this->max от конца
                $start = $this->amount - $this->max > 0 ? $this->amount - $this->max : 1;
            }
            
            # Возвращаем
            return [$start, $end];
        }
 
        /**
        * Для установки текущей страницы
        * 
        * @return
        */
        private function setCurrentPage()
        {
            # Получаем номер страницы
            $this->current_page = isset($_GET[$this->index]) ? (int) $_GET[$this->index] : 1;
            
            # Если текущая страница боле нуля
            if($this->current_page > 0)
            {
                # Если текунщая страница меньше общего количества страниц
                if($this->current_page > $this->amount)
                    # Устанавливаем страницу на последнюю
                    $this->current_page = $this->amount;
            }
            else
                # Устанавливаем страницу на первую
                $this->current_page = 1;
        }
        
        /**
        * Для получения и установки текущего GET-запроса
        * 
        * @return
        */
        private function setQueryString(){
            # Получаем параметры текущего запроса
            $query = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_QUERY );
            
            # Разбираем строку запроса
            parse_str( $query, $params );
            
            # Удаляем значение страницы, если есть
            unset( $params[$this->index] );
            
            # Формируем запрос
            $this->query = http_build_query( $params );
        }
        
        /**
        * Для получеия общего числа страниц
        * 
        * @return число страниц
        */
        private function amount()
        {
            # Делим и возвращаем
            return
                ceil( $this->total / $this->limit );
        }
    }

Если Вы захотите применить свои классы к UL, LI или A - тегам, то сделать это можно так:
PHP
1
$pagination = new Pagination(100,5, ['ul'=>'новый класс', 'li'=>'класс для LI', 'a'=>'класс для A']);
Т.е. передав третьим параметром массив с классами для тегов. Внимание: не обязательно писать классы для всех тегов. Ненужные можно опустить. Например, если Вы хотите добавить класс для тега "<a>", делайте так:
PHP
1
$pagination = new Pagination(100,5, ['a'=>'класс для A']);
В таком случае для тега "<a>" добавится класс, LI не будет иметь класса (по умолчанию), UL будет иметь класс "pagination" (по умолчанию).
3
GoDr
89 / 78 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
07.11.2015, 14:27 #42
Две библиотеки для работы с датой/временем: первая - можно сказать back-end, вторая ближе к front-and
Желательно PHP 5.4+
Описание и примеры в комментариях к коду

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/**
 * Класс для работы с Датой и Временем
 *
 * @package   Libraries
 * @version   1.2
 * @author    Gold Dragon <illusive@bk.ru>
 * @link      http://lotos-cms.ru
 * @copyright Авторские права (C) 2013-2015, Lotos CMS
 * @license   MIT License: /copyright/MIT_License.lic
 */
class LibDateTime
{
    /** string : Полный формат даты */
    const DATE_FORMAT_FULL = 'd.m.Y H:i:s';
 
    /** string : Короткий формат даты */
    const DATE_FORMAT_SHORT = 'd.m.Y';
 
    /** int : Смещением времени относительно UTC, ч */
    const DATE_OFFSET = 0;
 
    /** string : Формат возвращаемой разницы даты/времени */
    const DATE_FORMAT_DIFF = '%r%a';
 
    /**
     * Возвращает текущую дату в соответствии со смещением времени относительно UTC, ч
     *
     * @param string $format : формат возвращаемой даты/времени
     *
     * @return string
     *
     * @example :
     *         echo LibDateTime::getCurrentDate();
     *         echo LibDateTime::getCurrentDate('Y');
     *
     * @version 1.0
     * @since   21.08.2015 Gold Dragon
     */
    public static function current($format = self::DATE_FORMAT_FULL)
    {
        $local = self::DATE_OFFSET;
        $date = date($format);
        if ($local > 0) {
            return self::getDateAdd($date, 'PT' . $local . 'H', $format);
        } elseif ($local < 0) {
            return self::getDateSub($date, 'PT' . abs($local) . 'H', $format);
        } else {
            return $date;
        }
    }
 
    /**
     * Возвращает разницу дат
     *
     * @param datetime      $date1  : уменьшаемое
     * @param datetime|null $date2  : вычитаемое (если не задана то текущая)
     * @param string        $format : возвращаемый формат (каждому символу должен предшествовать знак процента [%])
     *                              Y : Годы, число, минимум две цифры с ведущими нулями
     *                              y : Годы, число
     *                              M : Месяцы, число, минимум две цифры с ведущими нулями
     *                              m : Месяцы, число
     *                              D : Дни, число, минимум две цифры с ведущими нулями
     *                              d : Дни, число
     *                              a : Общее количество дней в качестве
     *                              H : Часы, число, минимум две цифры с ведущими нулями
     *                              h : Часы, число
     *                              I : Минуты, число, минимум две цифры с ведущими нулями
     *                              i : Минуты, число
     *                              S : Секунды, число, минимум две цифры с ведущими нулями
     *                              s : Секунды, число
     *                              R : Знак "-" при отрицательном числе, "+" при положительном
     *                              r : Знак "-" при отрицательном числе, пусто при положительном
     *
     * @return int : разность (в днях)
     *
     * @example :
     *         echo LibDateTime::getDateDiff('01.01.2015');
     *         echo LibDateTime::getDateDiff('11.11.2020', '01.01.2015');
     *         echo LibDateTime::getDateDiff('11.11.2020', '01.01.2015', '%r%a');
     *
     * @version 1.1
     * @since   21.08.2015 Gold Dragon
     */
    public static function getDateDiff($date1, $date2 = null, $format = self::DATE_FORMAT_DIFF)
    {
        if (is_null($date2)) {
            $date2 = date(self::DATE_FORMAT_FULL);
        }
        $d2 = new DateTime($date1);
        $d1 = new DateTime($date2);
 
        $result = (int)$d1->diff($d2)->format($format);
 
        return $result;
    }
 
    /**
     * Прибавляет интервал к дате
     *
     * @param string $date     - дата
     * @param string $interval - интервал в формате ISO 8601, например, P5D (5 дней) или P3Y (3 года)
     *                         Y : Количество лет
     *                         M : Количество месяцев
     *                         D : Количество дней
     *                         W : недели. Преобразуется в дни, поэтому не может быть использован совместно с D.
     *                         H : часы
     *                         M : минуты
     *                         S : секунды
     * @param string $format   - возвращаемый формат (по умолчанию  d.m.Y)
     *
     * @return string - дата в формате $format
     *
     * @example :
     *         echo LibDateTime::getDateAdd('01.01.2015', 'P5D');
     *         echo LibDateTime::getDateAdd('01.01.2015', 'P5D', 'Y-m-d');
     *
     * @version 1.1
     * @since   21.10.2015 Gold Dragon
     */
    public static function getDateAdd($date, $interval, $format = self::DATE_FORMAT_SHORT)
    {
        $d1 = new DateTime($date);
        $result = $d1->add(new DateInterval($interval))->format($format);
 
        return $result;
    }
 
    /**
     * Отнимает интервал от дате
     *
     * @param string $date     - дата
     * @param string $interval - интервал в формате ISO 8601, например, P5D (5 дней) или P3Y (3 года)
     *                         Y - Количество лет
     *                         M - Количество месяцев
     *                         D - Количество дней
     * @param string $format   - возвращаемый формат (по умолчанию  d.m.Y)
     *
     * @return string - дата в формате $format
     *
     * @example :
     *         echo LibDateTime::getDateSub('01.01.2015', 'P5D');
     *         echo LibDateTime::getDateSub('01.01.2015', 'P5D', 'Y-m-d');
     *
     * @version 1.1
     * @since   21.08.2015 Gold Dragon
     */
    public static function getDateSub($date, $interval, $format = self::DATE_FORMAT_SHORT)
    {
        $d1 = new DateTime($date);
        $result = $d1->sub(new DateInterval($interval))->format($format);
 
        return $result;
    }
 
    /**
     * Преобразует дату в нужный формат
     *
     * @param string $date   - дата (если не задана то текущая)
     * @param string $format - возвращаемый формат (по умолчанию  d.m.Y)
     *
     * @return string
     *
     * @example :
     *         echo LibDateTime::formatDate();
     *         echo LibDateTime::formatDate('', 'Y-m-d');
     *         echo LibDateTime::formatDate('01.01.2015', 'Y-m-d');
     *
     * @version 1.1
     * @since   21.08.2015 Gold Dragon
     */
    public static function formatDate($date = null, $format = self::DATE_FORMAT_SHORT)
    {
        if (is_null($date)) {
            $date = date(self::DATE_FORMAT_SHORT);
        }
 
        $date_obj = new DateTime($date);
 
        return $date_obj->format($format);
    }
}
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/**
 * Класс для работы с Датой и Временем (front-end)
 *
 * @package   Libraries
 * @version   1.1
 * @author    Gold Dragon <illusive@bk.ru>
 * @link      http://lotos-cms.ru
 * @copyright Авторские права (C) 2013-2015, Lotos CMS
 * @license   MIT License: /copyright/MIT_License.lic
 */
class LibDateTimeForm
{
    /** @var array : перечень имён месяцев в именительном падеже */
    private static $_month_name_i = [
        '',
        'Январь',
        'Февраль',
        'Март',
        'Апрель',
        'Май',
        'Июнь',
        'Июль',
        'Август',
        'Сентябрь',
        'Октябрь',
        'Ноябрь',
        'Декабрь'
    ];
 
    /** @var array : перечень имён месяцев в родительном падеже */
    private static $_month_name_r = [
        '',
        'января',
        'февраля',
        'марта',
        'апреля',
        'мая',
        'июня',
        'июля',
        'августа',
        'сентября',
        'октября',
        'ноября',
        'декабря',
        ];
 
    /** @var array : суффикс полной даты */
    private static $_year_suffix = [
        '',
        'г.',
        'года'
        ];
 
    /**
     * Возвращает выпадающий список дней месяца
     *
     * @param int      $month       : номер месяца
     * @param int      $year        : год
     * @param string   $tag_name    : имя тега
     * @param null|int $selected    : значение для выбора
     * @param string   $tag_attribs : дополнительные атрибуты тега
     * @param int      $calendar    : Календарь, используемый для вычисления
     *                              0 or CAL_GREGORIAN - Грегорианский календарь (по умолчанию)
     *                              1 or CAL_JULIAN - Юлианский календарь
     *                              2 or CAL_JEWISH - Еврейский календарь
     *                              3 or CAL_FRENCH - Календарь со дня Французской революции
     *
     * @return string : HTML-код
     *
     * @example :
     *         echo LibForm::selectDays(2, 2015, 'qqq');
     *         echo LibForm::selectDays(2, 2015, 'qqq', 12);
     *         echo LibForm::selectDays(2, 2015, 'qqq', '', 'id="qq1" style="color:#900"');
     *
     * @version 1.1
     * @since   07.11.2015 Gold Dragon
     */
    public static function selectDays($month, $year, $tag_name, $selected = null, $tag_attribs = '', $calendar = CAL_GREGORIAN)
    {
        $_day = cal_days_in_month($calendar, $month, $year);
 
        $result = '<select name="' . $tag_name . ' ' . $tag_attribs . '">';
 
        for ($i = 1; $i <= $_day; $i++) {
            $result .= '<option value="' . $i . '" ' . (($i == $selected) ? ' selected="selected"' : '') . '>' . $i . '</option>';
        }
 
        $result .= '</select>';
 
        return $result;
    }
 
    /**
     * Возвращает выпадающий список месяцев
     *
     * @param string   $tag_name    : имя тега
     * @param null|int $selected    : значение для выбора
     * @param string   $tag_attribs : дополнительные атрибуты тега
     * @param bool     $padez       : падеж
     *                              true : именительный (по умолчанию)
     *                              false : родительный
     *
     * @return string : HTML-код
     *
     * @example :
     *         echo LibForm::selectMonth('qqq');
     *         echo LibForm::selectMonth('qqq', 5);
     *         echo LibForm::selectMonth('qqq', '', 'id="qq1" style="color:#900"', false);
     *
     * @version 1.1
     * @since   07.11.2015 Gold Dragon
     */
    public static function selectMonth($tag_name, $selected = null, $tag_attribs = '', $padez = true)
    {
 
        $result = '';
        $month = ($padez) ? self::$_month_name_i : self::$_month_name_r;
 
        $result .= '<select name="' . $tag_name . ' ' . $tag_attribs . '">';
 
        for ($i = 1; $i < 13; $i++) {
            $result .= '<option value="' . $i . '" ' . (($i == $selected) ? ' selected="selected"' : '') . '>' . $month[$i] . '</option>';
        }
 
        $result .= '</select>';
 
        return $result;
    }
 
    /**
     * Возвращает выпадающий список годов
     *
     * @param int      $year1       : начальный год
     * @param string   $tag_name    : имя тега
     * @param null|int $selected    : значение для выбора
     * @param string   $tag_attribs : дополнительные атрибуты тега
     * @param null|int $year2       : конечный год (если не задан, то текущий)
     *
     * @return string : HTML-код
     *
     * @example:
     *         echo LibForm::selectYear(2000, 'qqq');
     *         echo LibForm::selectYear(2000, 'qqq', 2013);
     *         echo LibForm::selectYear(2000, 'qqq', '', ' id="qq1" style="color:#900"', 2020);
     *
     * @version 1.1
     * @since   07.11.2015 Gold Dragon
     */
    public static function selectYear($year1, $tag_name, $selected = null, $tag_attribs = '', $year2 = null)
    {
        $result = '';
        if (is_null($year2)) {
            $year2 = date('Y');
        }
 
        $result .= '<select name="' . $tag_name . ' ' . $tag_attribs . '">';
 
        for ($i = $year1; $i <= $year2; $i++) {
            $result .= '<option value="' . $i . '" ' . (($i == $selected) ? ' selected="selected"' : '') . '>' . $i . '</option>';
        }
 
        $result .= '</select>';
 
        return $result;
    }
 
    /**
     * Возвращает дату в формате [12 декабря 2014 года]
     * (метод связан с библиотекой LibDateTime)
     *
     * @param datetime|null $date   : дата в любом форматие
     * @param int           $suffix : выводить ли слово после даты
     *                              0 - нет (по умолчанию)
     *                              1 - короткая форма
     *                              2 - длинная форма
     *
     * @return string : дата
     *
     * @example :
     *         echo LibForm::getDateName('01.01.2015');
     *         echo LibForm::getDateName('01.01.2015', 2);
     *
     * @version 1.2
     * @since   07.11.2015 Gold Dragon
     */
    public static function getDateName($date = null, $suffix = 0)
    {
        if (is_null($date)) {
            $date = date('d.m.Y');
        }
        $suffix = (int)$suffix;
        if ($suffix < 0 or $suffix > 2) {
            $suffix = 0;
        }
 
        $result[] = LibDateTime::formatDate($date, 'd');
        $result[] = self::$_month_name_r[LibDateTime::formatDate($date, 'n')];
        $result[] = LibDateTime::formatDate($date, 'Y');
        $result[] = self::$_year_suffix[$suffix];
 
        return trim(implode(' ', $result));
    }
}
Константы и свойства для удобства можно вынести в отдельные файлы настроек или языковые файлы
3
Fedor Vlasenko
Программист Php, Js
Эксперт PHP
816 / 549 / 215
Регистрация: 01.02.2015
Сообщений: 1,686
21.01.2016, 02:31 #43
Micro php router
Пользуемся на здоровье
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php # Author - Fedor Vlasenko, vlasenkofedor@mail.ru
define('URI', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
define('METHOD', (isset($_SERVER['HTTP_X_REQUESTED_WITH'])
    && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') ? 'AJAX' : $_SERVER['REQUEST_METHOD']);
 
# 1 parametr - uri, 2 - optional method or callback, 3 - not or callback
function router()
{
    $args = func_get_args();
    $num_args = func_num_args();
    ($num_args != 3 || $args[1] == METHOD)
    && ($args[0] == URI || preg_match('#^' . $args[0] . '$#u', URI, $match))
    && die($args[$num_args - 1](isset($match) ? $match : array()));
}
 
router('/', function () {
    echo 'Main Micro';
});
 
router('/article/(.*[^/])', 'GET', function ($result) {
    echo 'Article: ', $result[1];
});
 
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
echo '404';
1
VLK
195 / 164 / 19
Регистрация: 05.05.2013
Сообщений: 1,197
22.01.2016, 21:57 #44
Класс для удобной работы с тегами (создания тегов).

суть проблемы:
PHP
1
echo '<div class="' . $class . '" id="' . $id . '">' . $str . '</div>';
выглядит не очень, да и проблемы начинают когда допустим не известно есть $id или его надо пропустить, для этих целей я сделал класс:
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/**
 * класс предназначен для удобного формирования HTML тегов, вместе с атрибутами и стилями 
 * какой тег будет сформирован, ординарный или парный (контейнер) зависит от свойства $is_container_tag 
 * которое должно быть явно задано через метод SetIsContainerTag или если оно не задано, 
 * тогда в зависимости от содержимого свойства $inner_html, если оно === NULL, тогда тег ординарный
 */
class HtmlTagsManager
{
    /**
     * Get Object, возвращает объект класса с уже заданными свойствами, переданными в качестве параметров
     * @param string $tag_name название тега, например: div, span или input
     * @param array $attr_array массив с атрибутами, которые будут заданы тегу
     * @param string $inner_html содержимое, которое будет вставлено в тег, в случае если он парный (контейнер)
     * @param bool $htmlspecialchars нужно ли к $inner_html применять функцию htmlspecialchars
     * @return static
     */
    static function Go($tag_name, $attr_array = array(), $inner_html = NULL, $htmlspecialchars = NULL) {
        return new static($tag_name, $attr_array, $inner_html, $htmlspecialchars);
    }
    
    /**
     * Empty Manager, если $value не пусто, возвращает строку "$before+$value+$after", в противном случае NULL
     * @param string $value
     * @param string $before
     * @param string $after
     * @return string
     */
    static function em($value, $before = '', $after = '') {
        return empty($value) ? '' : ($before . $value . $after);
    }
    
 
    public static 
            /**
             * @var bool нужно ли по умолчанию применять к $inner_html функцию htmlspecialchars
             */
            $to_htmlspecialchars = true,
            /**
             * @var string концовка ординарного тега
             */
            $single_tag_end = '/>';
    
    protected 
            $tag,
            $is_container_tag = NULL,
            $attr,
            $style_array = array(),
            $inner_html,
            $before_html = '',
            $after_html = '';
    
    
    /**
     * возвращает объект класса с уже заданными свойствами, переданными в качестве параметров
     * @param string $tag_name название тега, например: div, span или input
     * @param array $attr_array массив с атрибутами, которые будут заданы тегу
     * @param string $inner_html содержимое, которое будет вставлено в тег, в случае если он парный (контейнер)
     * @param bool $htmlspecialchars нужно ли к $inner_html применять функцию htmlspecialchars
     * @return static
     */
    function __construct($tag_name, $attr_array = array(), $inner_html = NULL, $htmlspecialchars = NULL) {
        $this->tag = $tag_name;
        $this->attr = empty($attr_array) ? array() : $attr_array;
        $this->innerHTML($inner_html, $htmlspecialchars);
    }
    
    
    /**
     * задает, является ли тег парным
     * @param bool $bool TRUE - парный (контейнер), FALSE - ординарный
     * @return static
     */
    function SetIsContainerTag($bool) {
        $this->is_container_tag = $bool;
        return $this;
    }
    
    
    /**
     * задает содержимое тега, в случае если он парный (контейнер)
     * @param string $inner_html содержимое, которое будет вставлено в тег, в случае если он парный (контейнер)
     * @param bool $htmlspecialchars нужно ли к $inner_html применять функцию htmlspecialchars
     * @return static
     */
    function innerHTML($inner_html, $htmlspecialchars = NULL) {
        $hsp = ($htmlspecialchars === NULL) ? static::$to_htmlspecialchars : $htmlspecialchars;
        $this->inner_html = ($hsp && !empty($inner_html)) ? htmlspecialchars($inner_html) : $inner_html;
        return $this;
    }
    
    
    /**
     * задает атрибуты тега, если второй параметр не передан, то будет выведен в качестве атрибута $key, например readonly или hidden
     * так же в качестве второго параметра может быть передано bool значение - TRUE/FALSE, 
     * например если передать readonly FALSE, тогда атрибут readonly будет проигнорирован, 
     * но если передать 0, то будет выведено readonly="0", поэтому такого рода значения надо приводить к типу bool 
     * через данный метод можно задать атрибут style
     * @param string $key наименование атрибута
     * @param mixed $value значение атрибута, если передать FALSE, атрибут будет проигнорирован
     * @return static
     */
    function attr($key, $value = NULL) {
        if ($value === NULL) {
            $this->attr[] = $key;
        }
        else {
            $this->attr[$key] = $value;
        }
        return $this;
    }
    
    
    /**
     * задает стили, в качестве второго параметра может быть передано bool значение - TRUE/FALSE, 
     * если в качестве второго параметра передать FALSE, стиль будет проигнорирован 
     * данный метод имеет приоритет перед стилем заданным через метод attr
     * если стиль был задан при помощи метода attr, например color: red, а потом используя данный метод 
     * было задано color: green, в итоге color будет green
     * @param string $key наименование стиля
     * @param mixed $value значение, если передать FALSE, стиль будет проигнорирован
     * @return static
     */
    function style($key, $value = false) {
        $this->style_array[$key] = $value;
        return $this;
    }
    
    
    /**
     * задает какой-то текст перед тегом
     * @param string|mixed $value
     * @return static
     */
    function before($value) {
        $this->before_html = $value;
        return $this;
    }
    
    
    /**
     * задает какой-то текст после тега
     * @param string|mixed $value
     * @return static
     */
    function after($value) {
        $this->after_html = $value;
        return $this;
    }
    
    
    /**
     * из стилей заданных через метод style и метод attr формирует конечный набор стилей 
     * @return string возвращает строку, которая будет вставлена в атрибут style или NULL
     */
    protected function getStyleString() {
        if (empty($this->style_array) && empty($this->attr['style'])) {
            return '';
        }
        else if (empty($this->style_array)) {
            return $this->attr['style'];
        }
        
        $style = array();
        if ( !empty($this->attr['style']) ) {
            $parts = explode(';', $this->attr['style']);
            foreach($parts as $part) {
                $temp = explode(':', $part);
                if (count($temp) < 2) continue;
                $style[ trim($temp[0]) ] = trim($temp[1]);
            }
        }
        $style = array_merge($style, $this->style_array);
        $arr = array();
        foreach($style as $key => $value) {
            if ( !empty($value) ) {
                $arr[] = "{$key}: {$value};";
            }
        }
        return implode(' ', $arr);
    }
    
    
    /**
     * формирует конечный набор атрибутов, для вставки его в тег 
     * в данном методы получение стилей происходит при помощи вызова метода getStyleString 
     * @return string возвращает строку, которая будет вставлена в тег или NULL
     */
    protected function getAttrString() {
        if (empty($this->attr) && empty($this->style_array)) {
            return '';
        }
        
        $attr = $this->attr;
        $attr['style'] = $this->getStyleString();
        
        $temp = array();
        foreach($attr as $key => $value) {
            if ( is_int($key) && !empty($value) ) {
                $temp[] = $value;
            }
            else if ( !empty($value) || $value === 0 || $value === '0' ) {
                $temp[] = $value === true ? $key : ($key . '="' . htmlspecialchars($value) . '"');
            }
        }
        
        return empty($temp) ? '' : (' ' . implode(' ', $temp));
    }
    
    /**
     * формирует тег в конечную строку и возвращает её по схеме , "до + тег + после" 
     * если задан второй параметр, за место тега будет возвращена строка "до + параметр + после" 
     * @param string $another_text строка, которая будет возвращена за место тега по схеме 
     * "до + параметр + после" 
     * @return string
     */
    protected function to_string($another_text = false) {
        if ($another_text !== false) {
            $temp = $another_text;
        }
        else {
            $temp = '<' . $this->tag . $this->getAttrString();
            $ctrl = is_bool($this->is_container_tag) ? $this->is_container_tag : 
                    ( $this->inner_html !== NULL ? true : false );
            $temp .= $ctrl ? ">{$this->inner_html}</{$this->tag}>" : static::$single_tag_end;
        }
        return $this->before_html . "\r\n" . $temp . "\r\n" . $this->after_html;
    }
    
    /**
     * данный метод предназначен на тот случай если необходимо в дочернем классе перегрузить toString 
     * при этом иметь доступ к публичному методу создания конечной строки 
     * @param string $another_text строка, которая будет возвращена за место тега по схеме 
     * "до + параметр + после" 
     * @return string
     */
    function toStringBase($another_text = false) {
        return $this->to_string($another_text);
    }
    
    /**
     * формирует и возвращает тег вместе с атрибутами, стилями и вложением, по схеме "до + тег + после" 
     * @param string $another_text строка, которая будет возвращена за место тега по схеме 
     * "до + параметр + после" 
     * @return string
     */
    function toString($another_text = false) {
        return $this->toStringBase($another_text);
    }
    
    /**
     * формирует и выводит тег вместе с атрибутами, стилями и вложением, по схеме "до + тег + после" 
     * @param string $another_text строка, которая будет возвращена за место тега по схеме 
     * "до + параметр + после" 
     * @return string
     */
    function toEcho($another_text = false) {
        echo $this->toString($another_text);
    }
    
    function __toString() {
        return $this->toString();
    }
    
    function __invoke() {
        return $this->toString();
    }
}


применение / использование:
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// создаем тег div с содержимым hello и атрибутом main_div
echo HtmlTagManager::Go('div')
    ->innerHTML('hello')
    ->attr('id', 'main_div')
    ->toString();
 
 
// за счет того что не был задан innerHTML, тег будет ординарным
// если надо задать парный, надо это указать через метод SetIsContainerTag
echo HtmlTagManager::Go('input')
    ->attr('type', 'text')
    ->attr('name', 'user_name')
    ->attr('required') // для одиночный атрибутов не нужно задавать значение
    ->attr('value', 'Вася')
    ->toString();
 
 
// мы можем указывать для атрибута параметр false, тогда данный атрибут будет проигнорирован
// но не 0, в случае с 0, будет readonly="0", по этому надо приводить тип
echo HtmlTagManager::Go('textarea')
    ->SetIsContainerTag(true)
    ->attr('readonly', false)
    ->toString();
 
 
// можно задавать стили двумя способами, первый через attr в виде строчки, 
// второй через специализированный метод style, style имеет приоритет
echo HtmlTagManager::Go('span')
    ->innerHTML('some text..')
    ->style('color', 'green')
    ->attr('style', 'color: red; border: 1px solid gray; padding: 10px;')
    ->toString();
// в итоге color будет равен green
// так же можно указывать false, тогда стиль будет проигнорирован



класс можно расширить, что то изменить, что то дописать.

PS говнокод?
1
Fedor Vlasenko
Программист Php, Js
Эксперт PHP
816 / 549 / 215
Регистрация: 01.02.2015
Сообщений: 1,686
22.01.2016, 22:38 #45
Цитата Сообщение от VLK Посмотреть сообщение
PS говнокод?
Да. Есть шаблонизаторы. Ответил как думаю
0
VLK
195 / 164 / 19
Регистрация: 05.05.2013
Сообщений: 1,197
22.01.2016, 23:19 #46
Цитата Сообщение от Poznakomlus Посмотреть сообщение
Да. Есть шаблонизаторы. Ответил как думаю
ну шаблонизатор шаблонизатором, бывает когда его использование избыточно, кучу кода ради пару строк, а тут всего 200 строк.
а если без шаблонизатора?
0
GoDr
89 / 78 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
23.01.2016, 15:25 #47
VLK, а мне очень понравилось! Ну по крайней мере сама идея.. Некоторые вещи я бы поменял, но всё же... именно удобно когда есть необходимость некоторый HTML-код создавать динамически..

я бы убрал всякие "\r\n".. Любой браузер позволяет нормально форматировать код для просмотра, зачес ему мешать
0
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16750 / 6641 / 864
Регистрация: 12.06.2012
Сообщений: 19,892
Завершенные тесты: 1
24.01.2016, 20:28 #48
Цитата Сообщение от GoDr Посмотреть сообщение
я бы убрал всякие "\r\n".. Любой браузер позволяет нормально форматировать код для просмотра, зачес ему мешать
при просмотре исходного кода страницы в браузере они вовсе не будут лишними
0
GoDr
89 / 78 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
25.01.2016, 15:31 #49
Цитата Сообщение от KOPOJI Посмотреть сообщение
при просмотре исходного кода страницы в браузере они вовсе не будут лишними
для простого пользователя код смотреть не обязательно. А дляразработчиков.. так у всех есть средство отладки в которых код сам правильно форматируется, подсвечивается да и на валидность проверяется...
0
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16750 / 6641 / 864
Регистрация: 12.06.2012
Сообщений: 19,892
Завершенные тесты: 1
26.01.2016, 22:55 #50
GoDr, т.е., ситуации, когда надо посмотреть, какой html-код генерируется, никогда не встречаются?
Вот вам реальный пример кода из одного шаблона CMS (часть ненужного кода я удалил)
PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<ul>
<?$CURRENT_DEPTH=$arResult["SECTION"]["DEPTH_LEVEL"]+1;
foreach($arResult["SECTIONS"] as $arSection):
   if($CURRENT_DEPTH<$arSection["DEPTH_LEVEL"]):?>
    <ul>
   <?elseif($CURRENT_DEPTH>$arSection["DEPTH_LEVEL"]):?>
        <?=str_repeat("</li></ul>", $CURRENT_DEPTH - $arSection["DEPTH_LEVEL"]);?>
      </li>
   <?else:?>
    </li>
   <?endif;?>
   <li>
      <a href="<?=$arSection["SECTION_PAGE_URL"];?>"><?=$arSection["NAME"];?></a>
   </li>   
   <?$CURRENT_DEPTH = $arSection["DEPTH_LEVEL"];?>
<?endforeach?>
</ul>
В данном коде генерируется несколько неверный код. Не проще ли здесь будет посмотреть в браузере сгенерированный html-код, нежели дебажить пошагово? И чем вам помогут форматирование и подсветка в данной ситуации?
0
GoDr
89 / 78 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
27.01.2016, 10:01 #51
KOPOJI, ну вообще-то разговор шёл о принудительном переносе строки и возврате каретки. В данном случае это не поможет "красиво" посмотреть код. Тогда уж нужно и "\t" ставить. Да и генериться готовый HTML который отдаётся пользователю.. Что касается непосредственно этапом разработки, то тут практически любая IDE в принципе сама отформатирует код как нужно.

Цитата Сообщение от KOPOJI Посмотреть сообщение
И чем вам помогут форматирование и подсветка в данной ситуации?
Так "\r\n" тоже как -то не очень помогут. А форматирование и подсветка наоборот смогут показать валидность


KOPOJI, а сам код как? полезный? Твоё мнение Мне понравилась идея реализации. Я у себя использую только формирование подобным образом элементов форм.
0
Fedor Vlasenko
Программист Php, Js
Эксперт PHP
816 / 549 / 215
Регистрация: 01.02.2015
Сообщений: 1,686
27.01.2016, 12:13 #52
Цитата Сообщение от GoDr Посмотреть сообщение
Я у себя использую только формирование подобным образом элементов форм
https://code.google.com/archive/p/php-form-builder-class/downloads
слово
только
настораживает. в каждой задаче должен быть рациональный подход
1
GoDr
89 / 78 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
27.01.2016, 12:36 #53
Poznakomlus, немного не понял про что ты.. Слово "только" я использовал с сожалением поэтому мне и понравился код VLK
0
Fedor Vlasenko
Программист Php, Js
Эксперт PHP
816 / 549 / 215
Регистрация: 01.02.2015
Сообщений: 1,686
27.01.2016, 12:49 #54
гляньте библиотеку по ссылке
прежде чем писать новое решение, внимательно осмотритесь какие решения уже были написаны до этого
по сути форма это не контент, потому есть разные способы ее построения
1. php компонент (генератор форм)
2. шаблонизатор php
3. построение формы на клиенте
у каждого решения есть свои плюсы и минусы
я к тому, что не стоит утверждать только так и все, все зависит от пставленной задачи
0
GoDr
89 / 78 / 33
Регистрация: 17.08.2015
Сообщений: 512
Записей в блоге: 1
27.01.2016, 13:01 #55
Poznakomlus, хорошая ссылка. Спасибо, очень познавательно!
0
VLK
195 / 164 / 19
Регистрация: 05.05.2013
Сообщений: 1,197
27.01.2016, 15:24 #56
Обмен готовыми решениями
исправленный вариант, там я упустил момент с одиночными атрибутами, тут он поправлен:

Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
/**
* класс предназначен для удобного формирования HTML тегов, вместе с атрибутами и стилями
* какой тег будет сформирован, ординарный или парный (контейнер) зависит от свойства $is_container_tag
* которое должно быть явно задано через метод SetIsContainerTag или если оно не задано,
* тогда в зависимости от содержимого свойства $inner_html, если оно === NULL, тогда тег ординарный
*/
class HtmlTagManager
{
    /**
     * Get Object, возвращает объект класса с уже заданными свойствами, переданными в качестве параметров
     * @param string $tag_name название тега, например: div, span или input
     * @param array $attr_array массив с атрибутами, которые будут заданы тегу
     * @param string $inner_html содержимое, которое будет вставлено в тег, в случае если он парный (контейнер)
     * @param bool $htmlspecialchars нужно ли к $inner_html применять функцию htmlspecialchars
     * @return static
     */
    static function Go($tag_name, $attr_array = array(), $inner_html = NULL, $htmlspecialchars = NULL) {
        return new static($tag_name, $attr_array, $inner_html, $htmlspecialchars);
    }
    
    /**
     * Empty Manager, если $value не пусто, возвращает строку "$before+$value+$after", в противном случае NULL
     * @param string $value
     * @param string $before
     * @param string $after
     * @return string
     */
    static function em($value, $before = '', $after = '') {
        return empty($value) ? '' : ($before . $value . $after);
    }
    
 
    public static
            /**
             * @var bool нужно ли по умолчанию применять к $inner_html функцию htmlspecialchars
             */
            $to_htmlspecialchars = true,
            /**
             * @var string концовка ординарного тега
             */
            $single_tag_end = '/>';
    
    protected
            $tag,
            $is_container_tag = NULL,
            $attr = array(),
            $style_array = array(),
            $inner_html,
            $before_html = '',
            $after_html = '';
    
    
    /**
     * возвращает объект класса с уже заданными свойствами, переданными в качестве параметров
     * @param string $tag_name название тега, например: div, span или input
     * @param array $attr_array массив с атрибутами, которые будут заданы тегу
     * @param string $inner_html содержимое, которое будет вставлено в тег, в случае если он парный (контейнер)
     * @param bool $htmlspecialchars нужно ли к $inner_html применять функцию htmlspecialchars
     * @return static
     */
    function __construct($tag_name, $attr_array = array(), $inner_html = NULL, $htmlspecialchars = NULL) {
        $this->tag = $tag_name;
        
        if (is_array($attr_array)) {
            foreach($attr_array as $key => $value) {
                if (is_int($key)) {
                    $this->attr($value);
                }
                else {
                    $this->attr($key, $value);
                }
            }
        }
        
        $this->innerHTML($inner_html, $htmlspecialchars);
    }
    
    
    /**
     * задает, является ли тег парным
     * @param bool $bool TRUE - парный (контейнер), FALSE - ординарный
     * @return static
     */
    function SetIsContainerTag($bool) {
        $this->is_container_tag = (bool)$bool;
        return $this;
    }
    
    
    /**
     * задает содержимое тега, в случае если он парный (контейнер)
     * @param string $inner_html содержимое, которое будет вставлено в тег, в случае если он парный (контейнер)
     * @param bool $htmlspecialchars нужно ли к $inner_html применять функцию htmlspecialchars
     * @return static
     */
    function innerHTML($inner_html, $htmlspecialchars = NULL) {
        $hsp = ($htmlspecialchars === NULL) ? static::$to_htmlspecialchars : $htmlspecialchars;
        $this->inner_html = ($hsp && !empty($inner_html)) ? htmlspecialchars($inner_html) : $inner_html;
        return $this;
    }
    
    
    /**
     * задает атрибуты тега, если второй параметр не передан, то будет выведен в качестве атрибута $key, например readonly или hidden
     * так же в качестве второго параметра может быть передано bool значение - TRUE/FALSE,
     * например если передать readonly FALSE, тогда атрибут readonly будет проигнорирован,
     * но если передать 0, то будет выведено readonly="0", поэтому такого рода значения надо приводить к типу bool
     * через данный метод можно задать атрибут style
     * @param string $key наименование атрибута
     * @param mixed $value значение атрибута, если передать FALSE, атрибут будет проигнорирован
     * @return static
     */
    function attr($key, $value = NULL) {
        $this->attr[$key] = ($value === NULL) ? true : $value;
        return $this;
    }
    
    
    /**
     * задает стили, в качестве второго параметра может быть передано bool значение - TRUE/FALSE,
     * если в качестве второго параметра передать FALSE, стиль будет проигнорирован
     * данный метод имеет приоритет перед стилем заданным через метод attr
     * если стиль был задан при помощи метода attr, например color: red, а потом используя данный метод
     * было задано color: green, в итоге color будет green
     * @param string $key наименование стиля
     * @param mixed $value значение, если передать FALSE, стиль будет проигнорирован
     * @return static
     */
    function style($key, $value = false) {
        $this->style_array[$key] = $value;
        return $this;
    }
    
    
    /**
     * задает какой-то текст перед тегом
     * @param string|mixed $value
     * @return static
     */
    function before($value) {
        $this->before_html = $value;
        return $this;
    }
    
    
    /**
     * задает какой-то текст после тега
     * @param string|mixed $value
     * @return static
     */
    function after($value) {
        $this->after_html = $value;
        return $this;
    }
    
    
    /**
     * из стилей заданных через метод style и метод attr формирует конечный набор стилей
     * @return string возвращает строку, которая будет вставлена в атрибут style или NULL
     */
    protected function getStyleString() {
        if (empty($this->style_array) && empty($this->attr['style'])) {
            return '';
        }
        else if (empty($this->style_array)) {
            return $this->attr['style'];
        }
        
        $style = array();
        if ( !empty($this->attr['style']) ) {
            $parts = explode(';', $this->attr['style']);
            foreach($parts as $part) {
                $temp = explode(':', $part);
                if (count($temp) < 2) {
                    continue;
                }
                $style[ trim($temp[0]) ] = trim($temp[1]);
            }
        }
        $style = array_merge($style, $this->style_array);
        $arr = array();
        foreach($style as $key => $value) {
            if ( !empty($value) ) {
                $arr[] = "{$key}: {$value};";
            }
        }
        return implode(' ', $arr);
    }
    
    
    /**
     * формирует конечный набор атрибутов, для вставки его в тег
     * в данном методы получение стилей происходит при помощи вызова метода getStyleString
     * @return string возвращает строку, которая будет вставлена в тег или NULL
     */
    protected function getAttrString() {
        if (empty($this->attr) && empty($this->style_array)) {
            return '';
        }
        
        $attr = $this->attr;
        $attr['style'] = $this->getStyleString();
        
        $temp = array();
        foreach($attr as $key => $value) {
            if (!empty($value) || $value === 0 || $value === '0') {
                $temp[] = $value === true ? $key : ($key . '="' . htmlspecialchars($value) . '"');
            }
        }
        
        return empty($temp) ? '' : (' ' . implode(' ', $temp));
    }
    
    /**
     * формирует тег в конечную строку и возвращает её по схеме , "до + тег + после"
     * если задан второй параметр, за место тега будет возвращена строка "до + параметр + после"
     * @param string $another_text строка, которая будет возвращена за место тега по схеме
     * "до + параметр + после"
     * @return string
     */
    protected function to_string($another_text = false) {
        if ($another_text !== false) {
            $temp = $another_text;
        }
        else {
            $temp = '<' . $this->tag . $this->getAttrString();
            $ctrl = is_bool($this->is_container_tag) ? $this->is_container_tag :
                    ( $this->inner_html !== NULL ? true : false );
            $temp .= $ctrl ? ">{$this->inner_html}</{$this->tag}>" : static::$single_tag_end;
        }
        return $this->before_html . "\r\n" . $temp . "\r\n" . $this->after_html;
    }
    
    /**
     * данный метод предназначен на тот случай если необходимо в дочернем классе перегрузить toString
     * при этом иметь доступ к публичному методу создания конечной строки
     * @param string $another_text строка, которая будет возвращена за место тега по схеме
     * "до + параметр + после"
     * @return string
     */
    function toStringBase($another_text = false) {
        return $this->to_string($another_text);
    }
    
    /**
     * формирует и возвращает тег вместе с атрибутами, стилями и вложением, по схеме "до + тег + после"
     * @param string $another_text строка, которая будет возвращена за место тега по схеме
     * "до + параметр + после"
     * @return string
     */
    function toString($another_text = false) {
        return $this->toStringBase($another_text);
    }
    
    /**
     * формирует и выводит тег вместе с атрибутами, стилями и вложением, по схеме "до + тег + после"
     * @param string $another_text строка, которая будет возвращена за место тега по схеме
     * "до + параметр + после"
     * @return string
     */
    function toEcho($another_text = false) {
        echo $this->toString($another_text);
    }
    
    function __toString() {
        return $this->toString();
    }
    
    function __invoke() {
        return $this->toString();
    }
}
0
KOPOJI
27.01.2016, 21:01
  #57

Не по теме:

Цитата Сообщение от GoDr Посмотреть сообщение
KOPOJI, а сам код как? полезный? Твоё мнение
Мое мнение - нет. Меня больше прельщает вариант а-ля simple_form из RoR или CHtml из Yii. Но если кому-то больше нравится такая генерация - то, наверное, полезный код.. Это же все субъективно, а не объективно.

0
Fedor Vlasenko
Программист Php, Js
Эксперт PHP
816 / 549 / 215
Регистрация: 01.02.2015
Сообщений: 1,686
09.02.2016, 23:05 #58
Работаем с PDO в функциональном стиле
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function query($sql, $binds = [], $method = '', $params = [])
{
    static $pdo;
    if (empty($pdo)) {
        $pdo = new \PDO('mysql:host=localhost;dbname=micro', 'root', 'pass',
            [
                \PDO::ATTR_EMULATE_PREPARES => false,
                \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC
            ]);
    }
 
    try {// работаем с префиксами prefix_ ваш и можно #_ вместо __
        $sql = str_replace('__', 'prefix_', $sql);
        if (empty($binds)) {
            $query = $pdo->query($sql);
        } else {
            $query = $pdo->prepare($sql);
            $query->execute($binds);
        }
        $method && $query = call_user_func_array([$query, $method], $params);
    } catch (\Exception $e) {
        $query = false;
    }
 
    return $query ;
}
 
$result = query('SELECT `name` FROM __tree WHERE `id` = ?', [3], 'fetchColumn');
var_dump($result);
1
Para bellum
Эксперт PHP
4032 / 3007 / 958
Регистрация: 06.01.2011
Сообщений: 8,827
23.02.2016, 12:51 #59
Очень часто в самописных скриптах встречается нечто подобное:
PHP
1
$variable = isset($_POST['variable']) ? $_POST['variable'] : null;
Не знаю, зачем так делают, но меня это не вдохновляет. Если не используете framework, разве трудно одну функцию написать, для получения входных данных?
Вот, может простецкая функция поможет новичкам не писать кучу этих isset'ов, а сразу встать на более верную тропу.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
    /**
    * Для получения данных из запроса
    * @param mixed $key
    * @param boolean $file
    * @param mixed $default
    * 
    * @return mixed
    */
    function input($key=null, $file=false, $default=null){
        # Массив, откуда берём данные
        $source = $file ? $_FILES : $_REQUEST;
        
        # Если ключ не указан
        if( is_null($key) )
            # Возвращаем все данные
            return $source;
        
        # Если передан массив ключей
        if( is_array($key) )
            # Возвращаем данные
            return array_intersect_key( $source, array_flip($key) );
        
        # По умолчанию
        return isset($source[$key]) ? $source[$key] : $default;
    }
Получить можно данные в любом виде:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Получаем все данные разом из массива $_REQUEST (удобно перед передачей в валидатор)
input();
 
# Получаем все файлы разом из массива $_FILES
input(null, true);
 
# Получаем данные по ключу из массива $_REQUEST
input('fieldname');
 
 
# Получаем файл по ключу из массива $_FILES
input('filename', true);
 
# Получаем данные по нескольким ключам (как в Input::only, в Laravel) из массива $_REQUEST
input(['fieldname', 'fieldname2', 'и т.д.']);
И никаких Notice и никаких isset'ов.
По-моему, проще написать так:
PHP
1
2
# В массиве гарантированно будут присутствовать эти ключи. Notice не будет.
$data = input(['name', 'email', 'phone']);
Чем
PHP
1
2
3
$name  = isset($_POST['name']) ? $_POST['name'] : null;
$email  = isset($_POST['email']) ? $_POST['email'] : null;
$phone = isset($_POST['phone']) ? $_POST['phone'] : null;
Или, что ещё хуже:
PHP
1
2
3
$name  = @$_POST['name'];
$email  = @$_POST['email'];
$phone = @$_POST['phone'];
2
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16750 / 6641 / 864
Регистрация: 12.06.2012
Сообщений: 19,892
Завершенные тесты: 1
24.02.2016, 23:57 #60
Хм.. Ну, тогда добавлю еще пару функций для проверки на пустоту значений формы. Может, кому и пригодится
Создаем какой-нибудь файлик для функций (например, empty_check.php), в него добавляем код:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
function replaceFieldName($error, $field) {
    return preg_replace('~\\{field\\}~iu', $field, $error);
}
 
function prepareStruct(array $values) {
    return array_fill_keys(array_keys($values), null);
}
 
function isEmptyField(array $arr, $name, $title, $showError = true, $errorMessage = null)
{
    static $_EMPTY_MESSAGE = 'Вы не ввели {field}';
    $res = isset($arr[$name]) && trim($arr[$name]) != '';
 
    if(!$showError)
        return $res;
    if($res)
        return false;
    return replaceFieldName((isset($errorMessage) ? $errorMessage : $_EMPTY_MESSAGE), $title);
}
 
function checkValues(array $arr, array $values, $showError = true, $errorMessage = null, $withKeys = false)
{
    $errors = prepareStruct($values);
    $hasError = false;
 
    foreach($values as $name => $title)
    {
        if(($error = isEmptyField($arr, $name, $title)))
        {
            $errors[$name] = $error;
            $hasError = true;
        }
        else
            $values[$name] = $arr[$name];
    }
 
    return $withKeys
            ? array('hasError' => $hasError, 'errors' => $errors, 'values' => $values)
            : array($hasError, $errors, $values);
}
А дальше там, где требуется, подключаем его и пишем вызовы функций. Например, в таком виде
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$values = array('name' => 'Имя', 'email' => 'E-mail', 'comment' => 'Текст комментария');
$errors = prepareStruct($values);
 
if(!empty($_POST))
{
    //checkValues возвращает массив с ключами "Есть ошибка", "Ошибки" и "Значения"
    //можно сохранить результат в одну переменную, а можно использовать так:
    list($hasError, $errors, $values) = checkValues($_POST, $values);
 
    if($hasError)
    {
        //....
    }
    else
    {
        //...
    }
}
функция prepareStruct нужна для того, чтобы не посыпались нотайсы при выводе формы.
А дальше в коде формы подставлять нужный вывод
PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<form method="POST">
    <div class="input">
        <input type="text" name="name" placeholder="Имя">
        <span class="error"><?=$errors['name']; ?></span>
    </div>
    <div class="input">
        <input type="email" name="email" placeholder="E-mail">
        <span class="error"><?=$errors['email']; ?></span>
    </div>
    <div class="input">
        <textarea name="comment" placeholder="Текст комментария"></textarea>
        <span class="error"><?=$errors['comment']; ?></span>
    </div>
    <div class="input">
        <input type="submit" value="Оставить отзыв">
    </div>
</form>
Также можно получить значения вместе с указаниями ключей. Например, такая запись будет эквивалентна написанной выше
PHP
1
list($hasError, $errors, $values) = array_values(checkValues($_POST, $values, true, null, true));
Или сохранить результат в одну переменную
PHP
1
$checkInfo = checkValues($_POST, $values, true, null, true);
и использовать ее после в таком виде
PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<form method="POST">
    <div class="input">
        <input type="text" name="name" placeholder="Имя">
        <span class="error"><?=$checkInfo['errors']['name']; ?></span>
    </div>
    <div class="input">
        <input type="email" name="email" placeholder="E-mail">
        <span class="error"><?=$checkInfo['errors']['email']; ?></span>
    </div>
    <div class="input">
        <textarea name="comment" placeholder="Текст комментария"></textarea>
        <span class="error"><?=$checkInfo['errors']['comment']; ?></span>
    </div>
    <div class="input">
        <input type="submit" value="Оставить отзыв">
    </div>
</form>
Это просто минималка, т.к. я ленивый - мне лень постоянно проверять на пустоту и т.п., а так все обходится обычным копипастом. При желании и необходимости можно улучшить функционал. Например, навскидку, можно накидать нечто такое
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php
 
defined('DEBUG') or define('DEBUG', true);
 
error_reporting( - DEBUG);
ini_set('display_errors', DEBUG);
 
function replaceFieldName($error, $field) {
    return preg_replace('~\\{field\\}~iu', $field, $error);
}
 
function prepareStruct(array $values) {
    return array_fill_keys(array_keys($values), null);
}
 
function encode($s, $flags = ENT_COMPAT, $encoding = 'UTF-8', $double_encode = true) {
    return htmlspecialchars($s, $flags, $encoding, $double_encode);
}
 
function checkValues(array $arr, array $values, $showAll = true, $withKeys = false)
{
    $errors = prepareStruct($values);
    $hasError = false;
 
    foreach($values as $name => $info)
    {
        if(isset($info['allowEmpty']) && $info['allowEmpty'] == true)
            continue;
        if(($error = checkValue($arr, $name, $info['title'])))
        {
            $errors[$name] = $error;
            $hasError = true;
        }
        if($showAll && !empty($info['check']) && ($error = checkValue($arr, $name, $info['title'], $info['check'])))
        {
            $errors[$name] .= empty($errors[$name]) ? $error : '<br>' . $error;
            $hasError = true;
        }
 
        if(!$hasError)
            $values[$name] = $arr[$name];
    }
 
    return $withKeys
            ? array('hasError' => $hasError, 'errors' => $errors, 'values' => $values)
            : array($hasError, $errors, $values);
}
 
function checkValue(array $arr, $name, $title, array $check = array(), $showError = true)
{
    static $errorMessages = array(
        'empty' => 'Вы не ввели {field}',
        'regexp' => 'Неверный формат поля {field}',
        'big' => 'Поле {field} содержит слишком много символов',
        'small' => 'Поле {field} содержит слишком мало символов',
    );
    if(!($type = array_intersect_key($errorMessages, $check)))
        $type = 'empty';
    else
        $type = current(array_keys($type));
 
    if(!isset($arr[$name]))
        return false;
 
    switch($type)
    {
        case 'empty':
            $res = trim($arr[$name]) != '';
        break;
        case 'regexp':
            $res = empty($check[$type]) || preg_match('`' . $check[$type] . '`ui', $arr[$name]);
        break;
        case 'email':
            $res = filter_var($arr[$name], FILTER_VALIDATE_EMAIL);
        break;
        default:
            $res = false;
    }
 
    if(!$showError)
        return $res;
    if($res)
        return false;
    return replaceFieldName($errorMessages[$type], $title);
}
 
 
function textOrValue(array $arr, $key, $defaultValue = null) {
    return empty($arr[$key]) ? $defaultValue : $arr[$key];
}
 
 
function buildInputs(&$hasError, array $values, $addErrors = true, array $storage = array(), array $attributes = array('id', 'placeholder', 'required'))
{
    $res = null;
 
    $errors = prepareStruct($values);
 
    if($addErrors && $storage !== array())
    {
        list(,$errors,) = checkValues($storage, $values);
    }
 
    foreach($values as $name => $info)
    {
        $type = textOrValue($info, 'type', 'text');
        $attrs = null;
 
        $beginTag = $type == 'textarea' ? '<textarea ' : '<input type="' . $type . '" ';
        $beginTag .= 'name="' . $name . '" ';
 
        if(isset($storage[$name]) && !isset($info['value']))
            $value = $type == 'textarea' ? '>' . encode($storage[$name]) : 'value="' . encode($storage[$name]) . '">';
        else
            $value = '>';
 
 
        $endTag = $type == 'textarea' ? '</textarea>' : '';
 
        foreach($attributes as $attribute)
        {
            if(!isset($info[$attribute]))
                continue;
 
            $attrs .= $attribute . '="' . textOrValue($info, $attribute) . '" ';
        }
 
        $res .= '<div class="input">' . PHP_EOL
                    . '<label for="' . $info['id'] . '">' . $info['title'] . ':</label>' . PHP_EOL
                    . trim($beginTag . $attrs) . $value . $endTag . PHP_EOL;
 
        if($addErrors)
            $res .= '<span class="error">' . $errors[$name] . '</span>' . PHP_EOL;
 
        $res .= '</div>' . PHP_EOL;
    }
 
    $hasError = array_filter($errors, 'trim');
 
    return $res;
}
и вынести в отдельный файл, затем его просто подключать в нужном месте. Для этого кода уже надо будет формировать массив значений в таком виде
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$values = array(
    'name' => array(
        'type' => 'text',
        'id' => 'name',
        'title' => 'Имя',
        'placeholder' => 'Ваше имя',
        'allowEmpty' => true,
    ),
    'email' => array(
        'type' => 'email',
        'id' => 'email',
        'title' => 'E-mail',
    ),
    'phone' => array(
        'type' => 'tel',
        'id' => 'tel',
        'title' => 'Телефон',
        'check' => array(
            'regexp' => '^\\d{11}$',
        ),
        'required' => '',
    ),
    'comment' => array(
        'type' => 'textarea',
        'id' => 'comment',
        'title' => 'Текст комментария'
    ),
);
 
$hasError = false;
 
$inputs = buildInputs($hasError, $values, true, $_POST);
 
if(!$hasError) //success form check
{
    //...
}
Но в результате код формы будет выглядеть примерно так
PHPHTML
1
2
3
4
<form method="post">
    <?=$inputs; ?>
    <input type="submit" value="Отправить">
</form>
скрин
Название: Снимок экрана из 2016-02-24 23:56:35.png
Просмотров: 110

Размер: 12.4 Кб


Конечно, код далеко не совершенен (если не сказать по-другому), да и накидал я его только сейчас, за пару часов.. Но, может, кому и пригодится, вдобавок к коду выше
3
24.02.2016, 23:57
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.02.2016, 23:57

Обмен информацией с Web-сервером
Создайте веб-приложение, которое формирует возрастающую последовательность из...

Обмен данными между процессами
Здравствуйте! Задача такая: есть скрипт на php который постоянно в памяти и...

Обмен-валюта через ВебМани
как создать скрипты обмен-валюта через ВебМани? Моете подсказать, где может...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru