为啥要一个句号,“。”而不是加号“+”,用于 PHP 中的字符串连接?

Posted

技术标签:

【中文标题】为啥要一个句号,“。”而不是加号“+”,用于 PHP 中的字符串连接?【英文标题】:Why a full stop, "." and not a plus symbol, "+", for string concatenation in PHP?为什么要一个句号,“。”而不是加号“+”,用于 PHP 中的字符串连接? 【发布时间】:2010-12-24 09:05:08 【问题描述】:

为什么 php 的设计者决定使用句号/句点/“.”作为字符串 连接运算符而不是更常见的加号“+”?

这样做有什么好处,或者有什么理由吗?还是他们只是喜欢? :o)

【问题讨论】:

由于给出了过多的优秀答案,我想将这个问题概括为包括 Perl。即为什么 Perl(以及后来的 PHP)的创建者选择使用 '.'超过 '+' 谢谢! 我认为一个更好的问题是 Perl 为什么特别选择 . - 他们想要一个不同的连接运算符的原因很清楚(许多语言都这样做),但是选择 .出于这个目的的所有事物似乎是一个谜。 & 或 ~ 或 .. 或 .或 + 或我键盘上的任何其他符号。作为一名前数学家和 C 程序员,+ 表示“具有标识的可交换、关联二元运算”或“指针算术”——两者都不像字符串连接。我不喜欢 PHP,但我找不到他们使用不同符号来表示不同事物的错误。我们在校对中使用的符号表示“将这些词组合在一起”会更酷,但没有人可以输入。 我在下面给出的答案与语言无关(这样当两个参数都是数字时,字符串连接不会与加法混淆)。因此,对于任何支持将数字自动强制转换为字符串的语言,它都是解决此问题的一种方法。 @Ken,那个符号的名字是什么(供参考)? 【参考方案1】:

PHP 的语法受 Perl 影响,. 是 Perl 中的字符串连接运算符。

在弱类型语言中,使用不同的字符串连接和数字加法运算符具有优势:您使用哪一个将影响语言将变量强制转换为哪种类型。

碰巧的是,Perl 6 将使用波浪号 ~ 而不是点 . 进行字符串连接,因为 . 将用于对象成员访问。所以现在看来​​ Perl 的设计者认为这是一个糟糕的选择。

也许,在 Perl 和 PHP 的早期非面向对象的日子里,这似乎是一个不错的选择。也许这两种语言的设计者从来没有想过它们会成为强大的面向对象语言。

至于 PHP 是否有朝一日会放弃 -> 的成员访问语法为 .,谁知道呢?

【讨论】:

并没有真正回答“为什么使用句号”这个问题。它只是推迟了答案。 joshcomley:这是一个有效的观点,所以我已经详细说明了。最初,我从表面上看是对“PHP 的设计者”的引用 “.”事实上的标准化由于方法操作员发布了采用“。”的日期。用于 Perl 中的连接,然后影响了 PHP。 perl 最初没有面向对象。正是因为现在大家都期待“。”表示 Perl 6 采用的新语法(从 perl 的角度来看)允许“.”的对象上的方法。用于方法并使用“~”进行连接。 并不是他们认为这是一个糟糕的选择,而是 .运算符已成为几乎所有语言中事实上的方法访问器。在当时,这是一个不错的选择。现在他们想将它用于不同的目的。 因为如果你使用 + 进行连接,就像在 javascript 中一样,你会因为类型松散的语言而遇到打字问题。词法解析器很难确定您是要进行加法还是连接。【参考方案2】:

最明显的原因可能是 PHP 从 Perl 继承了许多语法 - 而 Perl 使用点 (.) 进行字符串连接。

