Как мне предотвратить использование неправильного типа в 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 answers
На самом деле для классов вы можете указать подсказку типа в PHP (5+).
<?php
class UsesBaseClass
{
function SetObject(InterfaceObject $obj)
{
}
}
?>
Это также будет корректно работать с наследованием, как вы и ожидали.
В качестве отступления, не добавляйте слово "объект" в имена ваших классов...
В дополнение к ответу Эрана Гальперина вы также можете использовать подсказку типа, чтобы заставить параметры быть массивами, а не просто объектами определенного класса.
<?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 - он полезен, когда вы хотите проверить, является ли объект одним из нескольких типов.
Вы можете установить параметр error_reporting ini в файле php.ini или использовать функцию error_reporting, чтобы установить его во время выполнения