Ответ 1
Вы можете только вручную сканировать типы "тип подсказки":
function foo($string) {
if (!is_string($string)) {
trigger_error('No, you fool!');
return;
}
...
}
Вот мой код:
function phpwtf(string $s) {
echo "$s\n";
}
phpwtf("Type hinting is da bomb");
Что приводит к этой ошибке:
Исправляемая фатальная ошибка: Аргумент 1, передаваемый в phpwtf(), должен быть экземпляром string, string
Это больше, чем маленький оруэлловский взгляд на то, как PHP распознает и отклоняет желаемый тип на одном дыхании. Есть пять огней, черт побери.
Что эквивалентно типу хинтинга для строк в PHP? Бонус за рассмотрение ответа, который точно объясняет, что здесь происходит.
Вы можете только вручную сканировать типы "тип подсказки":
function foo($string) {
if (!is_string($string)) {
trigger_error('No, you fool!');
return;
}
...
}
Тип Подсказки могут быть только типа объекта и массива (начиная с PHP 5.1). Подсказка традиционного типа с использованием int и string не поддерживается.
Итак, у вас есть это. Сообщение об ошибке не очень полезно, но я дам вам это.
В PHP7 появилось больше объявлений типов данных функций, и вышеупомянутая ссылка была перемещена в Аргументы функций: Объявления типов. С этой страницы:
Допустимые типы
- Имя класса/интерфейса: параметр должен быть экземпляром данного класса или имени интерфейса. (начиная с PHP 5.0.0)
- self: параметр должен быть экземпляром того же класса, что и класс, для которого определен метод. Это можно использовать только для методов класса и экземпляра. (начиная с PHP 5.0.0)
- массив: параметр должен быть массивом. (начиная с PHP 5.1.0) callable Параметр должен быть допустимым вызываемым. PHP 5.4.0
- bool: параметр должен быть логическим значением. (начиная с PHP 7.0.0)
- float: параметр должен быть числом с плавающей запятой. (начиная с PHP 7.0.0)
- int: Параметр должен быть целым числом. (начиная с PHP 7.0.0)
- строка: параметр должен быть строкой. (начиная с PHP 7.0.0)
- iterable: параметр должен быть либо массивом, либо экземпляром Traversable. (начиная с PHP 7.1.0)
Предупреждение
Псевдонимы для указанных выше скалярных типов не поддерживаются. Вместо этого они рассматриваются как имена классов или интерфейсов. Например, для использования логического значения в качестве параметра или возвращаемого типа потребуется аргумент или возвращаемое значение, которое является экземпляром класса или интерфейса логического типа, а не типа bool:
<?php function test(boolean $param) {} test(true); ?>
Приведенный выше пример выведет:
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 string"; поскольку в качестве типа аргумента в основном разрешены только имена классов/интерфейсов, PHP пытается найти имя класса "string", но не может найти ни одного, потому что это примитивный тип, поэтому происходит сбой с этой неловкой ошибкой.
PHP позволяет "намекать", где вы предоставляете класс для указания объекта. Согласно руководству 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
), которое будет интерпретироваться как имя класса.
Я получил эту ошибку при вызове функции из Laravel Controller в файл PHP.
Через пару часов я обнаружил проблему: я использовал $this из статической функции.
(первоначально опубликовано leepowers в его вопросе)
Сообщение об ошибке сбивает с толку по одной большой причине:
Имена примитивных типов не зарезервированы в PHP
Ниже приведены все допустимые объявления классов:
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 - примитивная строка? да - строковый экземпляр? нет
$ s2 - примитивная строка? нет - экземпляр строки? да
В PHP string
может быть string
кроме случаев, когда она действительно является string
. Как и в любом языке, который использует неявное преобразование типов, контекст - это все.
Есть ли кто-то, кто действительно может помочь мне исправить это? Какой файл мне нужно исправить? Я в отчаянии!
Спасибо!
Я думаю, что typecasting на php на внутреннем блоке, String на PHP не является объектом, как я знаю:
<?php
function phpwtf($s) {
$s = (string) $s;
echo "$s\n";
}
phpwtf("Type hinting is da bomb");
Возможно, это не безопасно и красиво, но если вы должны:
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"));