Комментарии 39
Мне подобный прием кажется грязным. Не очевидно(потому что там где у вас регулярки должен быть тип), легко может быть затерто программистом, встроенные валидаторы IDE для регулярок не работают.
PS: Очень много всего на отражениях завязано в phpUnit, но там в большинстве своем используются custom аттрибуты (@dataProvider например), не пересекающиеся со стандартным функционалом doc-блоков.
PS: Очень много всего на отражениях завязано в phpUnit, но там в большинстве своем используются custom аттрибуты (@dataProvider например), не пересекающиеся со стандартным функционалом doc-блоков.
+7
Я решил использовать аннотации, т.к. обычно для контроллеров вообще не пишу никаких комментариев, да и вызываются эти функции в основном автоматически, т.е. подсветка и подсказки из IDE особо не нужны и мешать они не будут. И наоборот плюсы есть от близости проверок к месту использования, не надо лезть в дальний файл с роутингом, чтобы проверить $num может быть [a-z0-9] или только [0-9].
В любом случае, PHPdoc описание для этих переменных выглядит так:
Т.е. как раз использование «не пересекающиеся со стандартным функционалом doc-блоков»
Вероятность любого кода быть затертым кем-то левым существует всегда, но от этого не застраховано вообще ничего :) Мне опасность кажется несколько надуманной, в той же Symfony2 они не побоялись.
В любом случае, PHPdoc описание для этих переменных выглядит так:
/**
* Тестовое действие
* @a /^[0-9]+$/i
* @b /^[0-9a-z]+$/i
* @var a int
* @var b string
*/
Т.е. как раз использование «не пересекающиеся со стандартным функционалом doc-блоков»
Вероятность любого кода быть затертым кем-то левым существует всегда, но от этого не застраховано вообще ничего :) Мне опасность кажется несколько надуманной, в той же Symfony2 они не побоялись.
0
Опасность не самое верное слово.
Но мне кажется, что подобный подход имеет смысл в phpUnit, который не часть программы, не обитает на production сервере и с его зависимостями/аттрибутами и правда пришлось бы париться без doc-блоков. Но для организации валидации аргументов экшна контроллера я бы не стал его использовать.
По-поводу того, что чем ближе — здесь мне нравится концепция маршрутов в yii. На оснвое аргументов можно перенаправить действие к другому экшну другого контроллера и вся эта логика хранится в конфигурации UrlManager.
Ниже правильно отписались — магии должно быть как можно меньше и одно дело магические методы, а совсем другое вынос логики в комментарии.
Но мне кажется, что подобный подход имеет смысл в phpUnit, который не часть программы, не обитает на production сервере и с его зависимостями/аттрибутами и правда пришлось бы париться без doc-блоков. Но для организации валидации аргументов экшна контроллера я бы не стал его использовать.
По-поводу того, что чем ближе — здесь мне нравится концепция маршрутов в yii. На оснвое аргументов можно перенаправить действие к другому экшну другого контроллера и вся эта логика хранится в конфигурации UrlManager.
Ниже правильно отписались — магии должно быть как можно меньше и одно дело магические методы, а совсем другое вынос логики в комментарии.
0
Интересно, но это магия, а магии в проекте должно быть как можно меньше для улучшения читаемости кода.
+6
На мой взгляд читаемость наоборот возрастает — сразу видно, какие переменные используются, какие проверки на них наложены.
-3
Читаемость определенно возрастает, я когда начинал с Симфони 2, я воспринял эту особенность в штыки и честно говоря почти передумал ее использовать из-за этого, но сейчас, после пару месяцев работы — я аннотации ни за что не променяю, крайне удобная вещь, конфигурация рутов теперь просто сказка.
Я считаю пока человек не попробует их использовать хоть какое-то время, смысла спорить тут нет.
P.S. Работаю в PhpStorm, проблем не было ни разу.
Я считаю пока человек не попробует их использовать хоть какое-то время, смысла спорить тут нет.
P.S. Работаю в PhpStorm, проблем не было ни разу.
+1
$method->getDocComment();
Обана. Теперь комментарии являются частью кода программы?
/**
* @a /^[0-9]+$/i
*/
function do($fileName) {
file_put_contents($fileName, 'somthing');
}
Написав этот комментарий я уверен, что выполнить ФС-инъекцию невозможно?
А потом кто-то со спокойной совестью проходится обфускатором или ещё лучше энкодером. И тот кто удалит все комментарии будет прав, потому что комментарии не могут никак влиять на ход выполнения программы и тем более не могут влиять на её безопасность.
+10
Я знаю тот факт, что русские не читают инструкцию по применению до тех пор, как что-то сломалось или не работает. Но об этой особенности системы таки следует написать и предупредить, что комментарии являются неотъемлемой частью, а кто не понял, тот ССЗБ
Ну а в особо важных местах, где потенциально есть опасность, можно не использовать комментарий, а по старинке воткнуть прямую проверку.
Ну а в особо важных местах, где потенциально есть опасность, можно не использовать комментарий, а по старинке воткнуть прямую проверку.
-3
НЛО прилетело и опубликовало эту надпись здесь
Имхо, это выглядит эффектно, и кажется удобным, но не более того. Магия вредна, особенно в коллективной и долгосрочной разработке. Если нужны валидаторы — оформлять соответствующие функции, классы с методами или конфиги с валидаторами. Если нравится макропрограммирование — делать компиляторы макрокода в обычный стандартный код. Недостатки описанного подхода очевидны: нарушение принципов программирования (логика находится в… комментариях к коду!), невозможность обработки кода (обфускации например). С архитектурной точкизрения, эти трюки ничем не лучше логики, основанной на файловой системе.
+5
Но косательно обфускации — вопрос спорный. Да, без подготовки — нельзя, посредствам отрожения лишь получается информация о параметрах, которые можно отдельно закешировать. А потом уже проводить абфускацию.
Я очень надеюсь что аннотации будут включены в сам язык. Мне они еще при работе с ASP понравились. Удобно.
Я очень надеюсь что аннотации будут включены в сам язык. Мне они еще при работе с ASP понравились. Удобно.
-1
обфускацию*… Праздники…
0
Чем удобно? Тем, что можно описать в комментариях ожидаемые значения переменных и результата, а потом получать их по код ассисту — бесспорно, удобно. Но только, если это не влияет на ход выполнения. Комментарий должен оставаться комментарием. А для проверки значений явно вызывать валидатор в первой строчке метода.
0
В Yii используют ReflectionAPI для аргументов экшенов, но немногу по другому — он подставляет параметры по имени переменной, а в роутах прописываются именованные параметры.
К тому же на phpDoc полагаться 100% нельзя, поскольку опкод кешеры могут его вырезать (в APC багтрекере точно был баг на эту тему).
К тому же на phpDoc полагаться 100% нельзя, поскольку опкод кешеры могут его вырезать (в APC багтрекере точно был баг на эту тему).
+2
А вы не знаете как обстоят дела с этим багом сейчас? Мне тогда он сильно жизнь подпортил.
0
В Yii еще используется ReflectionAPI для SOAP-сервера. И вот там он смотрит на комментарии.
0
Извините, пожалуйста, но это — жуть! :)
Почему нельзя было сделать так:
addMethodVariable('Controller', 'testAction', 'a', '/^[0-9]+$/i');
addMethodVariable('Controller', 'testAction', 'b', '/^[0-9a-z]+$/i');
Если уж есть в этом необходимость?
Почему нельзя было сделать так:
addMethodVariable('Controller', 'testAction', 'a', '/^[0-9]+$/i');
addMethodVariable('Controller', 'testAction', 'b', '/^[0-9a-z]+$/i');
Если уж есть в этом необходимость?
0
А почему нельзя прочитать название статьи. Внимательно
Потом прочитать дисклеймер.
Потом прочитать постскриптум
И удержаться от комментариев не в тему.
Потом прочитать дисклеймер.
Потом прочитать постскриптум
И удержаться от комментариев не в тему.
-4
Это можно использовать в непосредственно разработке, а в продакшене просто один раз закешировать все роуты и все, все счастливы, хоть заобфусцируйся :)
Но мне лично это не удобно, так как чтобы подправить роут придется лезть в контроллер этого роута, а это лишнее действие, для меня все же проще конфиг отдельный :)
Но мне лично это не удобно, так как чтобы подправить роут придется лезть в контроллер этого роута, а это лишнее действие, для меня все же проще конфиг отдельный :)
0
Мне намного больше нравится как в Kohana 3 сделано. В экшенах вообще нет аргументов, зато все параметры роутинга есть в объекте Request. Т.е. делаем в экшене $a = $this->request->param('a'); и все.
+1
Reflection это очень-очень медленно и использовать его в интенсивных (даже ещё не нагруженных) проектах — есть зло и напрасная утилизация процессорного времени. И кстати, это может поломаться в любой момент при использовании кешеров опкода.
+3
а замеры скорости?
+1
Хм… ну оверхед-то от такого подхода какой? Приходилось видеть упоминание о том, что с Reflection код работал в 3 раза медленее, чем без него. И это на каждом вызове. Поэтому использование Reflection как основной архитектурный подход может неслабо затормозить движок. Так что… есть ли от указанного подхода профиты?
+1
Я не предлагаю использовать этот подход везде и вся. Я вообще не предлагаю его где либо использовать. Я всячески выделил и обратил внимание, что мне было интересно посмотреть и понять как работает Reflection, тем более это используется в крупных фреймворках на определенном примере, который первым пришел в голову.
Тем не менее, не устающие минусовать хабравоины отстаивают догмы истинной веры.
Представьте, что это не контроллер, а тест. Не продакшн, а девелопмент. И вообще все комментарии будут скомпилированы во что-то прекрасное икошерное идеологически верное.
Тем не менее, не устающие минусовать хабравоины отстаивают догмы истинной веры.
Представьте, что это не контроллер, а тест. Не продакшн, а девелопмент. И вообще все комментарии будут скомпилированы во что-то прекрасное и
-1
даже есть разработанные библиотеки для облегчения работы:
code.google.com/p/addendum/wiki/AdvancedFeatures
code.google.com/p/addendum/wiki/AdvancedFeatures
0
НЛО прилетело и опубликовало эту надпись здесь
А какие еще варианты для динамического вызова контроллера?
0
вот такой:
function index($a){return $a;}
$a = 'some interesting string';
$ololo='index';
echo $ololo($a);
function index($a){return $a;}
$a = 'some interesting string';
$ololo='index';
echo $ololo($a);
0
Такой вызов может быть только если заранее известно число аргументов в вызываемом контроллере.
В примере это не так, так что этот способ не подходит.
В примере это не так, так что этот способ не подходит.
0
т.е.? а в таком вызове call_user_func_array( 'index', array( $a )) значит заранее не надо знать кол-во аргументов?
можно написать call_user_func_array( 'index', array( $a,$b,$c,$d,$ololo ) )?
можно написать call_user_func_array( 'index', array( $a,$b,$c,$d,$ololo ) )?
0
Вы невнимательно читали статью :)
Предложите как сделать этот вызов с помощью $ololo(...) не зная количество аргументов для функции.
$arr = CheckURLValid('Controller', 'testAction', $_GET);
call_user_func_array(array('Controller', 'testAction'), $arr);
Предложите как сделать этот вызов с помощью $ololo(...) не зная количество аргументов для функции.
0
что-то я не догоняю. в call_user_func_array(array('Controller', 'testAction'), $arr) неизвестно кол-во аргументов? т.е. в Controller->testAction можно пихнуть их любое кол-во?
0
Таки решил проверить. Простейший скрипт:
На моей девелоперской машине вариант №1 отрабатывает за ~0.000012 секунды, вариант №2 за ~0.000025
Т.е. формально да, очень медленно, аж в два раза. Но это уже ближе к оптимизации на print и echo.
$time = microtime(true);
function index ( $a ) { return $a; }
$a = 'some interesting string';
//Версия №1
echo index( $a );
//Версия №2
echo call_user_func_array( 'index', array( $a ) );
echo number_format( (microtime(true) - $time), 10, '.', '' );
На моей девелоперской машине вариант №1 отрабатывает за ~0.000012 секунды, вариант №2 за ~0.000025
Т.е. формально да, очень медленно, аж в два раза. Но это уже ближе к оптимизации на print и echo.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Возможности PHP Reflection