Как предотвратить использование неправильного типа в PHP?
PHP, как мы все знаем, очень слабо типизирован. Язык не требует указания какого-либо типа для параметров функции или переменных класса. Это может быть мощной особенностью.
Иногда, однако, это может сделать отладку вашего сценария болезненным опытом. Например, передача одного типа объекта в метод, который ожидает другой тип объекта, может привести к появлению сообщений об ошибках, жалующихся на то, что определенная переменная/метод не существует для передаваемого объекта. Эти ситуации таковы: в основном раздражения. Более тяжелые проблемы возникают, когда вы инициализируете один объект с объектом неправильного класса, и этот "неправильный объект" не будет использоваться до тех пор, пока позже не будет выполнен сценарий. В этом случае вы получите ошибку намного позже, чем при передаче исходного аргумента.
Вместо того, чтобы жаловаться, что то, что я передал, не имеет определенного метода или переменной, или ждать, пока намного позже при выполнении скрипта будет использован мой переданный Объект, я бы с большим удовольствием есть сообщение об ошибке, в том самом месте, где я указываю объект неправильного типа, жалуясь на неправильный или несовместимый тип объекта.
Как вы справляетесь с этими ситуациями в своем коде? Как вы обнаруживаете несовместимые типы? Как я могу ввести некоторую проверку типов в мои сценарии, чтобы я мог получить более понятные сообщения об ошибках?
Кроме того, как вы можете сделать все это, учитывая наследование в Php? Рассмотрим:
<?php
class InterfaceClass
{
#...
}
class UsesInterfaceClass
{
function SetObject(&$obj)
{
// What do I put here to make sure that $obj either
// is of type InterfaceObject or inherits from it
}
}
?>
Тогда пользователь этот код реализует интерфейс со своим собственным конкретным классом:
<?php
class ConcreteClass extends InterfaceClass
{
}
?>
Я хочу, чтобы экземпляры ConcreteClass и все будущие, неизвестные определяемые пользователем объекты также были приемлемы для SetObject. Как бы вы сделали это допустимым при проверке правильного типа?7 ответов:
На самом деле для классов вы можете предоставить подсказку типа в PHP (5+).
<?php class UsesBaseClass { function SetObject(InterfaceObject $obj) { } } ?>
Это также будет правильно работать с наследованием, как вы и ожидали.
В качестве отступления не добавляйте слово "объект" в имена классов...
В дополнение к ответу Эрана Гальперина можно также использовать тип hinting, чтобы заставить параметры быть массивами, а не просто объектами определенного класса.
<?php class MyCoolClass { public function passMeAnArray(array $array = array()) { // do something with the array } } ?>
Как вы можете видеть, вы можете ввести подсказку, что метод
::passMeAnArray()
ожидаетarray
, а также предоставить значение по умолчанию в случае, если метод вызывается без каких-либо параметров.
Для примитивных типов можно также использовать функции is_*:
public function Add($a, $b) { if (!is_int($a) || !is_int($b)) throw new InvalidArgumentException(); return $a + $b; }
Видите ли, существует несколько ответов о типе намеков . это техническое решение. Но вы также должны убедиться, что весь дизайн является разумным и интуитивно понятным. Это сделает типовые проблемы и ошибки более редкими.
Помните, что даже эти ошибки типа будут выброшены во время выполнения. Убедитесь, что у вас есть тесты для кода.
Даже в том случае, когда вы описываете, ваш скрипт будет аварийно завершаться, жалуясь на отсутствие метода / атрибута X на объекте Y, так что вы будете знать, откуда это происходит.
В любом случае, я думаю, что всегда пытаться помешать выросшим программистам передать неправильный объект методу-это не лучшая инвестиция времени : вы могли бы потратить его на документирование и обучение вместо этого.Утиный набор текста и внимательные коллеги - это то, что вам нужно, а не дополнительные проверки, которые сделают ваше приложение более удобным. жесткий.
Но это может быть точка зрения питониста...
@ответ Эрана Гальперина является предпочтительным методом для обеспечения правильного типа используемого объекта.
Также стоит отметить операторinstanceOf - это полезно, когда вы хотите проверить, что объект является одним из нескольких типов.