使用PHP内置服务器运行WordPress


从PHP5.4开始,PHP内置了一个Web服务器。它虽然不是一个功能齐全的Web服务器,但是可以很好的在开发环境中使用,避免了开发环境对于Nginx、Apache等Web服务器的依赖。

路由脚本

<?php

use \Throwable;
use \Exception;

// 根目录
$root = $_SERVER['DOCUMENT_ROOT'];

// 使用抛异常方式来处理错误,中断程序的同时,避免整个进程终止
class HTTPException extends Exception
{
	public function __construct($code = 400, $message = '')
	{
		parent::__construct($message, $code);
	}
}

function abort($status) {
	throw new HTTPException($status);
}

try {
	// url path
	$path = '/' . ltrim(parse_url($_SERVER['REQUEST_URI'])['path'], '/');
	
	// 绝对路径
	$abs = $root . $path;

	// 访问文件直接引入
	if (is_file($abs)) {
		if (strpos($abs, '.php') !== false) {
			require_once $abs;
			return true;
		} else if (strpos($abs, '.sqlite') !== false) {
			abort(403);
		} else {
			return false;
		}
	}
	
	// 文件夹的情况需要处理路径的标准化,否则html使用的相对链接会有问题
	if (is_dir($abs)) {

		// 标准化url
		if ( substr($path, -1) !== '/' ) {
			header('location:' . $path . '/');
			exit;
		}

		// 没有index.php禁止访问
		if (!is_file($abs . '/index.php')) {
			return false;
		}

		require_once $abs . '/index.php';
		return true;
	}

	// 其他所有情况都交给根目录的index.php处理
	require_once $root . '/index.php';
	return true;
} catch (HTTPException $e) {
	http_response_code($e->getCode());
	return true;
} catch (Throwable $e) {
	error_log('catch: ' . $e->getMessage());
	return false;
}

运行命令

php -S 0.0.0.0:9000 -t /var/www/html -c php.ini route.php
-S 监听地址
-t 根目录
-c 配置文件
如果希望多进程运行,在PHP 7.4及以上的版本中可以通过设置PHP_CLI_SERVER_WORKERS环境变量来指定运行的进程数量。

关于PHP内置服务器的更多信息,可以参考官方文档: PHP: Built-in web server