Как стать автором
Обновить

Object-oriented PHP

Время на прочтение5 мин
Количество просмотров1.5K
Здравствуйте. Хочу презентовать хабрасообществу альфа-версию новой open-source библиотеки на PHP для работы с примитивами(string, integer, float и array) как с объектами.

Под катом — короткое описание, ссылка на гуглокод, описание целей и планов.

Сразу скажу огромное спасибо greedykid, который помог мне в отлавливании огромного количества багов и покрытии юнит-тестами на 80%. Думаю, если вам понравилась библиотека, он заслужил кармы не меньше, чем я.

Мысли вслух


При всей моей любви к пхп никогда не понимал слегка наплевательского и грубого отношения его разработчкиов к дизайну.
В одном месте они плюют на обратную совместимость и делают непонятно что, в другом — даже не стараются ввести какие-то стандарты кодирование (ну вот, например, почему вместе с неймспейсами не ввести бы \array\* и \string\* функции, а старые со временем объявить как deprecated?)
Еще один пример наплевательского отношения — класс Array_Object, который просто поражает своей скудностью. Ну если уже взялись сделать, то почему бы не сделать серьёзно и изящно?

Цели


Цели данной обёртки, в отличии от большинства обёрток подобного типа — не демонстрация возможностей, а полноценное использование в рабочих проектах, используя все преимущества, которые даёт нам такой подход — полноценный TypeHinting, наследование и т.д.
Также, была цель максимально облагородить ужасные названия функций и непоследовательность методов. Была попытка внести стиль именования и порядка аргументов методов.
Некоторые методы, по моему мнению, использовать стало намного проще (очевиднее), большинство методов использовать субъективно приятнее, чем встроенные функции.
Хотелось банально добавить изящества грубому php-core. И в основном, где язык не стал преградой, это получилось прекрасно

Нюансы


В отличии от большинства подобных библиотек — данная библиотека отлично работает сама с собой. То есть, например, Map будет считать одним значением что new String(«abc»), что «abc». То есть $map[«key»] и $map[new String(«key»)] ­— равносильны.
Так как это объекты — все значения передаются по ссылке. Со всеми вытекающими.
Кое-где мы уперлись в ограничения php. Например, при использвании foreach ($map as $key => $value) $key возвращается примитивным значением, а не объектом, потому рекомендуется использовать альтернативный, не менее красивый синтаксис: while($map->each($key, $value)) {} или $map->loop(function ($key, $value) {}), который можно использовать не выходя из цепочки вызовов.

Планы и надежды


Надеюсь, что многим понравится эта библиотека. Кто-то захочет быть просто пользователем, кто-то — пользователем + активным баг-репортером.
И, естественно, надеюсь на то, что найдутся желающие принять участие в разработке проекта. Надеюсь на скорый выпуск более-менее стабильной версии
После этого хотелось бы видеть расширение на Си, соответствующее по интерфейсам этой либе. Это будет вообще отлично. На небольших проектах можно использовать пхп-код, зная, что если проект разрастётся и станет большим достаточно будет установить это расширение и потери производительности от этой обёртки не будет. Имхо, это будет хороший толчок.
А там, как знать, может быть, лет через восемь в Васюках состоится первый в истории мироздания междупланетный шахматный конгресс!

Пример кода


<?
$map
    
->clear(function ($key$val) {
        
// Удалим все элементы, где ключ равен значению
        
return !$key->equals($val);
    })
    ->
join(' '// String
    
->replace(',''зпт')
    ->
pregReplace('/([0-9]+)/', function ($m) {
            return 
"!$m[0]!"// Some string with number(e.g. !12345!), is here
    
})
    ->
changeCase(Str::TITLEStr::UP_FORCED)
    ->
insert('[вставлено]'5)
    ->
length() // Number
    
->multiply(4)
    ->
add(69, new Number(15))
    ->
divided(5)
    ->
sum(Number::EVEN)
    ->
dump() // (Number) 1062.51
    
->root(4)
    ->
round(3// Just 3 symbols after dot
    
->dump() // (Number) 5.709
    
->round(Number::UP// round to up (ceil)
    
->hex('15abbf')
    ->
toString() // String ('1420223')
    
->hash() // 'md5' as default
    
->dump(); // (String) '0d1b1558224c8f3b125cd905c378c9f7'

// Смотрите «KurrencyKonverter.php» в примерах
$uah = new KurrencyKonverter (500); // KurrencyKonverter extends Number
// Сколько долларов у нас будет, если мы купим их в Украине за 500 гривень
echo $uah
    
->copy()
    ->
convert('Currency.Ua.Sell''UAH''USD')
    ->
toString(2); // 63,02
// Сколько долларов у нас будет, если мы купим в Украине за 500 гривень рубли, а потом в России за эти же рубли - доллары
echo $uah
    
->convert('Currency.Ua.Sell''UAH''RUR')
    ->
convert('Currency.Ru'     'RUR''USD')
    ->
toString(2); // 44,77

Подробнее — на гуглокоде. Рекомендую посмотреть примеры — там можно найти много интересного)

Предупреждение


Предсказуеумые и унылые желающие крикнуть «Зачем изобретать велосипед?», «ООП ради ООП» и «КГ/АМ» заранее посланы матом
Любители покричать о спичечной оптимизации посланы изучать Ассемблер
Принимаю восторженные отзывы и конструктивную критику :)

Ссылки


Обсуждение первой alpha-версии на php.ru

Проект на гуглокоде



Примечания


Принимаются как багрепорты, так и предложения. Рекомендую почитать тему с обсуждением на форуме php.ru — там можно узнать много интересного про возможности библиотеки. Там же можно заметить, что интересные приложения достаточно быстро воплощаются в жизнь.
Желание помочь в написании кода — приветствуется)
Естественно, пока возможны баги. Но на то она и альфа-версия)
Лицензия — LGPL

пс. По ходу статью могу редактировать, добавлять новые мысли
Теги:
Хабы:
Всего голосов 104: ↑70 и ↓34+36
Комментарии122

Публикации

Истории

Работа

PHP программист
148 вакансий

Ближайшие события