Как мне предотвратить использование неправильного типа в PHP?

StackOverflow https://stackoverflow.com/questions/137336

  •  02-07-2019
  •  | 
  •  

Вопрос

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.Как бы вы сделали это допустимым при проверке правильного типа?

Это было полезно?

Решение

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

В любом случае, я думаю, что всегда пытаться помешать взрослым программистам передавать неправильный объект методу - не лучшая инвестиция времени :вместо этого вы могли бы потратить их на документирование и обучение.

Аккуратный ввод текста и внимательные коллеги - вот что вам нужно, а не дополнительные проверки, которые сделают ваше приложение более жестким.

Но это может быть точка зрения питониста...

@Эран ГальперинОтвет - это предпочтительный метод для обеспечения того, чтобы используемый вами объект имел правильный тип.

Также стоит отметить, что Экземпляр оператор - это полезно, когда вы хотите проверить, является ли объект одним из нескольких типов.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top