Как предотвратить использование неправильного типа в 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 3

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 - это полезно, когда вы хотите проверить, что объект является одним из нескольких типов.

Вы можете установить параметр error_reporting ini в вашем php.ini-файл или используйте функцию error_reporting, чтобы установить его во время выполнения