2011-01-21 2 views
3

В настоящее время я работаю над фреймворком и приступил к сбою ... как я должен обрабатывать неправильные типы параметров, когда кто-то вызывает функцию в рамках?PHP function param type best practices

Пример:

// 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 !!!

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

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 
} 

Это был в основном проверить, что первые и вторые параметрами являются строками, а третий параметр представляет собой целое число или число с плавающей точкой. Вы можете объединить «строку, INT, массив, объект» и т.д. любых типов и все допустимые типы взяты из GetType

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

Вот это от меня, ошибки можно легко исправить: D

+3

Мое предложение: не используйте 'trigger_error'. Выбросьте исключения. Они намного гибче и легче справляются с этим. – ircmaxell

+0

исключение для чего-то такого же тривиального, как тип данных, кажется, похоже на то, что ... вы не можете действительно ожидать, что люди будут запускать каждую функцию в try/catch. – Ozzy

+0

Не отвечая на ваш вопрос здесь, но если вы создаете фреймворк, лучше создать единую функцию, которая выполняет проверки для вас, а ваши другие функции/классы относятся к этой единственной функции. – Duniyadnd

ответ

6

Это зависит.

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

Строго соблюдение примитивных типов часто очень неустойчиво и может быть проблемой для работы.

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

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

Вот как я подойду к нему. +1 для маршрута ООП! – Josh

0

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

0

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

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