我无法解决PHP中类型提示的重要性。
显然,PHP中的“类型提示”可以定义如下:
“类型提示”强制您仅传递特定类型的对象。 这可以防止您传递不兼容的值,并创建一个 如果您正在与团队合作等标准。
因此,在最基本的级别上进行类型提示,不需要实际使代码有效吗?
我有以下代码试图了解发生了什么......
的index.php
<?php
include 'Song.php';
$song_object = new Song;
$song_object->title = "Beat it!";
$song_object->lyrics = "It doesn't matter who's 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();
中使用或不使用小类提示进行处理因此,这让我相信类型提示只是一种编码约定,以确保只使用某些类而不需要生成功能代码,这是正确的吗?
如上所述,类型提示可以创建标准,如果您正在与团队合作。
我在这里错过了什么吗?
答案 0 :(得分:22)
类型提示不是必需的,但它可以让您捕获某些类型的错误。例如,您可能有一个需要整数的函数或方法。 PHP将happily convert&#34;数字看字符串&#34;整数,这可能导致难以调试的行为。如果在代码中指定特别需要一个整数,则可以首先防止出现这类错误。许多程序员都认为以这种方式保护他们的代码是最佳实践。
作为此操作的具体示例,让我们查看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 doesn't matter who's wrong or right... just beat it!";
$test_object->title = "Test it!";
$test_object->lyrics = "It doesn't matter who's 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 doesn't matter who's 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()
函数时尝试使用错误类型的类。
答案 1 :(得分:5)
类型提示是一个自然过程。起初看起来似乎是额外的工作,但随着您的项目在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 doesn't matter who's 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
答案 2 :(得分:3)
您的代码 可以使用或不使用类型提示运行。
类型提示只会强制您将特定类型的内容传递给该函数/方法。
E.g。
function displayNames($names)
{
foreach ($names as $n) {
echo $n;
}
}
假设用户按如下方式传入数组,此函数可以正常工作。
displayNames(array('Tom', 'John', 'Frank'));
然而,PHP将允许用户传递任何内容,例如字符串,int,bool,对象等。当它到达foreach
displayNames
内部时,这些都不会表现出您的预期。 1}}功能。
添加array
类型提示强制执行此函数期望$names
为数组的事实。
function displayNames(array $names)
{
// We now KNOW that $names is an array.
foreach ($names as $n) {
echo $n;
}
}
数组是一个简单的示例,但正如您所说,您也可以键入提示对象。在这种情况下,它允许开发人员仅以doSqlQuery()
方法接受数据库连接的实例。
你应该知道
低于7的PHP版本仅允许类(包括接口)和数组的类型提示。要为string
,int
,bool
等输入提示,您需要使用PHP 7。
答案 3 :(得分:1)
类型提示就像名称更多的提示。它允许开发人员查看哪些类可以作为参数传递,并防止它们传递错误的参数。如果你不仅仅是一个人在同一个项目上工作和/或代码是用于开源的话,那就特别有帮助。
在php7类型提示中添加了字符串,int,(mixed)和数组,所以你不需要只有类,但也可以使用标准的php类型
答案 4 :(得分:0)
使您的代码更稳定,尤其是在项目较大的情况下
该代码更具可读性,更简洁,更专业
让您在IDE中自动完成
代码嗅探器可以在调用方法的地方找到 参数错误
您可以更轻松地理解代码以及进入新项目时方法的工作方式
没有类型提示,如果您将使用错误的对象调用方法,则不会发生任何事情,因为 $ song-> title 和 $ song-> lyrics 将返回null ,并抛出类型提示异常