есть ли phpdoc для магических статических методов?

grigori

( ͡° ͜ʖ ͡°)
Команда форума
привет, не знаете, можно ли описать в phpdoc список статических методов, вызов которых идет через __callStatic?
@method работает только для методов объекта
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ладно, обойдусь без магии

я начинаю писать свою обертку для получения пользовательских данных через filter, вместо той лажи в yii

PHP:
namespace R;


/**
 * A more convenient interface to filters
 * @author gri
 * 
 */
class _Request{
    protected function getScope(){
        switch (substr(static::who(),2)){
            case 'GET': return INPUT_GET; 
            case 'POST': return INPUT_POST; 
            case 'COOKIE': return INPUT_COOKIE;
            default: trigger_error('The scope is not supported',E_USER_ERROR); 
        }
    }

    /**
     * @param string $var
     */
    static function bool($var){
        return filter_input(self::getScope(), $var,FILTER_VALIDATE_BOOLEAN);
    }
    /**
     * @param string $var
     */
    static function numeric($var){
        return filter_input(self::getScope(), $var,FILTER_VALIDATE_FLOAT);
    }
    /**
     * @param string $var
     */
    static function int($var){
        return filter_input(self::getScope(),$var,FILTER_VALIDATE_INT);
    }
    /**
     * @param string $var
     */
    static function intPositive($var){
        return filter_input(self::getScope(),$var,FILTER_VALIDATE_INT,array('options'=>array('min_range'=>1)));
    }
    /**
     * @param string $var
     */
    static function numericPositive($var){
        return filter_input(self::getScope(),$var,FILTER_VALIDATE_FLOAT,array('options'=>array('min_range'=>1)));
    }
    /**
     * @param string $var
     */
    static function email($var){
        return filter_input(self::getScope(),$var,FILTER_SANITIZE_EMAIL);
    }
    /**
     * @param string $var
     */
    static function url($var){
        return filter_input(self::getScope(),$var,FILTER_SANITIZE_URL);
    }
    /**
     * @param string $var
     */
    static function scalar($var){
        return filter_input(self::getScope(),$var,FILTER_UNSAFE_RAW);
    }
}
class POST extends _Request{
    protected function who(){
        return __CLASS__;
    } 
}
class GET extends _Request{
    protected function who(){
        return __CLASS__;
    } 
}
class COOKIE extends _Request{
    protected function who(){
        return __CLASS__;
    } 
}
Usage:
PHP:
$id = R\GET::intPositive('id');
автокомплит работает, не надо ничего помнить

сначала я думал использовать прослойку для возможности подмены источника, и вызовы были бы R\Filter::GET()->intPositive('id');
короткий вариант мне нравится больше, но без описаний в PHPDoc все вызовы на __callStatic не завернуть, автокомплит здесь - главное,
получается копипастить 10 методов по 1 строке, что тоже не очень хорошо в принципе

пока это только прототип для размышления, и к тестирофилам просьба не ругаться
если у кого есть какие мысли - буду рад
 

AmdY

Пью пиво
Команда форума
только есть неймспейсы так не правильно
нельзя использовать пространство имён в вызове, а то половина смысла теряется
use R;
GET::intPositive('id');

только я бы посоветовал по другому, у меня немножко другие проблемы решаются, но гетер тоже делает кастинг типов. Само приведение типов вынесено в отдельный класс
PHP:
/**
     * return value from request
     *      get(0),
     *      get(0, 'default', Kiss_Type::T_STRING)
     *      get('test', 0, Kiss_Type::T_INTEGER)
     *      get('test', new Exception_Badparam('не передан id'), Kiss_Type::T_INTEGER)
     * @param string $key
     * @param mixed $default
     * @param string $type
     * @return mixed
     */
    public function get($key, $default = null, $type = null) {
        if ($this->has($key)) {
            if ($type) {
                return Kiss_Type::run($this->part[$key], $type);
            } else {
                return $this->part[$key];
            }
        } else {
            if (is_object($default) && $default instanceof Exception) {
                throw $default;
            } else {
                return $default;
            }
        }
    }
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
особой разницы в написании неймспейса не улавливаю - use R\*; как в java не напишешь, а все классы перечислять не хочу
if ($post_id = r\GET::intPositive('id')){ немного более читабельно на мой взгляд, чем if ($post_id = GET::intPositive('id')){

приведение типов тут делает сам php,
подумаю над разделением API и самого получения данных по разным классам, и по способу указания дефолтного значения
 

craz

Нестандартное звание
if ($post_id = r\GET::intPositive('id')){ немного более читабельно на мой взгляд, чем if ($post_id = GET::intPositive('id')){
вот уж не скажите, имхо вообще не понятно написано r/ - 1) это не точка как в других языках при обращении к свойтсву, 2) это не :: и 3) не ->

и вообщем как то не красиво вообще смотрится конструкция
 

fixxxer

К.О.
Партнер клуба
Читаемость этой хрени весьма увеличивается, если вокруг бэкслеша ставить пробел.

Ср.:
PHP:
$id = R\GET::intPositive('id');
PHP:
$id = R \ GET::intPositive('id');
 

fixxxer

К.О.
Партнер клуба
А это потому что там лексер тупой, без понятия о контексте. Ну, зато быстрый :)
 

