Почему в PHP нужен тип намека?
У меня возникают проблемы, когда я думаю о важности подсказок по типу в PHP.
Очевидно, "подсказка типа" в PHP может быть определена следующим образом:
"Тип подсказки" заставляет вас пропускать только объекты определенного типа. Это предотвращает передачу несовместимых значений и создает стандартно, если вы работаете с командой и т.д.
Таким образом, подсказка типа на самом базовом уровне, не требуется, чтобы фактически заставить код работать?
У меня есть следующий код, чтобы попытаться понять, что происходит...
Index.php
<?php
include 'Song.php';
$song_object = new Song;
$song_object->title = "Beat it!";
$song_object->lyrics = "It does not matter who wrong or right... just beat it!";
function sing(Song $song)
{
echo "Singing the song called " . $song->title;
echo "<p>" . $song->lyrics . "</p>";
}
sing($song_object);
Song.php
<?php
class Song
{
public $title;
public $lyrics;
}
код выполняет свою функцию с небольшой подсказкой типа в функции sing() или без нее;
![enter image description here]()
Итак, это наводит меня на мысль, что хинтинг типов - это просто соглашение о кодировании, позволяющее убедиться, что используются только определенные классы и которые не нужны для создания функционального кода, верно?
Подсказка типа, как следует из приведенной выше цитаты, предназначена для создания стандарта, если вы работаете с командой.
Я что-то здесь упускаю?
Ответы
Ответ 1
Подсказка по типу не обязательна, но она позволяет вам обнаруживать определенные типы ошибок. Например, у вас может быть функция или метод, который требует целое число. PHP с радостью преобразует "строки с числовым отображением" в целые числа, и это может привести к затруднению отладки поведения. Если вы указываете в своем коде, что вам конкретно нужно целое число, это может предотвратить подобные ошибки в первую очередь. Многие программисты считают защиту своего кода таким способом лучшей практикой.
В качестве конкретного примера этого в действии, давайте посмотрим на обновленную версию вашего файла index.php
:
index.php
<?php
include 'Song.php';
include 'Test.php';
$song_object = new Song;
$test_object = new Test;
$song_object->title = "Beat it!";
$song_object->lyrics = "It does not matter who wrong or right... just beat it!";
$test_object->title = "Test it!";
$test_object->lyrics = "It does not matter who wrong or right... just test it!";
function sing(Song $song)
{
echo "Singing the song called " . $song->title;
echo "<p>" . $song->lyrics . "</p>";
}
sing($song_object);
sing($test_object);
А также новый файл Test.php
, который я добавил:
test.php
<?php
class Test
{
public $title;
public $lyrics;
}
Когда я запускаю index.php
сейчас, я получаю следующую ошибку:
Выход:
Singing the song called Beat it!<p>It does not matter who wrong or right...
just beat it!</p>PHP Catchable fatal error: Argument 1 passed to sing() must
be an instance of Song, instance of Test given, called in test/index.php on
line 22 and defined in test/index.php on line 15
Catchable fatal error: Argument 1 passed to sing() must be an instance of
Song, instance of Test given, called in test/index.php on line 22 and defined
in test/index.php on line 15
Это PHP, сообщающий мне, что я пытался использовать неправильный тип класса, когда вызывал функцию sing()
.
Ответ 2
Тип подсказок - это естественный процесс. Поначалу это может показаться дополнительной работой, но это очень полезно по мере роста вашего проекта на PHP. Это обеспечивает лучшую читаемость и облегчает применение контроля ошибок и строгих правил программирования.
Первоначально вы должны реализовать ‘контракт, где контракт - это интерфейс php, который может блокировать константы и ключевые открытые методы и их аргументы, как таковые:
interface SongInterface {
//...
}
class Song implements SongInterface
{
public $title;
public $lyrics;
//...
}
Затем перейдите к фактической части выполнения:
$song = (object) new Song;
$song->title = (string) "Beat it!";
$song->lyrics = (string) "It does not matter who wrong or right... just beat it!";
function sing(SongInterface $song): string
{
$html = (string) "Singing the song called " . $song->title
. "<p>" . $song->lyrics . "</p>";
return htmlentities($html, ENT_QUOTES, 'utf-8');
}
echo sing($song);
Используя интерфейс, вы только определяете функции и затем реализуете их в классе песни. Таким образом, вы всегда можете добавить другой класс песни (с новыми функциями и изменениями), не нарушая приложения. Проверьте oop интерфейсы: http://php.net/manual/en/language.oop5.interfaces.php
Начиная с php7, вы также можете определить тип возвращаемого значения функции. https://wiki.php.net/rfc/return_types
Ответ 3
Ваш код будет работать нормально с подсказкой типа или без него.
Подсказка типа просто заставляет вас передать что-то определенного типа этой функции/методу.
например.
function displayNames($names)
{
foreach ($names as $n) {
echo $n;
}
}
Эта функция будет работать нормально, если пользователь будет передан в массиве следующим образом.
displayNames(array('Tom', 'John', 'Frank'));
Тем не менее, PHP позволит пользователю передавать что-либо, например строку, int, bool, object и т.д. Ни один из них не будет действовать так, как вы ожидаете, когда он достигнет foreach
внутри функции displayNames
.
Добавление подсказки типа array
приводит к тому, что эта функция ожидает, что $names
будет массивом.
function displayNames(array $names)
{
// We now KNOW that $names is an array.
foreach ($names as $n) {
echo $n;
}
}
Массив - простой пример, но, как вы сказали, вы также можете вводить объекты подсказки. В этом случае разработчик может только принять экземпляр соединения с базой данных в методе doSqlQuery()
, например.
Вы должны знать
PHP-версии ниже 7 ТОЛЬКО разрешают типы подсказок для классов (включая интерфейсы) и массивов. Чтобы набрать подсказку для string
, int
, bool
и т.д., Вам нужно использовать PHP 7.
Ответ 4
Тип намека похож на имя, которое говорит больше намека. Это позволяет разработчикам видеть, какие классы могут передаваться в качестве аргументов, и не позволяет им передавать неправильные аргументы. Это особенно полезно, если вы работаете над одним и тем же проектом с более чем одним человеком и/или код предназначен для открытого исходного кода.
В php7 тип hinting для строки, int, (смешанный) и массив добавлены, поэтому вам не нужны только классы, но также могут использовать стандартные типы php
Ответ 5
Это необходимо? Нет
Это лучшая практика? Да
Какая версия PHP поддерживает это? PHP 5.6 только для классов, PHP 7+ также позволяет указывать тип для примитивов (int, string, boolean и т.д.).
Чем это полезно?
- Получение подсказок от IDE (зависит от IDE).
- Стандартизация стиля кодирования в командных проектах.
- Сокращение логических ошибок.
- Переход от PHP, являющегося языком с типом с потерями, к типу PHP со строгой типизацией, но оставляющим возможность использовать функции с потерями или сильно от рук разработчиков.
Ответ 6
делает ваш код более стабильным, особенно если проект большой
код более читабельный, понятный и профессиональный
дает автозаполнение в IDE
снифферы кода, такие как phpstan, могут найти, где вы вызываете метод
с неверным параметром
Вы можете легче понять код и методы работы, когда приходите в новый проект
без подсказки типа, если вы вызовете свой метод с неправильным объектом, ничего не произойдет, потому что $song-> title и $song-> текст вернет ноль, с исключением подсказки типа