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

Author: Paweł Hajdan, 2008-09-26

7 answers

На самом деле для классов вы можете указать подсказку типа в PHP (5+).

 <?php
 class UsesBaseClass
 {
      function SetObject(InterfaceObject $obj) 
      {
      }
 }
 ?>

Это также будет корректно работать с наследованием, как вы и ожидали.

В качестве отступления, не добавляйте слово "объект" в имена ваших классов...

 11
Author: Eran Galperin, 2008-09-26 02:00:01

В дополнение к ответу Эрана Гальперина вы также можете использовать подсказку типа, чтобы заставить параметры быть массивами, а не просто объектами определенного класса.

<?php
class MyCoolClass {
   public function passMeAnArray(array $array = array()) {
      // do something with the array  
   }  
 }  
 ?>

Как вы можете видеть, вы можете ввести подсказку о том, что метод ::passMeAnArray() ожидает array, а также указать значение по умолчанию в случае, если метод вызывается без каких-либо параметров.

 4
Author: phatduckk, 2008-09-26 02:05:43

Для примитивных типов вы также можете использовать функции is_*:

public function Add($a, $b)
{
  if (!is_int($a) || !is_int($b))
    throw new InvalidArgumentException();
  return $a + $b;
}
 2
Author: Andrei Rînea, 2008-10-04 12:16:50

Видите ли, существует несколько ответов о намеках типа. Это техническое решение. Но вы также должны убедиться, что весь дизайн продуман и интуитивно понятен. Это сделает проблемы с типом и ошибки более редкими.

Помните, что даже эти ошибки типа будут вызваны во время выполнения . Убедитесь, что у вас есть тесты для кода.

 1
Author: Paweł Hajdan, 2008-09-26 07:08:24

Даже в случае, который вы описываете, ваш сценарий завершится сбоем, жалуясь на отсутствие метода/атрибута X для объекта Y, чтобы вы знали, откуда это взялось.

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

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

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

 1
Author: e-satis, 2008-09-27 11:48:55

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

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

 1
Author: leek, 2017-05-23 10:32:50

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

 0
Author: Ahmad, 2008-09-26 03:19:28