<rmcreative>

RSS

Yii: параметры для действия контроллера

30 августа 2010

В стремительно приближающемся релизе Yii 1.1.4 будет довольно приятная возможность. Теперь можно будет использовать $_GET-параметры как параметры действия контроллера.

Теперь вместо:

class PostController extends CController
{
    public function actionCreate()
    {
        if(isset($_GET['category']))
            $category=(int)$_GET['category'];
        else
            throw new CHttpException(404,'invalid request');
 
 
        if(isset($_GET['language']))
            $language=$_GET['language'];
        else
            $language='en';
 
 
        // ... действительно полезная часть кода ...
    }
}

можно будет так:

class PostController extends CController
{
    /**
     * Создание поста.
     * @param integer $category ID категории нового поста
     * @param string $language язык нового поста
     */
    public function actionCreate($category, $language='en')
    {
        // ... действительно полезная часть кода ...
    }
}

При этом, если в $_GET не оказалось указанного параметра и для параметра нет значения по умолчанию, будет выброшено исключение CHttpException.

Если в PhpDoc метода присутствуют типы параметров (поддерживаются integer(int),boolean(bool),float(double) иstring`), происходит автоматическое приведение типа из $_GET к указанному.

UPD: после пары дней внутренних и внешних обсуждений было решено выкинуть приведение типов.

Комментарии RSS

  1. №2964
    Владимир
    Владимир 30.08.2010, 15:57:56

    Классно!

  2. №2966
    Psih
    Psih 30.08.2010, 16:51:12

    Супер :)

  3. №2967
    Exel
    Exel 30.08.2010, 17:17:24

    Звучит здорово :-)

    Но как вы из PhpDoc тип-то выцепляете? Не медленно ли это?

  4. №2968
    Андрей
    Андрей 30.08.2010, 17:38:22

    Интересно вы всегда создаете объекты через $_GET?

    если так то почему в "urlManager" не сделать правило "/post/create/<category:[a-z]+>/<language:[en|ru|ua]>"=>'action/controller' ?

  5. №2969
    AntonYu
    AntonYu 30.08.2010, 17:38:23

    Вау-вау-вау. Мега удобно.

  6. №2970
    Scriptin
    Scriptin 30.08.2010, 18:17:07

    Меня тоже интересует вопрос насчет скорости вытягивания типов с помощью PhpDoc, а также такой: что будет, если я захочу убрать все комментарии?

    Я считаю, что все-таки лучше явно делать валидацию параметров, тем более что фреймворк к этому располагает (класс CValidator и производные). И как в этом случае отключить валидацию по PhpDoc?

  7. №2971
    Dr.Death
    Dr.Death 30.08.2010, 18:18:24

    Напоминает register_globals от которых все открещиваются :D

  8. №2972
    Sam
    Sam 30.08.2010, 18:33:07

    Exel

    PhpDoc выцепляем через reflection. Производительность не страдает. По крайней мере для одного единственного вызова на запрос.

    Андрей

    Параметры мапятся только $_GET. На urlmanager завязываться не хотелось, но тоже вариант.

    Scriptin

    Это не валидация, а приведение типов. Если убрать все комментарии, то его не будет. Отключить можно просто не описывая параметры.

    Dr.Death

    Ничего общего с register_globals не вижу.

  9. №2973
    Scriptin
    Scriptin 30.08.2010, 18:51:43

    Sam

    Согласен насчет валидации/приведения. Но приведение типов можно рассматривать как альтурнативу валидации. Не будет ли подход а-ля "фреймворк все сделает за вас, ничего вам не сказав" (ключевой является заключительная часть фразы) мотивировать неопытных разработчиков на отказ от явных проверок и приведений?

    Вариант "чтобы отключить - не пишите" выглядит очень обдуманным решением.

  10. №2974
    Scriptin
    Scriptin 30.08.2010, 18:52:43

    Ой, s/выглядит очень обдуманным/выглядит НЕ очень обдуманным/

  11. №2975
    Sam
    Sam 30.08.2010, 19:22:35

    Приведение типов и валидация — штуки совершенно разные. Валидация никуда не девается.

    Есть вариант лучше?

  12. №2976
    Scriptin
    Scriptin 30.08.2010, 20:12:59

    Sam

    Да пусть будет :) И я не говорю, что валидация куда-то девается. Просто неявные преобразования иногда могут чреваты негативными последствиями. Пример: удаление комментариев, нарушающее работоспосоность программы.

    Насчет альтерантивы имел в виду вот что: если в качестве параметра "идентификатор чего-то" приходит строка "12", то ее приведение к int уже включает валидацию, потому что ничего кроме целого числа мы не получим - это уже исключает SQL-инъекции. Про то, что это разные вещи, я уже выше согласился.

  13. №2977
    boston
    boston 30.08.2010, 21:02:53

    Отчасти похоже на реализацию в recessframework, но там более гибко и сложнее:

    /**
     * !RespondsWith Layouts
     * !Prefix Views: home/, Routes: /
     */
    class MyHomeController extends Controller {
     
     /** !Route GET */
     function index() {
      $this->flash = 'Welcome to your new Recess application!';
     }
     
     /** !Route GET, /hello/world/$fut/$rrrt */
     function aaaassd($fut='nullll',$rrrt){
      $this->flash = 'aewqewqe';
      $this->fffff = 'p1:'.$fut.$rrrt;
     }
     
    }

    По ссылке более красивое и понятное видео: http://www.recessframework.org/page/clean-urls-with-route-annotations

  14. №2978
    karneds
    karneds 30.08.2010, 21:07:52

    реализовывал подобную вещь у себя с phpdoc. Была проблема при использовании кешеров, в частности с eaccelerator вроде бы. После того как скрипт закеширован, phpdoc уже недоступен для работы.

  15. №2979
    Ekstazi
    Ekstazi 30.08.2010, 21:17:49

    codeigniter многому всех научил)

  16. №2980
    Sam
    Sam 30.08.2010, 21:25:30

    boston

    Recess, к сожалению, в последнее время застрял в развитии.

    karneds

    То есть недоступен? Через reflection?

  17. №2981
    Serge Bezborodov
    Serge Bezborodov 30.08.2010, 23:47:30

    Приведении типов через рефлексию штука удобная, но начинает попахивать кейковской automagick, за то yii и люблю, что все что делается - предельно прозрачно

  18. №2982
    Exel
    Exel 31.08.2010, 15:44:53

    Не, я категорически против приведения типов через reflection/phpdoc. Слишком зыбко, не стоит привязываться к структурам, которые не являются частью языка, имхо.

    Лучше действительно через urlManager что ли...

  19. №2983
    eVerbs
    eVerbs 31.08.2010, 15:59:22

    Вы знаете, хоть я и не сильно большой специалист. Но уже в своем объеме имею проекты на Yii.

    По сабжу - я присоединяюсь к тем кто "против". Я тоже выступаю за прозрачность работы фреймворка. Имхо оно в любом случае лучше для каждого из сторон.

  20. №2984
    Sam
    Sam 31.08.2010, 19:01:01

    Спасибо за отзывы. Как я понял, сама возможность получить таким образом параметры всем нравится. Вопросы только по PHPDoc.

    На данный момент как негативные стороны PHPDoc рассматриваются:

    1. Возможность сделать то же роутером.

    2. Проблема с eaccelerator, скомпилированным без --with-eaccelerator-doc-comment-inclusion (без него вырежет все комментарии).

    3. Слишком магично.

    4. Не часть языка.

  21. №2985
    Владимир
    Владимир 31.08.2010, 22:23:27

    Передача аргументов методу радует.

    А вот пхпдок и ексепшен - нет.

    Про пхп док много написано, а про ексепшн хотелось бы сказать, что через $_GET не всегда передаются обязательные параметры, лучше было бы в случае, если параметр не передан назначать ему null.

  22. №2986
    Exel
    Exel 31.08.2010, 23:10:12

    Вот подумал я тут и пришел к тому, что указание типа для приведения в правилах роутинга тоже не есть блестящая идея... Получается указываем тип в одном месте, а полагаемся на него совершенно в другом. Прошло время, все подзабылось, правила роутинга поменялись и бах, имеем либо ошибку, либо уязвимость... Нехорошо в общем в действии опираться на то, что написано в конфиге роутера.

    Я наверное остановлюсь на хелперах вида:

    public function actionDosomething()
    {
      $id=$this->getParamOr400($name, $type=null);
      // и 
      $id=$this->getParamOrDefault($name, $type=null, $default=null);
    }
  23. №2987
    Sam
    Sam 31.08.2010, 23:10:29

    Владимир

    public function actionCreate($category=null)
  24. №2995
    Владимир
    Владимир 01.09.2010, 18:33:46

    Sam

    Ну это понятно. Но когда null по умолчанию приятнее.

    Да и часто бывает нужно написать свой эксепшн или будет предусмотрено переопределение эксепшенов.

    P.S. а в ближайшем будещем облегченный AR делать не собираются?

  25. №2996
    Sam
    Sam 01.09.2010, 19:24:14

    Облегчённый AR? Что это такое?

  26. №3026
    g
    g 03.09.2010, 14:30:48

    офтопик

    sam Как вам flexicacms? Как система i18n в ней? Можно ли что-то из этого потянуть в фреймворк? Что думаете насчет URL-менеджера и "servises" в нем?

    И правильно ли это выводить админку в модуль и захламляя URL-менеджер, делать проверки на админа. Может лучше все это выкинуть, и спокойно делать админку в отдельном скрипте?

    Расскажите что-нибудь про правильную архитектуру расширяемого приложения на Yii, пожалуйста.

  27. №3036
    Sam
    Sam 03.09.2010, 20:20:03

    flexica я детально не смотрел. Посмотрел в общем плане и немного код.

    Про архитектуру как-нибудь расскажу.

  28. №3054
    Алексей
    Алексей 05.09.2010, 18:41:23

    Александр, а можешь рассказать о планах внедрения миграций в Yii. Помню как то на хабре ты в одном из комментариев обмолвися что скоро будут. Очень бы хотелось надеяться.

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.