websharks/php-web-server

WebSharks, Inc. 的 PHP Web Server

dev-dev 2016-08-24 03:03 UTC

This package is not auto-updated.

Last update: 2024-09-11 23:57:12 UTC


README

警告:PHP 内置的 Web 服务器是为了帮助应用开发而设计的。它也可能适用于测试目的或在受控环境中运行的应用演示。它不是一个功能齐全的 Web 服务器。不应用于公共网络。有关更多信息,请参阅这篇文章

安装

通过 Composer

需要 PHP 5.4+ 并带有 mbstring 扩展。已知与 PHP 7.x 的最新版本兼容。

{
    "require": {
        "websharks/php-web-server": "dev-master"
    }
}

或者,通过 Git

$ mkdir -p ~/projects/websharks;
$ git clone https://github.com/websharks/php-web-server ~/projects/websharks/php-web-server;

运行 Web 服务器

所需的目录结构

  • ~/www(绝对根基本目录;以下作为 -t 传递)
    • /localhost(与以下主机名匹配的文档根子文件夹)
      • index.php ...以及任何其他可访问的 Web 文件都可以存放在这里。
    • ...为任何您喜欢的域名。
$ mkdir -p ~/www/localhost;
$ echo 'It works!' > ~/www/localhost/index.php;

从终端窗口启动服务器

$ php \
  -S localhost:8080 \
  -t ~/www \
  -d variables_order=EGPCS \
  ~/projects/websharks/php-web-server/src/includes/router.php

注意:进程保持打开(即,占用)您的终端会话是正常的。在服务器运行时,您可以在浏览器中打开并导航到可访问的 Web 文件。完成测试后,按 Ctrl-C 在您的终端窗口中停止 Web 服务器。

注意:文档根最初只是 ~/www 基础,然后当您在浏览器中访问 http://localhost:8080/ 时自动变为: ~/www/localhost。换句话说,文档根根据请求中的主机名而变化,使得可以针对多个主机名运行一个 PHP Web 服务器,并通过 router.php 动态满足多个文档根。

更多信息

WordPress 兼容

router.php 文件能够自动回退到每个主机名文档根子文件夹中的根 index.php 文件(即,它执行 mod_rewrite 模拟)。这使得 PHP Web 服务器也与如 WordPress 这样的应用程序兼容。

限制:仅限标准 WordPress。与 WordPress 多站点网络不兼容。

使用自定义主机名

如果您已编辑 /etc/hosts 文件并希望使用自定义主机名,那是可以的。只需以不同的主机名启动 Web 服务器,并创建与该主机名匹配的文档根子文件夹。

为什么在这里使用 sudo大多数系统需要 sudo 绑定到小于 1024 的端口。在这种情况下需要 sudo,因为我们想使用默认标准端口 80,这样我们就可以通过输入自定义主机名: http://example.dev(不带端口号)来访问可访问的 Web 文件。因此,绑定到默认端口 80 需要 sudo

注意:如果端口 80 可用,这将仅在端口 80 上工作。例如,如果您还正在运行 Apache、Nginx 或其他占用端口 80 的 Web 服务器,您必须停止该服务器以释放端口 80 供 PHP 使用。

$ sudo php \
  -S example.dev:80 \
  -t ~/www \
  -d variables_order=EGPCS \
  ~/projects/websharks/php-web-server/src/includes/router.php

现在,如果您的 /etc/hosts 配置正确,您可以通过

  • http://example.dev/

文档根最初为 ~/www,然后在您访问 http://example.dev/ 时变为: ~/www/example.dev

一个文档根与多个子域名

您可以通过以下方式将文档根子文件夹强制到固定位置:硬编码完整的文档根。注意以下 -t 参数中添加的 /example.dev

为什么在这里使用 sudo大多数系统需要 sudo 绑定到小于 1024 的端口。在这种情况下需要 sudo,因为我们想使用默认标准端口 80,这样我们就可以通过输入自定义主机名: http://example.dev(不带端口号)来访问可访问的 Web 文件。因此,绑定到默认端口 80 需要 sudo

注意:如果端口 80 可用,这将仅在端口 80 上工作。例如,如果您还正在运行 Apache、Nginx 或其他占用端口 80 的 Web 服务器,您必须停止该服务器以释放端口 80 供 PHP 使用。

$ sudo php \
  -S example.dev:80 \
  -t ~/www/example.dev \
  -d variables_order=EGPCS \
  ~/projects/websharks/php-web-server/src/includes/router.php

现在,如果您的 /etc/hosts 配置正确,您可以通过

  • http://example.dev/
  • http://sub1.example.dev/
  • http://sub2.example.dev/

