а вообще забавный это зверёк - руби. в своё время ни перл ни питон как-то не торкнули. прикольно конечно, но не более. а вот руби похоже что самое то. одно но - как отучиться на автомате ставить ; в конце строки :-?
При всём моём презрении к пхп как к языку с уродливым, эволюционно-костыльным дизайном, и при уважении к идеям, заложенным в дизайн руби - таки скажу за похапе.
> а вообще забавный это зверёк - руби. в своё время ни перл ни питон как-то не торкнули. прикольно конечно, но не более. а вот руби похоже что самое то. одно но - как отучиться на автомате ставить ; в конце строки :-?
когда то давно в C++ мне очень не хватало любимых дельфевых атрибутов класса. ручные гетеры/сетеры с отличным от синтаксисом выглядели редким убожеством. похоже, я таки дождался, когда истина восторжествует на примере руби :)))
ps: да, я в процессе открытия для себя этого инструмента так что свой ЖЖ я буду вести прямо тут.
так неинтересно. цель-то какая? на пхп как ни стараются, а любой MVC фреймворк тормозит шопипец. даже самый быстрый из популярных, CodeIgniter, по reqs/s уступает не сильно-то и быстрым рельсам раз в пять. и вообще, http://www.avnetlabs.com/php/php-framework-comparison-benchmarks - это ли не звиздец? с другой стороны, популярность на хостинге и дешевизна, угу.
>одно но - как отучиться на автомате ставить ; в конце строки :-?
можешь не отучаться) в руби можно использовать ";" как разделитель. но в этом случае все стейтменты(черт, вот как перевести "стейтмент" правильнее? у меня обучение на английском было, извините :/ ) с ";" в конце строки будут интерпретироваться вместе, т.е.:
>> a = "some string";
*> b = a;
*> d = c;
*> puts d
NameError: undefined local variable or method `c' for main:Object
from (irb):3
>на пхп как ни стараются, а любой MVC фреймворк тормозит шопипец
Ну, не знаю, мой вполне шустро бегает. А уж когда задействовано статическое кеширование (даже форум на нём) - так вопрос быстродействия языка вообще не у дел :)
>CodeIgniter, по reqs/s уступает не сильно-то и быстрым рельсам раз в пять
По твоей ссылке он RoR немного превосходит. 98-118 r/q для разных php-акселераторов и 86-96 для разных реализаций у RoR.
Насколько я помню такой же тест (или это он же? Влом комменты вычитывать) Django сделал PHP в 5 раз, все порадовались, потом, как обычно, автору теста указали на отсутствие акселератора. Тот честно измерил с ним и отметил, что с акселератором у PHP вышло пятикратное ускорение, чем без него. Но общую таблицу результатов поправлять не стал :D
> Интерпретируется при каждом запросе в любом ЯВУ. Хоть в Питоне, хоть в Руби
Надо отметить, что в PHP всегда есть бутстраппинг на каждый запрос. И приложения с тяжелой инициализацией начинают прилично тормозить. В питоне и руби этот этап происходит только при старте fcgi/wcgi сервера.
И, товарищи, вспомним и содрогнемся от php'шных фаталов. По-моему, больше ни в одном интерпретаторе нет такой дебильной схемы. Как можно разработчика оставить без трейса? Вобщем продолжаем плакать и давиться этой блевотиной.
Забываем про trigger_error(), юзаем throw. На текущий момент там есть вполне приличная система исключений. Хочешь по умолчанию видеть стек? Пожалуйста:
function myExceptionHandler($e)
{
echo get_class($e).' at '.basename($e->getFile()).' line '.$e->getLine().':'.$e->getMessage().'<PRE>'.$e->getTraceAsString().'</PRE>';
}
set_exception_handler('myExceptionHandler');
Ну, и debug_backtrace() опять же никто не отменял. В общем и целом, жить можно. Хотя да, плачем.
>Как увидеть трейс для такого?
>$a = null; echo $a->field;
Да, я после написания коммента уже вдруг понял, что просто не понял ваших проблем. Потому что у меня давным-давно не возникало такой проблемы. А не возникало её по тривиальной причине: правильный стиль программирования. То есть для меня fatal - это _всегда_ повод внести локальные изменения, то есть трейс просто не нужен. Это либо ошибка в этой же функции, что правится локально, либо неправильные параметры, что сразу же служит поводом для if(неправильный параметр) throw new myException("Внятное сообщение"); В общем, смотри "программирование по контракту" и прочее XP.
> Я всегда юзаю $a->field(); - оно много гибче выходит :)
Если у нула вызвать метод, то тоже будет фатал. Данный пример показывал несерьезность интерпретатора, а не OOP beauty. Кстати в питоне и руби есть нормальные проперти.
Вообще, до определенного уровня, пхп достаточно хорош. Но при тесной интеграции с энтерпрайз окружением начинаеся веселье.
1) SOAP. SoapClient годен только для достаточно простых вещей, шаг в сторону от простых бинов и энвелоп собирать и разбирать надо самому.
Нельзя структурировать SoapFault, для оборачивания внешних исключений надо приделывать свои костыли.
2) Messaging. ActiveMQ. Если продьюсинг еще более менее рабочий (через StompClient), то написать надежный консьюминг это задача не для слабонервных. Иногда процесс просто вешается.
3) Сборка мусора. Отвратительная. Сложные объекты со ссылками не подбираются. В итоге, после какого-то количества запросов, процесс вылетает с memory limit. Или, если надо запустить пакетную обработку, допустим миллиона объектов. Приходиться бить поток на куски и форкать детей для обработки. Иначе процесс тоже до конца не доживет.
4) Нет потоков. Тут, как говориться, "no comments".
Список можно продолжать. Единственно, что заставляет в наше время продолжать писать на пхп -- это куча написанного на нем кода. Других объективных причин нет.
> То есть для меня fatal - это _всегда_ повод внести локальные изменения, то есть трейс просто не нужен
Я могу только сердечно поздравить. Но бывают ситуации, когда трейс нужен, а его нет. Это memory limit, time limit, recursion limit.
А еще бывают проблемы с автоматическим класс лоадером, интерпретатор просто молча умирает, тут спасает только сгенерированный профайлером валгринд лог.
Так проверять нужно. У Си тоже если к NULL-указателю обратиться, сегфолт словишь.
1,2 Ты уверен, что это в нише PHP нужно? :)
3 - я с PHP уже лет 8 вожусь. И ни разу не помню проблемы сборки мусора :D Идеология, как бы, другая, чем в Java... Хотя миллионы объектов обрабатывать доводилось. А сотни тысяч (сложных) - в memcached висят вообще постоянно :)
4 - а нафига они в PHP, если ими web-сервер может заниматься?
Найди предыдущее упоминание :D Боюсь, как бы б уже не месяца три прошло. Вряд ли это часто. И, заметь, ни ссылок тут, ни имён - какая же это реклама или хвастовство? :D Просто привожу примеры из своей PHP-практики. И что из того, если она последние пару лет фактически с одним продуктом связана?
Точно также, как если разговор зайдёт о Java я говорю об ныне замороженном L2F.
Буду ещё с чем-то много работать - буду упоминать новый продукт :)
Основной проект, над которым работаю -- http://baza.farpost.ru крутится на одиннадцати серверах. В мои задачи входят функциональное тестирование и разработка рекламного движка.
Полгода назад мы решили монолитный кусок php-кода разбить на слабосвязанные веб-сервисы (масштабируемость, управляемость и все такое...). Так появились сервисы рекламы, биллинга и поиска. Написаны на яве. Синхронные вызовы через SOAP. Асинхронные через ActiveMQ.
Вобщем, авантюра. Опыта ни о кого не было. У всех на ушах только маркетоидные дифирамбы. Никто даже и не подозревал, что php настолько безнадежен.
Более того, каюсь, чтобы не переписывать клиентский код под новый api рекламы, я решил сохранить все старые интерфейсы, и "просто" написать имплементацию, работающую удаленно, через SOAP. Угу, наивный чукотский парень.
В итоге, java-сервис был написан, php имплементация сделана. На моей рабочей машине все идеально работало. Торжественный момент -- вливание кода в основную ветку, билд, деплой и... на продакшене все обсирается. Сервер тупо не справляется с нагрузкой.
Короче, две недели не было рекламы. Танцы с кэшированием, с оптимизацией количества soap-call'ов на страницу. Потом месяц ловил таймаут при отсылке soap запроса (php не дожидаясь ответа сервера просто умирал!). Еще веселуха с wsdl'кой. Если SoapClient не может ее скачать, то это ФАТАЛ!!!
В итоге. Все, конечно устаканилось. Сделаны соответствующие костыли. Получил коллосальный опыт построения сложных гетерогенных сред. Спасибо начальнику, который терпел все мои обещания о том, что вот-вот, к концу недели, все стабилизируется и заработает. И, однако, внешний сервис -- это очень удобно. Можно без проблем его отключить. Легко пилится нагрузка. К тому же все плюсы явы, связанные с малой стоимостью рефакторинга. Явашная модель с того момента изрядно переделана, клиенты остались в щастливом неведении.
Если бы я вернулся к моменту принятия решения о выделении рекламы в отдельный сервис. Не раздумывая принялся опять, только вместо удаленной модели сделал бы фасад. Энтерпрайзные штучки в сложных системах себя оправдывают целиком и полностью.
Следом за рекламой пошли биллинг и поиск. Мои коллеги также матерились и плевались на php. Как раз в поиске возникла проблема сборки мусора, когда невозможно пройтись по всем объявлениям и отправить их на индексацию.
> а нафига они в PHP, если ими web-сервер может заниматься
Представь, как здорово бы было. Побыстрее отдать клиенту страницу, а в отдельном потоке записать статистику. Сейчас в умах гуляет идея все тяжелые операции, не связанные с рендерингом страницы, вытащить в конец реквеста и поиграться с ob_flush()
> На моём фреймворке довольно извращённый автоматический класслоадер. И не помню ни одного случая, чтобы интерпретатор умер
У нас три с половиной тыщи классов. Возможно дело в пределе прочности интерпретатора. Мы этот предел испытываем каждый день :)
>У всех на ушах только маркетоидные дифирамбы. Никто даже и не подозревал, что php настолько безнадежен.
В общем, как и следовало ожидать, PHP тут не при чём :D Если кто-то рекламирует парацетомол как панацею от всех бед, а другой пытается лечить им рак, то парацетомол тут не при чём. И хуже в своей нише он не становится :D
>Короче, две недели не было рекламы.
Обновление боевого движка без серьёзного тестирования - это ещё лучше. И опять PHP виноват? :)
>> а нафига они в PHP, если ими web-сервер может заниматься
>Представь, как здорово бы было. Побыстрее отдать клиенту страницу, а в отдельном потоке записать статистику.
У меня для решения такой задачи просто есть отдельная task-система. Я быстро отдаю клиенту страницу и записываю задание в очередь. Отдельный, даже не web'овский, а консольный PHP-поток (или несколько, если потребуется) сидит и разбирает тормозные отложенные задачи. У меня это обычно всякая поисковая индексация, сбросы тяжёлых кешей и т.п.
>У нас три с половиной тыщи классов.
И все-все загружаются?? И умный класс-лоадер написать, который будет грузить классы по запросу - ломает? :) У меня классов на среднем проекте всего штук 500, но загружаются - считанные единицы. При чём процесс загрузки ничуть не усложняется. __autoload() рулит. Никаких лишних include'ов, автоматический выбор классов из подкаталогов, да ещё из разных мест...
$cat = new airbase_forum_category($cat_id);
и оно, если соответствующий класс ещё не загружен, само возьмёт его с {один из ряда базовых каталогов в порядке приоритета}/classes/bors/airbase/forum/category.php
Хотя прямое конструирование объектов у меня большая редкость, обычно идёт что-то типа $cat = object_load('airbase_forum_category', $cat_id); или даже $cats = objects_array('airbase_forum_category', array('id IN' => array(1,2,5,7...))); - это уже работает с ORM (в т.ч. мультиобъектным), кешированием объектов и в рамках одного процесса, в памяти, и с memcached, с автосохранением изменённых объектов и т.п.