Как разрешить «должен быть экземпляр строки, строка, заданная» до PHP 7?

Вот мой код:

function phpwtf(string $s) { echo "$s\n"; } phpwtf("Type hinting is da bomb"); 

Что приводит к этой ошибке:

Допустимая фатальная ошибка: аргумент 1, переданный phpwtf (), должен быть экземпляром строки, заданной строкой

Это больше, чем немного Оруэллиан, чтобы увидеть, как PHP распознает и отклоняет желаемый тип на одном дыхании. Есть пять огней, черт возьми.

Что эквивалентно типу намека на строки в PHP? Бонусное рассмотрение ответа, в котором точно объясняется, что здесь происходит.

До появления подсказок типа PHP 7 можно использовать только для создания типов объектов и массивов. Скалярные типы не относятся к типу. В этом случае ожидается ожидаемый объект string classа, но вы даете ему (скалярную) string . Сообщение об ошибке может быть забавным, но с самого начала оно не должно работать. Учитывая динамическую систему набора текста, это фактически делает какой-то извращенный смысл.

Вы можете только вручную «набирать подсказки» скалярными типами:

 function foo($string) { if (!is_string($string)) { trigger_error('No, you fool!'); return; } ... } 

Из руководства PHP :

Тип подсказки может быть только типа объекта и массива (начиная с PHP 5.1). Традиционный тип hinting с int и string не поддерживается.

Итак, у вас это есть. Сообщение об ошибке не очень полезно, но я даю вам это.

** 2017 Редактировать **

PHP7 представила больше объявлений типов данных функций, и вышеупомянутая ссылка была перенесена в аргументы Function: Введите объявления . С этой страницы:

Допустимые типы

  • Имя classа / интерфейса : Параметр должен быть экземпляром данного classа или имени интерфейса. (начиная с PHP 5.0.0)
  • self : Параметр должен быть экземпляром того же classа, что и тот, на котором определен метод. Это можно использовать только для методов classа и экземпляра. (начиная с PHP 5.0.0)
  • array : Параметр должен быть массивом. (поскольку PHP 5.1.0) вызываемый. Параметр должен быть допустимым. PHP 5.4.0
  • bool : Параметр должен быть логическим значением. (начиная с PHP 7.0.0)
  • float : Параметр должен быть числом с плавающей запятой. (начиная с PHP 7.0.0)
  • int : Параметр должен быть целым числом. (начиная с PHP 7.0.0)
  • string : Параметр должен быть строкой. (начиная с PHP 7.0.0)
  • iterable : Параметр должен быть либо массивом, либо экземпляром функции Traversable. (начиная с PHP 7.1.0)

Предупреждение

Псевдонимы для указанных выше скалярных типов не поддерживаются. Вместо этого они рассматриваются как имена classов или интерфейсов. Например, использование boolean как параметра или возвращаемого типа потребует аргумента или возвращаемого значения, которое является экземпляром classа или интерфейса boolean, а не типа bool:

  

Вышеприведенный пример выводит:

  Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of boolean, boolean given, called in - on line 1 and defined in -:1 

Последнее предупреждение действительно важно для понимания ошибки «Аргумент должен иметь тип string, string given»; поскольку в качестве типа аргумента допускаются только имена classов / интерфейсов, PHP пытается найти имя classа «строка», но не может найти его, потому что он является примитивным типом, поэтому с этой неудобной ошибкой терпит неудачу.

PHP позволяет «намекать», где вы предоставляете class для указания объекта. Согласно руководству PHP, «Type Hints могут быть только типа объекта и массива (начиная с PHP 5.1). Традиционный тип hinting с int и string не поддерживается». Ошибка путается из-за вашего выбора «string» – поместите «myClass» на свое место, и ошибка будет выглядеть по-разному: «Аргумент 1, переданный phpwtf (), должен быть экземпляром myClass,

Как уже говорили другие, тип hinting в настоящее время работает только для типов объектов. Но я думаю, что конкретная ошибка, которую вы вызвали, может быть связана с подготовкой следующего типа строк SplString .

Теоретически это ведет себя как строка, но поскольку это объект, он будет проходить проверку типа объекта. К сожалению, он еще не в PHP 5.3, может появиться в 5.4, поэтому не проверял это.

Начиная с PHP 7.0, объявления типа допускают скалярные типы, поэтому теперь доступны эти типы: self , array , callable , bool , float , int , string . Первые три были доступны в PHP 5, но последние четыре являются новыми в PHP 7. Если вы используете что-либо другое (например, integer или boolean ), которое будет интерпретироваться как имя classа.

Дополнительную информацию см. В руководстве по PHP .

Я получил эту ошибку при вызове функции из Laravel Controller в файл PHP.

Через пару часов я нашел проблему: я использовал $ this из статической функции.

(изначально опубликованный leepowers в его вопросе)

Сообщение об ошибке запутывается по одной большой причине:

Имена примитивных типов не зарезервированы в PHP

Ниже перечислены все допустимые объявления classов:

 class string { } class int { } class float { } class double { } 

Моя ошибка заключалась в том, что сообщение об ошибке ссылалось исключительно на примитивный тип строки – слово «экземпляр» должно было дать мне паузу. Пример, иллюстрирующий далее:

 class string { } $n = 1234; $s1 = (string)$n; $s2 = new string(); $a = array('no', 'yes'); printf("\$s1 - primitive string? %s - string instance? %s\n", $a[is_string($s1)], $a[is_a($s1, 'string')]); printf("\$s2 - primitive string? %s - string instance? %s\n", $a[is_string($s2)], $a[is_a($s2, 'string')]); 

Вывод:

$ s1 – примитивная строка? yes – строковый экземпляр? нет

$ s2 – примитивная строка? no – string instance? да

В PHP возможно, что string будет string за исключением случаев, когда она фактически является string . Как и на любом языке, использующем неявное преобразование типов, контекст – это все.

Я думаю, что typecasting на php на внутреннем блоке, String на PHP не является объектом, как я знаю:

  

Может быть, это не безопасно и красиво, но если вам нужно:

 class string { private $Text; public function __construct($value) { $this->Text = $value; } public function __toString() { return $this->Text; } } function Test123(string $s) { echo $s; } Test123(new string("Testing")); 
  • Почему некоторые люди предпочитают «T const &» над «const T &»?
  • unsigned short в java
  • Где в памяти мои переменные, хранящиеся в C?
  • Generics в C #, используя тип переменной как параметр
  • В чем разница между 'int?' и 'int' в C #?
  • Получение типа System.Type из частичного имени типа
  • Какой примитивный тип данных - time_t?
  • Почему я могу вводить функции псевдонима и использовать их без кастинга?
  • Каков тип строкового литерала в C ++?
  • Что такое декларации и деклараторы и как их типы интерпретируются стандартом?
  • Возвращать определенный тип внутри Haskell
  • Давайте будем гением компьютера.