并且,文档根现在(始终)是 ~/www/example.dev,只要你的硬编码文档根子文件夹以请求的根主机名结尾。在这种情况下:example.dev

这种方式唯一的缺点是,你将失去运行单个PHP Web Server进程的能力,该进程能够根据主机名定位嵌套的文档根子文件夹。在这个例子中,你正在硬编码文档根子文件夹,这限制了PHP Web Server只在该文档根下运行;即,只针对单个根主机名。

环境变量

标准的PHP环境变量以期望的方式存在于 $_SERVER 超全局中。WebSharks PHP Web Router 还将添加一些额外的环境变量以方便使用,并努力填补通常由 Nginx 或其他 PHP-FPM 集成提供的常见 FastCGI 参数

以下是一个 $_SERVER 的示例转储,它将为您提供快速浏览。这是在以下URL生成的:http://localhost:8080/index.php/path/info?v=1(使用 PATH_INFO 展示更完整的示例)。

[HTTP_HOST] => localhost:8080

[DOCUMENT_BASE] => /Users/websharks/www
[DOCUMENT_ROOT] => /Users/websharks/www/localhost

[REMOTE_ADDR] => ::1
[REMOTE_PORT] => 61573

[SERVER_PORT] => 8080
[SERVER_NAME] => localhost
[SERVER_ADDR] => 127.0.0.1
[SERVER_PROTOCOL] => HTTP/1.1
[SERVER_SOFTWARE] => PHP 7.0.4 Development Server

[REQUEST_METHOD] => GET
[REQUEST_SCHEME] => http
[REDIRECT_STATUS] => 200

[QUERY_STRING] => v=1
[PATH_INFO] => /path/info
[SCRIPT_NAME] => /index.php
[DOCUMENT_URI] => /index.php
[PHP_SELF] => /index.php/path/info
[REQUEST_URI] => /index.php/path/info?v=1

[SCRIPT_FILENAME] => /Users/websharks/www/localhost/index.php
[PATH_TRANSLATED] => /Users/websharks/www/localhost/index.php

[REQUEST_TIME_FLOAT] => 1457530515.8927
[REQUEST_TIME] => 1457530515

除了 $_SERVER 之外,还有一个 $_ENV 超全局,其中包含启动PHP Web Server时使用的shell中的本地环境变量。默认情况下,PHP会自动 排除 内置PHP Web Server上下文中的 $_ENV 超全局。然而,建议您包含 $_ENV,因为它提供了大量有用的信息,例如 USERHOMESHELL 等。这是通过启动服务器时使用的 -d variables_order=EGPCS 标志(注意 E 的包含)来实现的。

每当 $_ENV 被填充(建议)时,WebSharks Web Router 将创建所有环境变量的内部副本。它将 $_SERVER 合并到 $_ENV 中($_SERVER 具有最高优先级);然后它将使用完整的环境变量集重新填充 $_SERVER,这样就可以从 $_SERVER 超全局访问它们。这也是大多数FastCGI实现的方式。这提高了兼容性并提供了一些额外的便利。

MIME类型库

以下文件扩展名将自动与这些内容类型头一起提供。

// Text files.
'md'  => 'text/plain; charset=utf-8',
'txt' => 'text/plain; charset=utf-8',

// Log files.
'log' => 'text/plain; charset=utf-8',

// Translation files.
'mo'  => 'application/x-gettext-translation',
'po'  => 'text/x-gettext-translation; charset=utf-8',
'pot' => 'text/x-gettext-translation; charset=utf-8',

// SQL files.
'sql'    => 'text/plain; charset=utf-8',
'sqlite' => 'text/plain; charset=utf-8',

// Template files.
'tmpl' => 'text/plain; charset=utf-8',
'tpl'  => 'text/plain; charset=utf-8',

// Server config files.
'admins'          => 'text/plain; charset=utf-8',
'cfg'             => 'text/plain; charset=utf-8',
'conf'            => 'text/plain; charset=utf-8',
'htaccess'        => 'text/plain; charset=utf-8',
'htaccess-apache' => 'text/plain; charset=utf-8',
'htpasswd'        => 'text/plain; charset=utf-8',
'ini'             => 'text/plain; charset=utf-8',

// CSS/JavaScript files.
'css'  => 'text/css; charset=utf-8',
'js'   => 'application/x-javascript; charset=utf-8',
'json' => 'application/json; charset=utf-8',

// PHP scripts/files.
'php'  => 'text/html; charset=utf-8',
'phps' => 'text/html; charset=utf-8',

// ASP scripts/files.
'asp'  => 'text/html; charset=utf-8',
'aspx' => 'text/html; charset=utf-8',