但是,我们可以更深入地研究它并找出为什么在 Perl 中实现它 - + 运算符最常用于数学方程 - 它仅用于变量类型可以定义方式的语言中的连接算子工作的地方(简单解释,例子是C#)

var intAddition = 1 + 2;
Console.WriteLine(intAddition); // Prints 3
var stringConcat = "1" + "2";
Console.WriteLine(stringConcat); // Prints "12"

^ 如您所见,+ 运算符在 C# 中用于连接和加法。


也许推理水平较低,是由于布尔代数 logic gates - + 在逻辑门中表示 OR,而 . 用作 AND 运算符 - 当它来到字符串连接。

有两个独立的运算符是有意义的,一个用于连接,一个用于加法 - 不幸的是,由于其他语言,这两个可能会混淆。

【讨论】:

嗨,我猜还有一个原因,但我不知道它是否正确。另一个原因可能是我们没有为变量指定数据类型,因为我们不知道它不能连接的 string 或 int,所以他们可能已经避免了这种情况。当然 var 数据类型是存在的,但即使我也猜到了这一点。你说的话? @丹尼尔·梅【参考方案3】:

我不是 PHP 专家,但是,您还能如何区分最后两行?

$first  = 100;
$second = 20;
$stringresult     = $first . $second; // "10020"
$arithmeticresult = $first + $second; // 120

【讨论】:

为了清楚起见 - $stringresult 返回“10020”,$arithmeticresult 返回 120 您使用了一些理智的运算符,例如 VB 使用的 &,或 D(显然还有 Perl6)使用的 ~,或 Lua 使用的 ..(这在 IMO 中仍然很奇怪,但更容易理解)。 @Pavel:好吧,如果您将原始发帖人的问题解释为美学问题之一,那么您可能有道理——我自己也更喜欢“&”,但我认为技术解释是在这种情况下确实被要求(他们认为在这两种情况下都使用“+”是可以的)。 @Pavel:为什么. 不是连接的“理智运算符”?仅仅因为您习惯于将. 用于对象成员并不能使其成为最合乎逻辑的运算符。 (PHP 选择-> 是相当不错的IMO。) -> 并不糟糕,但该运算符最常见的用途是在 C++ 中作为取消引用指向对象或结构的指针的简写。假设有一个struct 和一个成员x,并且你有一个指向该类型结构的指针p。与其使用(*p).x = 5;,不如使用p->x = 5;。鉴于 PHP 的类 C 血统,我认为这会重载语法,即使在 PHP 的上下文中没有使用该运算符。【参考方案4】:

逻辑上 + 用于数字。例如,dot 用于连接段落中的两个句子(字符串)。因此点用于连接字符串。所以我相信这是非常合乎逻辑的。这样比较好……

【讨论】:

您多久使用一次字符串连接来连接句子?另外,点是句子terminator,而不是句子separator,所以类比无论如何都会中断。 比喻不完美,11点拍。 为什么要在句子之间加一个点?我想你不应该包括一个:)【参考方案5】:

Douglas Crockford thinks that + for Concatenation is a Bad Idea:

JavaScript 也有一些设计错误,例如 + 的重载意味着两者 类型强制的加法和连接

【讨论】:

我同意道格的观点。一旦你习惯了语法,它就会更加清晰和不那么模棱两可——这两个目标都是值得的语法目标。 是的; Javascript + 经常破坏我的大脑,通常是因为它在我不想要的时候开始连接。 + for concatenation 是在 JS 中经常引起我注意的少数几件事之一【参考方案6】:

在 PHP 中使用点作为字符串连接运算符可能可以追溯到 Perl。请记住,PHP 曾经只是一堆 Perl 脚本。

另外,使用不同的字符串连接和加法运算符也很有意义,尤其是在弱类型语言中。 PHP 中的陷阱已经足够让你自食其果了,你不需要再添加一个了。

【讨论】:

【参考方案7】:

我也更喜欢使用句号而不是加号,因为我通常将 + 与数学方程式联系起来。

例如"this is a string " + 56 + 20

这对于编译器/解释器和开发人员来说都是非常混乱的。

但是,使用句号作为连接运算符的缺点是它只是屏幕上的一个点,有时您无法看到它是在字符串中还是在字符串之外。

【讨论】:

如果你不习惯的话会很困惑。在 Java 和 C# 中,这是常态。 是的,我知道。在 Java 中我不得不这样做:"this is a string " + (56 + 20) “习惯”与此无关。我写 C# 已经有几年了,在这之前的 Java 是从 1999 年左右开始的,这种模棱两可的废话仍然让我感到困惑。 (相比之下,Haskell 的字符串连接运算符花了我大约 10 秒的时间才弄清楚。)蹩脚语法的例子就像混蛋:每种语言都有一个,而且它们都很臭。【参考方案8】:

这并没有回答问题,只是想分享一些东西。

来自PHP Manual: String Operators,有人发布了这个我觉得很有趣的帖子。注意空间在输出中的作用。

摘录: 如果您尝试使用连接运算符添加数字,您的结果将是这些数字作为字符串的结果。

<?php

echo "thr"."ee";           //prints the string "three"
echo "twe" . "lve";        //prints the string "twelve"
echo 1 . 2;                //prints the string "12"
echo 1.2;                  //prints the number 1.2
echo 1+2;                  //prints the number 3