Вурдалак

Продвинутый новичок
Сначала Sokil.Dmytro пишет, что «\» — операция деления (я вот даже сразу и не вспомню в каком ЯП бекслеш выступает в роли оператора деления, причём целочисленного). :confused: Потом fixxxer ему поясняет (?!), что там (в PHP, да?) лексер «тупой»: без понятия о контексте. Я вот этой связи двух предложений не улавливаю совсем. К тому же понятие о контексте совсем не требуется: к примеру, амперсанд может выступать как в роли обозначения ссылки, так и бинарного оператора в зависимости от текущего состояния автомата. Ну, раз ты понял, craz, то объясняй!
 
  • Like
Реакции: craz

craz

Нестандартное звание
Сначала Sokil.Dmytro пишет, что «\» — операция деления (я вот даже сразу и не вспомню в каком ЯП бекслеш выступает в роли оператора деления, причём целочисленного). :confused: Потом fixxxer ему поясняет (?!), что там (в PHP, да?) лексер «тупой»: без понятия о контексте. Я вот этой связи двух предложений не улавливаю совсем. К тому же понятие о контексте совсем не требуется: к примеру, амперсанд может выступать как в роли обозначения ссылки, так и бинарного оператора в зависимости от текущего состояния автомата. Ну, раз ты понял, craz, то объясняй!
ну они короче все понятно написали)
фиксер имел ввиду что вот такую хрень ввели для неймспейсов, чтоб отрабатывало побыстрее, а сокил имел ввиду что "похоже" на деление)

ну или я стал телепатом)
 

Вурдалак

Продвинутый новичок
Если даже это как-то бы повлияло на скорость (pfff), то есть акселераторы.
 

fixxxer

К.О.
Партнер клуба
Не потому что побыстрее. А потому что:

1) Рассмотрим вариант "::". Foo::bar() - это вызов функции bar из неймспейса Foo или вызов статического метода bar класса Foo?
2) Рассмотрим вариант ":". $value ? Foo:bar() : false - опаньки: распарсится как $value ? Foo : bar() и дальше syntax error

итд.

А поскольку в compile time нифига не известно, то и отрезолвить это по контексту (как это делается в том же C++) не выйдет. Не говоря уж о том, что до компилятора дело тут даже и не дойдет, потому что лексер уже всё решил где что :)

Если бы компилятор php был шибко умный - ну... Сравниваем, сколько компилится c и сколько c++, думаем... =) Без акселераторов бы вообще нифига не работало.
 

Вурдалак

Продвинутый новичок
причем тут акселератор?
— акселератор сохраняет байт-код, который будет выглядеть совершенно одинаково какой бы там разделитель не был. Неужели я так непонятно пишу, craz? Других ты понимаешь (хоть и неправильно) прямо-таки сразу.
 

craz

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

Возможно вы еще сможете показать как раз то место где разбираеться данная лексема?
 

Sokil.Dmytro

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

Я кстати тоже не понимаю почему в чем трудности отличить имя неймспейса от имени класса и использовать ::. Над будет разобраться

PHP:
call_user_func_array(array("namespace\typicalClass", "method"), array(1,2,3))
:)
 

craz

Нестандартное звание
... и придумаете как бы слеш изменить на более адекватные :: или точку...

Я кстати тоже не понимаю почему в чем трудности отличить имя неймспейса от имени класса и использовать ::
я имею ввиду что мне не хватит знаний докопаться в исходниках до этого места
 

Вурдалак

Продвинутый новичок
Я кстати тоже не понимаю почему в чем трудности отличить имя неймспейса от имени класса и использовать ::
— трудность в том, что отличить просто невозможно.

Возможно вы еще сможете показать как раз то место где разбираеться данная лексема?
— зачем тебе? См. Zend/zend_language_parser.c (грамматика описана в файле с тем же названием, только с расширением *.y). Он, естественно, сгенерирован. :)
 
Сверху