PHP Manual
/
文体和惯例

撇号和引号

22. 08. 2019

Obsah článku

你可以使用引号或撇号来给字符串定界。我个人喜欢只用**括号**,除非它是一个特殊的换行符或制表符。

这有很多原因,让我们建设性地看一下。

不使用引号的主要原因是安全和对数据类型的不适当处理。

在字符串中使用HTML标签

如果我们需要在一个字符串中返回HTML代码,而我们用引号来包裹这个字符串,那么我们就必须很笨拙地进行转义。

return "<a href=\"{$link}\">{$text}</a>";

或者以更可读的方式做同样的事情,保留引号而不转义。

return '<a href="' . $link . '">' . $text . '</a>';

绳子与变量的视觉距离较长

没有什么比把变量直接粘在一个字符串上更糟糕的了,你无法快速直观地分辨什么是变量,什么是字符串。

$url = "{$baseImageUrl}/{$dirName}/{$basename}.{$ext}";

这种符号对功能没有负面影响,只是将字符串中的各个变量和固定字符堆叠在一起,距离太近,降低了可读性。

让我们再试一次,让它更有可读性。

$url = $baseImageUrl . '/' . $dirName . '/' . $basename . '.' . $ext;

我看到的主要优点是变量周围很干净,名称中没有多余的字符碍事。

此外,它将更容易包装,并且在字符串中没有包装字符;)

$url = $baseImageUrl
. '/' . $dirName
. '/' . $basename . '.' . $ext;

不可能在引号内调用一个函数

但变量可以,这就是为什么 "东西 "被附加在字符串外面(特别是函数),而变量被写回里面。而有时,程序员甚至会在字符串后追加变量。简而言之,混乱中的混乱。

为什么我们不能统一做事情?

另一种数据类型对字符串的不恰当映射

考虑下面的函数调用。

echo getFullName("{$user->name}");
function getFullName(string $name): string
{
// ... 实施 ...
}

可以在引号中插入变量,这将使它们被改写成一个字符串。但是,如果该变量在字符串本身中,并且数据类型与字符串不同,那么关于原始数据类型的信息可能会被破坏。例如,如果$user->name构造返回falsenull,我们就无法知道这是一个错误。

一个应用程序应该始终识别错误条件并正确地失败,而不是忽略它。正确的错误报告会导致未来更好的调试。

偶尔,你可能会遇到覆盖的情况,特别是因为一个函数需要一个特定的数据类型。

trim("{$returnText}");

在这种情况下,我更倾向于把它写下来。

trim ((string) $returnText);

这并不那么 "神奇",甚至对不太熟练的用户来说,变量的情况也很明显。

从数据库中删除值 "null"。

假设我们正在从数据库中检索一个酒店的名称。

return "{$row->hotel->name}";

但是如果这个名字不存在,是 "空 "的呢?通过使用引号,我们创造了一个潜在的难以检测的错误,因为它将被重写为一个空字符串。然而,我们希望返回一个真正的 "空"。如果记录不存在,或者存在但却是空的,这就有区别了。

因此,正确的做法是什么都不指定。

return $row->hotel->name;

该函数是否要求返回特定的数据类型,它对此是否严格?如果我们不能满足规范,我们应该抛出一个异常。

function getHotelName(int $hotelId): string
{
// 执行
if ($row->hotel->name === null) {
throw new \Exception('酒店名称不存在。');
}
return $row->hotel->name;
}

字符和数据类型的编码不一致

遇到类似这样的结构是很常见的。

echo "{$returnCode}" . self::CRLF;

这句话最好写成。

echo $returnCode . "\n";

在这种情况下,在变量周围使用引号是不必要的,只会使它更难读,因为它是额外的不必要的字符。同时,"CRLF "类型的换行并不现代,最好只使用 "UTF-8 "编码中的 "n"。

正确地说,我们仍然可以为代码验证数据类型。例如,它是一个数字,并可能返回一个替换。这可以通过ternary operator来完成。

echo (is_int($returnCode) ? $returnCode : '?') . "\n";

注意:使用is_int()函数表明应用程序设计不当,因为我们不应该发生不知道一个变量的数据类型。

用撇号包住输出的字符串

通常有必要在异常文本中用引号或撇号括住变量的输出字符串。然而,这不必要地为两种类型的字符串定界符创造 "回报",如果字符串以相同的字符开始和结束,在多个字符串的情况下,如果里面出现一撇一捺,就不可能迅速明确地确定字符串的开始和结束位置。

throw new \Exception(__METHOD__ . ": Unsupported data type '{$fileType}'");

我个人解决这个问题的方法是用不同的字符类型包围它(方括号对我来说很有效),这样就可以优雅地看到字符串的开始和结束。

throw new \Exception(__METHOD__ . ': 不支持的数据类型[' . $fileType . ']');

或者。

throw new \Exception("Status '{$status}' is invalid");

可以换成。

throw new \Exception('状况[' . $status . '] 是无效的');

按行进行解析

引号是有用的,例如,用于按新行进行解析。

foreach(explode("\n", $text) as $line) {
// 执行
}

它们是专门为此目的而创造的。

但是,如果你需要处理更复杂的文件(如编程语言的源代码或HTML页面),我建议使用Tokenizer正则表达式

不要将两种包围的方法结合起来

如果出于某种原因,你还是要使用引号,至少要在整个过程中保持一致。

这是一个具有威慑力的案件。

throw new \Exception("URL上的图片不存在。响应大小。" . strlen($result) . ')');

其中,字符串的开头由引号划定,结尾由撇号划定。

这个缺陷在使用自动格式化工具(如Code Sniffer)时特别容易发生,这些工具试图统一惯例,但并不总是成功。

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
4.
Status:
All systems normal.
2024