在许多语言中,您都是从头开始构建 Web 框架(即从 unix 套接字开始)并分层抽象。如果我想用 OCaml 或 C 从头构建 Web 框架,我首先会构建一个监听端口 80 的套接字服务器。
我突然想到,PHP 可能像任何其他高级语言一样,以某种方式包装了 unix 套接字。现在我知道 PHP 的设计从来就不是这样的。但是,我不明白为什么它从来没有以这种方式使用过。同样,PHP 解释器也从来没有像 Python 解释器那样以这种方式使用。
例如,当我从头构建一个 Python Web 服务器并部署它时,我会执行以下操作:在某个端口(比如 8000)上附加一个 unix 套接字,像这样守护进程化我的脚本python server.py 8000
,并在端口 80 上使用 nginx 反向代理并转发到端口 8000 上的内部本地服务器。我从未见过在 PHP 中完成此操作,尽管这是可能的。
我承认除了使用独立的解释器之外,在 Python 中你还有其他选择(例如 tornado、uwsgi 等)。然而,两种方式都可以。
我的问题是,PHP 语言、解释器或社区的哪些方面阻碍了 PHP Web 框架从 unix 套接字调用开始构建、在本地端口上守护进程以及反向代理而不是使用 cgi/fastcgi 包装器?
答案1
一句话,历史。这是对 15 多年历史的简要总结(如果你真的感兴趣,可以在网上找到更多信息):
首先,虽然 PHP 具有编程语言的所有功能,但情况并非总是如此。它开始作为“超文本预处理器”,其目的是嵌入 HTML 页面并由 CGI 程序或 Web 服务器本身解析。它旨在运行经过现有的 Web 服务器,而不是是网络服务器。在早期版本中,它是一个非常简单的语言(有些人会说它现在仍然是)。
PHP 的历史可以追溯到 20 世纪 90 年代末,当时 Web 服务器运行动态内容的唯一方式是通过电脑生成图像处理。CGI 最大的问题是它相当慢,因为它会为每个请求创建一个新进程。这在早期并不是什么大问题,但当互联网泡沫爆发时,它就成了一个问题。PHP 变得非常流行,以至于嵌入作为可加载模块放入 Apache,它比 CGI 具有更好的性能并提供了一些其他好处。
长期以来,PHP 只能以上述两种方式之一运行,但由于它已成为占据绝大多数市场份额的语言,因此没人真正关心它。虽然最终有些人想使用 Apache 以外的服务器,而且有一段时间 CGI 是唯一的方法,直到快速CGI服务器 API 称为php-fpm(FastCGI 进程管理器)最终被贡献到 PHP 中。与 CGI 不同,FastCGI 会保持一个进程池始终运行并随时准备处理传入的请求。
2000 年代出现了其他语言,它们的工作方式不同。例如,Ruby 中的应用程序库包含在所谓的 gem 中,只需将一些现有的 gem 与业务逻辑粘合在一起,就可以轻松创建一个程序。Rack 是一个 Ruby gem,它提供了用于构建 Web 服务器的 Ruby API,mongrel、unicorn、thin 等服务器以及 Rails 和 Sinatra 等框架都构建于其之上。
其他语言(例如 Python 和 Java)也有类似的 Web 服务器和 Web 服务器框架。如您所见,这与 PHP 所采用的方法完全不同,PHP 通常根本不使用 HTTP 来处理请求。
然而,PHP 的最新版本现在有一个“内置网络服务器“, 但它是相对较新并且每次只能处理一个连接,因此不适合用于生产。它是专为开发人员设计的。
归根结底,PHP 的设计目的是在现有 HTML 文档的上下文中工作,而 Python、Ruby、Java 等其他语言则是通用的。据我所知,在这方面与 PHP 类似的其他 Web 语言只有微软的“经典” ASP,其设计类似。
答案2
没什么。您可以使用任何语言监听任何端口并在协议规则内做出响应(在本例中为HTTP
)。没有任何规定说这在 中是不可能的PHP
。您可以将其绑定到套接字,或者只是读取和写入STDIN
,STDOUT
并从 启动xinet
,甚至可以与另一个应用程序(例如apache
或 )一起使用,大多数人对 或 的了解比他们自己想要实现的要nginx
多得多。HTTP