?>

【讨论】:

【参考方案9】:

+ 应始终定义为可交换运算(即 A+B = B+A)。在字符串连接的情况下,情况并非如此(“foo”+“bar”!=“bar”+“foo”)。因此,+ 不是用于连接操作的好运算符。语言作者在使用 . 时是否考虑到了这一点(这与乘法运算符很接近,交换律不需要成立)还有待观察,但这是一个不错的决定。

【讨论】:

即使在数学中,加法也不总是可交换的;例如不适用于序数。 @Pavel:嗯?我从未听说过有人尝试添加序数。 First + Second 如何计算?答案是第三吗?如果是这样,为什么 Second + First 不等于 Third?【参考方案10】:

这里有一点历史背景。

PHP 语言最初是一组 Perl 脚本。 因此,PHP 的大部分语法来自 Perl。

Perl 以及 PHP 的扩展,具有无类型变量。

     "5"  ==   5
"5" + 5   ==  10
"5" . 5   ==  55
为了能够区分加法和串联,它们必须是两个不同的运算符。 Perl 从 C -&gt; 复制了方法访问运算符。 这是许多更现代的编程语言开始使用. 进行方法访问之前。 连接是比较常见的操作之一,应该使用较少的字符。根据霍夫曼编码。 . 是少数可用于此用途的字符之一。唯一可以使用的另一个是 ~,这可能就是现在 Perl 6 连接运算符的原因。

【讨论】:

不知道你从哪里得到 Perl 主页,但在 12 年的 PHP 开发中,我从未听说过它叫这个:“个人主页工具”可能 哦,它目前代表“PHP超文本预处理器” Grr 在“无类型变量”。过于简单化了。 Perl 主页工具是对的。在***文章的德语版本中,第一句就提到了:de.wikipedia.org/wiki/PHP 我确信我读到它被称为 Perl 主页,在它发布之前的某个时间之前。不过,那可能只是我的想法在欺骗我。无论如何,我从列表中删除了该项目,因为没有它,这篇文章似乎更好。【参考方案11】:

虽然这不是历史原因,但它可能会向您展示为什么在 PHP 中使用单独的运算符进行加法和连接是件好事。

原因是我们在 JavaScript 中看到的。我们也使用+ 字符进行连接和加法。在 PHP 中,我们有一个单独的运算符用于这两个运算符,这对于同时存在隐式类型转换的动态类型语言很重要。

在 PHP 中

echo  5  + 1; //6
echo  5  . 1; //51
echo "5" + 1; //6
echo "5" . 1; //51

这对任何人来说都不足为奇,因为我们总是明确说明是否要添加或连接这两个变量。或者换句话说,如果我们将它们视为数字或字符串。

在 JavaScript 中

console.log( 5  +  1);  //6
console.log("5" +  1);  //51
console.log( 5  + "1"); //51
console.log("5" + "1"); //51

如果不知道隐式类型转换是如何在幕后发生的,在许多情况下(尤其是复杂的情况下)可能会发生令人惊讶的结果,因为我们不知道结果会是什么,因为它没有明确说明.

在 Python 中

Python 也使用+ 运算符进行连接和加法,但它不会让隐式类型转换发生。您必须明确标记类型转换。

print  5  + 1 //6
print "5" + 1 //TypeError: cannot concatenate 'str' and 'int' objects

我们必须进行类型转换才能使其工作:a + int(b)

总之

如果我们仔细想想,我们可以看到在 PHP 中发生的事情与在 Python 中看到的几乎相同,但是我们没有显式地标记类型转换,而是用运算符标记了我们如何根据类型查看变量。

【讨论】:

【参考方案12】:

我猜是这样你可以将数字与字符串连接起来?

$i=100;
$str="hello";
$str2 = $str.$i

由于您没有声明变量类型,使用 + 可能会给出 100 而不是“hello100”的结果。

【讨论】:

以上是关于为啥要一个句号,“。”而不是加号“+”,用于 PHP 中的字符串连接?的主要内容,如果未能解决你的问题,请参考以下文章

TortoiseGit添加文件还没有提交为啥显示对号不是加号?

抛开价格不谈,为啥要选择 Google Cloud Bigtable 而不是 Google Cloud Datastore?

为啥我们需要 HTTP 而不是 SSH?

Jquery的序列化方法为啥要把空格替换成加号

为啥 CORS 只用于 Javascript 而不是 PHP? [复制]

使用明确编号的重复而不是问号、星号和加号