Лучшие практики типа функции PHP - PullRequest
3 голосов
/ 21 января 2011

Я сейчас работаю над фреймворком и столкнулся с загадкой ... как мне обращаться с неправильными типами параметров, когда кто-то вызывает функцию в фреймворке?

Пример:

// Title is expected to be string, comment_num is expected to be int
function example1($title, $comment_num) {


 // Doesnt throw error, just converts type 
 $title = (string) $title;
 $comment_num = (int) $comment_num;

}

или

// Title is expected to be string, comment_num is expected to be int

function example2($title, $comment_num) {


 if (!is_string($title)) {

  trigger_error('String expected for first parameter', E_USER_WARNING);
  return;
 }

 if (!is_string($title)) {

  trigger_error('Int expected for second parameter', E_USER_WARNING);
  return
 }
}

Или будет работать смесь обоих? Выдает ошибку и все равно конвертируете тип?

Каков наилучший способ сделать это? Я планирую выпустить его, чтобы я не просто использовал его, поэтому я хочу подумать и о лучшем для других. Спасибо.

EDIT !!!

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

function __type_check($params) {

    if (count($params) < 1) {

        return; 
    }
    $types = func_get_args();
    array_shift($types);

    $backtrace = debug_backtrace();
    $backtrace = $backtrace[1];

    $global_types = array(
        'bool'  => 'boolean',
        'int'   => 'integer',
        'float' => 'double' 
    );

    $error = false;


    for ($i = 0, $j = count($types); $i < $j; ++$i) {

        if (strpos($types[$i], ',') === false) {

            $type = strtolower($types[$i]);

            if (isset($global_types[$type])) {

                $type = $global_types[$type];
            }

            if (gettype($params[$i]) != $type) {
                $error = true;
                break;
            }

        } else {

            $current_types = array_map('trim', explode(',', $types[$i]));

            foreach ($current_types as $type) {

                $type = strtolower($type);  

                if (isset($global_types[$type])) {

                    $type = $global_types[$type];
                }

                if (gettype($params[$i]) == $type) {

                    continue 2; 
                }
            }

            $error = true;
            break;
        }       
    }

    if ($error) {
        trigger_error($backtrace['function'] . '() expects parameter ' . ($i + 1) . ' to be ' . $types[$i] . ', ' . gettype($params[$i]) . ' given', E_USER_WARNING);
        return false;
    }

    return true;
}

И вы бы использовали это так:

function string_manipulation($str, $str2, $offset = 1) {

    if (!__type_check(func_get_args(), 'string', 'string', 'int,float')) {

        return false;   
    }   

    // do manipulation here
}

Это в основном проверит, что первый и второй параметры являются строками, а 3-й параметр - целое число или число с плавающей точкой. Вы можете комбинировать любые типы 'string, int, array, object' и т. Д., И все допустимые типы взяты из gettype

/ * Известные ошибки * / null - это тип, не могу решить, должен ли он быть или нет если вы вводите имя класса, он не проверяет экземпляр, а просто проверяет тип не нашел хороший способ вызвать ошибку ... meh

Это от меня, ошибки могут быть легко исправлены: D

Ответы [ 3 ]

6 голосов
/ 21 января 2011

Это зависит.

PHP - это язык с динамической типизацией, а иногда и по уважительной причине.Так как он много работает с данными HTTP, которые все время являются строками, числа не обязательно всегда имеют тип int и все равно будут работать нормально для общих операций.не-PHPish и может быть хлопотно работатьТип становится проблемой.

function example1($title, $comment_num) {

    // do some operations that should work error-free regardless of type

    if ($result != 'something specific you expect here') {
        throw new Exception('Something went wrong!');
        // or
        trigger_error('Something went wrong!');
        return false;
    }

    // continue with $result
}

Вы можете пройти путь ООП и построить объекты таким образом.Объекты будут в некоторой степени гибкими в том, что они принимают.Если им удастся создать, у вас есть определенный объект определенного типа, который вы можете использовать для подсказки типа с применением PHP:

function example1(TitleObject $title) {
    // rest assured that $title is of the right type
}
0 голосов
/ 21 января 2011

Я бы автоматически вводил типы данных int и string без каких-либо жалоб (потому что их было бы легко смешать), но для чего-то вроде ресурса или объекта это могло бы быть полезным для уведомления программиста об ошибке.

Я бы также настроил код уведомления в его собственной функции, чтобы все не было таким повторяющимся.В любом случае, удачи!

0 голосов
/ 21 января 2011

Если что, просто используйте SPLTypes и все готово;в противном случае выведите исключения InvalidArgument

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...