
Ага, вот эти ребята, сейчас я покажу Вам магию ООП.
Вместо предисловия. Об авторах языка
Точнее о траве которую курили разработчики, ну как так можно именовать функции? Ну возьмем для примера функции для работы со строками:
- str_replace(ищем строку $search, заменяем на $replace, в строке $subject [, итого поменяли &$count ] )
- strpos ( в строке $haystack, ищем $needle [, пропускаем $offset символов] )
- substr_replace( в строке $string, заменям на $replacement, с позиции $start [, $length ])
- nl2br (изменяем строку $string [, это $is_xhtml ] )
Как мы видим это очень мрачно, а если брать массивы — в одном месте у нас функция возвращает результат, в другом — работает по ссылке… брр…
Благодаря отсутвию стандартов даже в самом языке, мы имеем некий дискомфорт при работе с данным языком. Да и другие косятся…
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(,100,10) // врапер для range
->size() // врапер для sizeof
;
Как Вам? Даю еще пищу для мозга:
<?php
// создаем массив из элементов
// => array('module', 'controller', 'action')
oArray('module', 'controller', 'action')
// врапер для array_combine
// => array('module'=>'default', 'controller'=>'index', 'action'=>'index')
->combine(oArray('default', 'index', 'index'))
// врапер для http_build_query возвращает oUrl
// => module=default&controller=index&action=index
->to_url()
// добавляем кусочек строки в начало
// => http://domain.com/?module=default&controller=index&action=index
->insert('http://domain.com/?')
// врапер для parse_url возвращает oArray
->parse()
// возвращает array['host']
// => domain.com
->host
;
И еще:
oString("It's my way")
// str_replace => "It's your way"
->replace('my','your')
// substr => "It's you"
->sub(, 8)
// str_pad => "It's you..."
->pad(11, '.')
// str_repeat => "It's you...It's you..."
->repeat(2)
// получаем oArray => array('It's you','It's you', '')
->explode('...')
// удаляем пустые элементы
->clear()
// array_merge => array('It's you','It's you', 'Yes','No','Maybe')
->merge(array('Yes','No'), array('Maybe'))
// implode => It's you;It's you;Yes;No;Maybe
->implode(';')
// return 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!!!
Как видим — подобный класс даже имеет право на существование ;)
Вот такое нехитрое творение у меня получилось, скачать его можно с моего блога:
oObject ver.0.1
P.S. Данные классы не претендуют на жизнь в реальных проектах, они предназначены дабы развеять миф о не-ООП-ешности PHP, а так же послужат неплохим материалом для изучения начинающими программистами…
P.P.S. Я же
обещал сие написать ради холивара…
комментарии (114)
boost это вещь, давай, жги!
Если вас сжимает отсутствие множественного наследования и перегрузки — меняйте язык. Нет смысла кукожить обходными путями PHP.
В одном из проектов 15% сжирало использование геттера вместо public свойства. Сам в шоке :) PHP 5.2.8
Я не знал, что Вы писали эти обертки не для использования, а только ради ООП.
Fatal error: Exception thrown without a stack frame in Unknown on line 0
С опытом напрягает это все меньше и меньше. Но. Иногда хочется, чтобы настал такой момент, например к выходу PHP6 — хрен с ней с обратной совместимостью — чтобы причесали все названия функций и логику того что они возвращают.
Неплохо бы интегрировать с Spl Types
К недостатком кода нужно отнести отсутствие интеграции с стандартными интерфейсами.
Посмотрите например на сlass ArrayIterator с пакета Spl.
ИМХО: юнит тестов нехватает, вообщем пялить и пялить :).
Если так не нравится пхпшная каша из функций, не мучайтесь и пишите на RoR.
anton.shevchuk.name/php/php-library-for-jquery/
На… всех хостингах…… ставьте……
пОцаны — это производное от ПОЦ… или… я… не…… понял?
:-D
XSLT2.0 вообще так всего две реализации. Это о чем говорит? О неоправданной сложности.
Schema-aware XForms я еще не встречал. WXS это бегемот какой-то, никто его не может реализовать.
Впрочем, LAMP устарел, да.
Нет, веб это до сих пор (!) HTML 4, уже десять лет как (плюс припарки в виде CSS/JS). XHTML так и не получил должного распространения (и вряд ли получит: работы над XHTML2 все еще не закончены, а работы над XHTML1 уже давно прикрыты).
Да и потом, если брать XHTML, то посмотрим на другие технологии их состояние:
— SVG (переусложнен, противоречив, никому из интырпрайза нафиг не нужен)
— SMIL (кто-нибудь вообще слышал о нем? %))
— MathML (ну и где они, реализации?)
— XForms (я видел только одну реализацию для браузера: плагин в FF, но он даже под 3-ю версию не портирован...)
В этих технологиях несомненно есть хорошие идеи, но на деле они никому не нужны.
> единственные «минусы» которых — отсутствие знаний у разработчиков
Ну да, а еще:
— непоследовательность (эх, W3C...)
— отсутствие интеграции (даже несмотря на то, что XPath 2.0, XQuery 1.0 и XSLT 2.0 используют одно представление XML)
— сложность реализации
Ну и прочие «мелочи».
Как это реализовать в PHP — думайте сами.
А так — спасибо) Переделаю под себя под UTF-8 с нормальными именами)
$x->вСтроку('1234.5')->заменить('.',",")->развернуть(); ?%-ЮвСтроку(э1234ю5э)-Юзаменить(э.эб э,э)-Юразвернуть()ж
(а то лень раскладку постоянно менять...)
Иногда в поисках возможности создать что-то более простое, чем имеющиеся стандартные методя языка приводят к абсолютно другому результату. Это я к тому, что есть некоторая грань, которая стоит в максимальной простоте и удобности для большинства пользователей. Эта грань очень сумрачна и размыта и определяется только временем. Если есть в языке неудобные штуки — появляются заплатки, которые делают их удобными и т.д.
Всегда есть возможность сделать лучше. Абсолютно всегда. Всегда, в любую систему можно добавить новый функционал или улучшить старый. Но не всегда это нужно.
то что вы сделали конечно предполагает очень красивое написание, не спорю. Только вот можно обойтись без этого? Думаю, что да. Тем более, что если к странностям php (а такие странности в любом языке есть) привыкаешь, то уже не думаешь над названиями функций.
Вобщем, конечно красиво, но я бы не стал этим пользоваться. Потому что кроме красоты это мало что дает. Но за эту красоту надо еще заплатить 1) тем, что надо все-таки врубаться в ваши классы 2) что лишних ресурсов это чуть-чуть да сожрет. А при частом использовании может и не чуть-чуть.
Как я уже говорил, данный пример и не должен использоваться в живых проектах — лишь для самообразования… (хотя некоторые элементы реализации и имеют право на существование)…
— Здравствуйте, — говорит.
И начинает раздеваться.
Снимает рубашку, складывает её по швам, пуговки застегивает и кладет на стул.
Снимает майку, тоже складывает и укладывает рядом с рубашкой.
Ботиночки рядом поставил, носки снял, разгладил и рядом положил.
Брюки по стрелочкам и на спинку стула, трусы снимает, тоже по швам разгладил рядом с майкой положил и говорит:
— Знаете, доктор, вот посмотрите, у меня одно яичко чуть выше другого.
— Ну и что тут такого?
— Как что? Неаккуратненько как-то.
framework.zend.com/manual/en/coding-standard.naming-conventions.html#coding-standard.naming-conventions.filenames
Или действительно существуют какие то ограничения на уровне языка?
Своим постом вы только подтвердили убогость языка, называя ЭТО «магией ООП».
какая еще «убогость»? что за «ЭТО»? Что есть «не убогость»? Где нет «ЭТОГО»?
А Вы на каком уровне с Руби знакомы? Можно посмотреть сравнительные примеры «убогости» PHP и «неубогости» Ruby?
Во-вторых, мне вот щас действительно не очень хочется расписывать какие-либо преимущества руби перед пхп. Если вам действительно интересно, посмотрите на рельсы, там вся эта магия руби очень основательно используется, даже слишком, благодаря чему исходники крайне запутаны, а конечные интерфейсы зачастую может и выглядит красиво, но до фига не удобны, когда хочется выйти за рамки задуманого разработчиками. Тем не менее мы сейчас говорим о возможностях языка, а он как раз позволяет делать такое. Для примера можете взглянуть на реализацию коллекций ассоциаций в рельсах и подумать как подобное можно было бы реализовать в пхп. Те кто думает что CakePHP — это «как RoR» сильно заблуждаются.
«вы только подтвердили убогость языка» — habrahabr.ru/blogs/php/47785/#comment_1229894
> Те кто думает что CakePHP — это «как RoR» сильно заблуждаются.
А причем здесь какие-то Рельсы и какой-то там КейкПХП?
Вы дали четкое определение «убого» относительно ПХП: «убого» это когда называют «магией ООП» засовывание кучи функций во враппер-класс. Вот мне и интересно — где «не убого»? Определенно же — Вы должны знать ответ на этот вопрос, раз так категорично определяете «убогость» PHP. Или я ошибся?
> Для примера можете взглянуть на реализацию коллекций ассоциаций
а что за коллекции ассоциаций?
а в Руби не так разве?
Это все конечно мелочи, но крови попортили достаточно
это во многих реализациях так
Но это все равно не ООП :)
Ситуация схожа с выпуском на рынок популярных китайских фейков.
Выглядит также, а пользуешься, понимаешь реальную разницу.
а что есть ООП? В Вашем понимании.
все эти претензии к дизайну PHP говорят лиш о низком уровне владения данным языком. вот поработаете подольше с ним (если конечно будет желание), то поймете что все эти обертки и костыли якобы для улутшения — не нужны, т.к. php уже имеет много чего встроенного.
насчет того, что функция может «портить» аргумент, работая с ним по ссылке и никак этот факт визуально не определить — тоже плохо (например, можно было бы помечать такие имена функций знаком восклицания в конце — obj.sort!), но с другой стороны — можно посмотреть всегда документацию и уточнить такие моменты (поскольку все случаи невозможно предусмотреть и где-то нужно, чтобы функция преобразовывала объект-параметр)
насчет неинтуитивных возвращаемых значений ('', 0, false) — да, тоже бы неплохо иметь хоть какой-нибудь конвеншн, но и в других языках, я не уверен, что с этим моментом все четко
по поводу, что такое ООП-язык и что такое не-ООП-язык — пожалуйста, все, кто утверждает об принадлежности или непринадлежности языка к ООП — придите сюда и четко изложите свои мысли и доводы, что такое настоящий ООП язык, откуда вы эти рамки взяли и с чего, вообще, взяли, что предложенное вами определение будет верным в последней инстанции? Можно будет взять различные фундаментальные труды и их определния, соотнести, что схоже, что нет (что должно быть обязательно, что — не обязательно, и почему) и т.д. Это будет конструктивней и инстересней, нежели твердеть с деловым видом об «убожестве» чье-то, довольно мощной, разработки.
А устраивать какие-то сомнительные холиворы (не являясь при этом создатилями ни PHP, ни Ruby) — вообще какая-то ерунда.
— чье-то => чьей-то*
— создатилями => создателями*
Настоящее ООП, по всей видимости, присутствует только в Smalltalk, но и там основным элементом является посылка сообщения, а не объекты, хе-хе.
в Smalltalk — одна из реализаций объектной системы; любая иная реализация вправе вносить свои изменения, если они технически и идеологически обоснованы и отвечают тербованиями поставленых задач.
Фтопку.
Только в конце не забудьте циклом фор например сравнить скорость работы с и без этих оберток. И прозреете. :)))
PS: данный кастом не претендует на жизнь в реальных условиях, он предназначен дабы развеять миф о черепашности 2101, а так же послужит неплохим материалом для изучения начинающим психиатрам
Меня устраивают и базовые функции php (как названия, так и return'ы — привыкнуть можно)
Или я тут чего-то очень интересного/удобного не заметил (добавление восклицательных знаков и ucfirst не в счет, думаю, и так понятно, что в геттере/сеттере можно обрабатывать значения)?
Мне кажется, интереснее было бы написать о реализации «виртуальных» геттеров, например. Ну это так…
ка-то на пхп-Клубе высказался, что согласно классификации Буча, пхп не явл объектно-ориентированным языком. Объектным — да… за что был закидан помидорами.