// Perl scripts/files.
'cgi' => 'text/html; charset=utf-8',
'pl'  => 'text/html; charset=utf-8',

// HTML/XML files.
'dtd'   => 'application/xml-dtd; charset=utf-8',
'hta'   => 'application/hta; charset=utf-8',
'htc'   => 'text/x-component; charset=utf-8',
'htm'   => 'text/html; charset=utf-8',
'html'  => 'text/html; charset=utf-8',
'shtml' => 'text/html; charset=utf-8',
'xhtml' => 'application/xhtml+xml; charset=utf-8',
'xml'   => 'text/xml; charset=utf-8',
'xsl'   => 'application/xslt+xml; charset=utf-8',
'xslt'  => 'application/xslt+xml; charset=utf-8',
'xsd'   => 'application/xsd+xml; charset=utf-8',

// Document files.
'csv'  => 'text/csv; charset=utf-8',
'doc'  => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'odt'  => 'application/vnd.oasis.opendocument.text',
'pdf'  => 'application/pdf',
'rtf'  => 'application/rtf',
'xls'  => 'application/vnd.ms-excel',

// Image/animation files.
'ai'       => 'image/vnd.adobe.illustrator',
'blend'    => 'application/x-blender',
'bmp'      => 'image/bmp',
'eps'      => 'image/eps',
'fla'      => 'application/vnd.adobe.flash',
'gif'      => 'image/gif',
'ico'      => 'image/x-icon',
'jpe'      => 'image/jpeg',
'jpeg'     => 'image/jpeg',
'jpg'      => 'image/jpeg',
'png'      => 'image/png',
'psd'      => 'image/vnd.adobe.photoshop',
'pspimage' => 'image/vnd.corel.psp',
'svg'      => 'image/svg+xml',
'swf'      => 'application/x-shockwave-flash',
'tif'      => 'image/tiff',
'tiff'     => 'image/tiff',

// Audio files.
'mid'  => 'audio/midi',
'midi' => 'audio/midi',
'mp3'  => 'audio/mp3',
'wav'  => 'audio/wav',
'wma'  => 'audio/x-ms-wma',

// Video files.
'avi'  => 'video/avi',
'flv'  => 'video/x-flv',
'ogg'  => 'video/ogg',
'ogv'  => 'video/ogg',
'mp4'  => 'video/mp4',
'mov'  => 'movie/quicktime',
'mpg'  => 'video/mpeg',
'mpeg' => 'video/mpeg',
'qt'   => 'video/quicktime',
'webm' => 'video/webm',
'wmv'  => 'audio/x-ms-wmv',

// Font files.
'eot'   => 'application/vnd.ms-fontobject',
'otf'   => 'application/x-font-otf',
'ttf'   => 'application/x-font-ttf',
'woff'  => 'application/x-font-woff',
'woff2' => 'application/x-font-woff',

// Archive files.
'7z'   => 'application/x-7z-compressed',
'dmg'  => 'application/x-apple-diskimage',
'gtar' => 'application/x-gtar',
'gz'   => 'application/gzip',
'iso'  => 'application/iso-image',
'jar'  => 'application/java-archive',
'phar' => 'application/php-archive',
'rar'  => 'application/x-rar-compressed',
'tar'  => 'application/x-tar',
'tgz'  => 'application/x-gtar',
'zip'  => 'application/zip',

// Other misc files.
'bat'   => 'application/octet-stream',
'bin'   => 'application/octet-stream',
'class' => 'application/octet-stream',
'com'   => 'application/octet-stream',
'dll'   => 'application/octet-stream',
'exe'   => 'application/octet-stream',
'sh'    => 'application/octet-stream',
'bash'  => 'application/octet-stream',
'zsh'   => 'application/octet-stream',
'so'    => 'application/octet-stream',

注意事项

  • 目前完全不支持 https://

  • 目前完全不支持 HTTP 2(仅支持 HTTP 1.1)。

  • PHP的Web服务器仅运行单个单线程进程。如果请求被阻塞,PHP脚本将挂起;即,请求是同步处理的。一次一个(最大)。这意味着,例如,你不能有一个尝试连接到由同一PHP Web Server提供的另一个PHP脚本的PHP脚本。这将每次都导致超时。

    例如,如果 http://localhost:8080/script1.php 包含

    <?php
    file_get_contents('http://localhost:8080/script2.php');
    // `script2.php` will not load because `script1.php` is blocking it.
    // In other words, `script2.php` cannot run until `script1.php` finishes.
    // It can't finish, because it is stuck waiting for `script2.php`.

    简而言之,script2.php 将永远不会运行,而 script1.php 将在等待它时超时。