Ага, вот эти ребята, сейчас я покажу Вам настоящую магию из мира PHP.
Вместо предисловия. Об авторах языка
Точнее о траве которую курили разработчики, ну как так можно именовать функции? Ну возьмем для примера функции для работы со строками:
- str_replace( ищем строку $search, заменяем на $replace, в строке $subject [, итого поменяли &$count ] )
- strpos( в строке $haystack , ищем $needle [, пропускаем $offset символов] )
- substr_replace( в строке $string , заменям на $replacement , с позиции $start [, $length ])
- nl2br( изменяем строку $string [, это $is_xhtml ] )
Как мы видим это очень мрачно, а если брать массивы – в одном месте у нас функция возвращает результат, в другом – работает по ссылке… брр…
Благодаря отсутвию стандартов даже в самом языке, мы имеем некий дискомфорт при работе с данным языком. Да и другие косятся…
PHP это неправильный язык программирования
Эту сказку я частенько слышу. Решил я написать какой-то такой наглядный код, чтобы сразу было понятно, PHP — это ого-го-го :)
Решил, и написал – на Ruby пару классов, которые будут представлять из себя обертку для строк и масивов. Данные классы включают в себя лишь часто используемые функции (по моему скромному мнению), а вызов остальных возложил на рефлексию.
Массив – oArray
Данный класс включает в себя стандартные функции.
- array_diff — Вычислить расхождение в массивах
- array_fill — Заполнить массив определенным значением
- array_filter — Применяет фильтр к массиву, используя функцию обратного вызова
- array_flip — Поменять местами значения массива
- array_key_exists — Проверить, присутствует ли в массиве указанный ключ или индекс
- array_keys — Выбрать все ключи массива
- array_map — Применить функцию обратного вызова ко всем элементам указанных массивов
- array_pop — Извлечь последний элемент массива
- array_product — Вычислить произведение значений массива
- array_push — Добавить один или несколько элеметов в конец массива
- array_rand — Выбрать одно или несколько случайных значений из массива
- array_reverse — Возвращает массив с элементами в обратном порядке
- array_search — Осуществляет поиск данного значения в массиве и возвращает соответствующий ключ в случае удачи
- array_shift — Извлечь первый элемент массива
- array_slice — Выбрать срез массива
- array_splice — Удалить последовательность элементов массива и заменить её другой последовательностью
- array_sum — Вычислить сумму значений массива
- array_unique — Убрать повторяющиеся значения из массива
- array_unshift — Добавить один или несколько элементов в начало массива
- array_values — Выбрать все значения массива
- sort — Отсортировать массив
- rsort — Отсортировать массив в обратном порядке
- natsort — Отсортировать массив, используя алгоритм “natural order”
- natcasesort — Отсортировать массив, используя алгоритм “natural order” не принимая во внимание регистр символов
- ksort — Отсортировать массив по ключам
- krsort — Отсортировать массив по ключам в обратном порядке
- implode — Объединяет элементы массива в строку
А так же немного полезной отсебячины:
- to_url — Обертка для http_build_query
- clear — Убрать пустые элементы массива
- odd — Оставить лишь нечетные элементы
- even — Оставить лишь четные элементы
- size — Врапер для функции sizeof
Для всех функций вида array_* сей префикс я убрал (ведь мы и так знаем, что работает с массивом), остальный функции – на совести метода __call и рефлексии.
Строка – oString
Данный класс включает в себя стандартные функции.
- addslashes — Экранирует спецсимволы в строке
- count_chars — Возвращает информацию о символах, входящих в строку
- crc32 — Вычисляет CRC32 для строки
- crypt — Необратимое шифрование (хэширование)
- explode — Разбивает строку на подстроки
- html_entity_decode — Преобразует HTML сущности в соответствующие символы
- htmlentities — Преобразует символы в соответствующие HTML сущности
- htmlspecialchars_decode — Преобразует специальные HTML-сущности обратно в соответствующие символы
- htmlspecialchars — Преобразует специальные символы в HTML сущности
- ltrim — Удаляет пробелы из начала строки
- md5 — Возвращает MD5 хэш строки
- money_format — Форматирует число как денежную величину
- nl2br — Вставляет HTML код разрыва строки перед каждым переводом строки
- number_format — Форматирует число с разделением групп
- parse_str — Разбирает строку в переменные
- rtrim — Удаляет пробелы из конца строки
- sha1 — Возвращает SHA1 хэш строки
- sprintf — Возвращает отформатированную строку
- str_pad — Дополняет строку другой строкой до заданной длины
- str_repeat — Возвращает повторяющуюся строку
- str_replace — Заменяет строку поиска на строку замены
- str_ireplace — Регистро-независимый вариант функции str_replace()
- str_word_count — Возвращает информацию о словах, входящих в строку
- strip_tags — Удаляет HTML и PHP тэги из строки
- stripslashes — Удаляет экранирование символов, произведенное функцией addslashes()
- strstr — Находит первое вхождение подстроки
- stristr — Регистро-независимый вариант функции strstr()
- strpos — Возвращает позицию первого вхождения подстроки
- stripos — Возвращает позицию первого вхождения подстроки без учета регистра
- strrpos — Возвращает позицию последнего вхождения символа
- strripos — Возвращает позицию последнего вхождения подстроки без учета регистра
- strrev — Переворачивает строку
- strtolower — Преобразует строку в нижний регистр
- strtoupper — Преобразует строку в верхний регистр
- substr_count — Возвращает число вхождений подстроки
- substr_replace — Заменяет часть строки
- substr — Возвращает подстроку
- trim — Удаляет пробелы из начала и конца строки
- ucfirst — Преобразует первый символ строки в верхний регистр
- ucwords — Преобразует в верхний регистр первый символ каждого слова в строке
- wordwrap — Выполняет перенос строки на данное количество символов с использованием символа разрыва строки
А так же немного полезной отсебячины:
- add — Конкатенация строк
- insert — Вставка строки в строку
- size — Врапер для функции strlen
Для всех функций вида str_*
и str*
сей префикс был убран.
Так же выделил функции для работы с URL – и запихнул их в отдельный класс (oUrl):
- parse_url
- urlencode
- urldecode
Слайды
Теперь приведу пример использования сего творения:
oArray() // создаем пустой массив ->range(0,100,10) // врапер для range ->size() // врапер для sizeof ;
Как Вам? Даю еще пищу для мозга:
oArray('module', 'controller', 'action') // создаем массив из элементов => array('module', 'controller', 'action') ->combine(oArray('default', 'index', 'index')) // врапер для array_combine => array('module'=>'default', 'controller'=>'index', 'action'=>'index') ->to_url() // врапер для http_build_query возвращает oUrl => module=default&controller=index&action=index ->insert('http://domain.com/?') // добавляем кусочек строки в начало => http://domain.com/?module=default&controller=index&action=index ->parse() // врапер для parse_url возвращает oArray ->host // возвращает array['host'] => domain.com ;
И еще:
oString("It's my way") ->replace('my','your') // str_replace => "It's your way" ->sub(0, 8) // substr => "It's you" ->pad(11, '.') // str_pad => "It's you..." ->repeat(2) // str_repeat => "It's you...It's you..." ->explode('...') // получаем oArray => array('It's you','It's you', '') ->clear() // удаляем пустые элементы ->merge(array('Yes','No'), array('Maybe')) // array_merge => array('It's you','It's you', 'Yes','No','Maybe') ->implode(';') // => It's you;It's you;Yes;No;Maybe ->get() // => ;
Объект – oObject
Даже обычный класс можно улучшить – добавив ему хитрые гетеры/сетеры для свойств объекта (я это подсмотрел в RoR):
class MyClass extends Object_Object { // это действительно protected свойство protected $_protected; // для данных полей можно определить гетеры/сетеры protected $title; protected $description; // public свойство без гетеров/сетеров public $data; /** * Сеттер для свойства title * * @param string $value * @return mixed */ function setTitle($value) { $this->title = ucfirst($value); } /** * Геттер для свойства title * * @return mixed */ function getTitle() { return $this->title . '!!!'; } } $MyClass = new MyClass(); $MyClass -> title = 'article title'; echo $MyClass -> title;
В результате сей махинации мы получим следующий результат:
Article title!!!
Как видим – подобный класс даже имеет право на существование ;)
Вот такое нехитрое творение у меня получилось, скачать его можете по следующей ссылке:
Заключение
P.S. Данные классы не претендуют на жизнь в реальных проектах, они предназначены дабы развеять миф о каком-то неправильном PHP, а так же послужат неплохим материалом для изучения начинающими программистами…
убери словосочетание “магия ООП” везде, где ты его употребляешь, т.к. это магия, но вовсе не ООП, а рефлексии.
@COTOHA:
Ну и метода __call :)
Статью чутка подправил…
В классе MyClass перемешаны стили объявления protected переменных.
Думаю в общем из этих классов будут использованы не более 5-8 функций, остальные очень редко. И легче все таки вызвать одну функцию str_len чем, создавать объект класса для ее вызова, так и быстрее и надежней и более независимо от наличия данного класса в проекте. Минус, надо будет всей команде переучиться на использование данного класса.
Я бы выкинул из этого класса все функции, которые не используются и переименовал класс, в что то более относящееся к предметной области и задачи.
В ПХП действительно отсутствует дизайн языка…. и это сильно удручает… никакой системы в именовании функций.
Интересная РУБИфикация получилась… но себя все равно не обманешь. Большинство вкусностей руби в пхп не реализуемы.
@korzhik:
Собственно это и происходит в классе Object_Object…
Брррр а зачем тогда определены методы setTitle?
@korzhik:
Это конкретная реализация гетера/сетера для поля title, т.к. в PHP нет реализации гетера/сетера для конкретного поля, то я сделал этот функционал в классе Object_Object…
То что никаких обёрточных классов не нужно, это совершенно очевидный факт, но всё же
непонятно, чем конкретно “плохи” названия функций, зачем их переименовывать?
мне кажется дело не в названиях, а в путанице аргументов, сам не раз прибегаю к мануалу..
Сделали бы везде – функция(ЧТО, ОТКУДА, …), а довольно часто бывает (ОТКУДА, ЧТО, …) в этом и путаница