PHP 내장 웹 서버
머리말
PHP는 5.4부터 웹 서버가 내장되어 있습니다.
주로 지역 개발을 위해 사용됩니다. 온라인 환경에서는 사용할 수 없습니다. 이제 이 도구를 사용하는 방법을 소개하겠습니다.
기본 응용 프로그램
먼저 프로젝트 디렉터리가 /home/baoguoxiao/www/php/demo
이고 외부 세계에서 액세스할 수 있는 디렉터리가 /home/baoguoxiao/www라고 가정합니다. /php/demo/공개
. 그러면 액세스 포트는 8000
이고 항목 파일은 index.php
및 index.html
입니다. 그런 다음 다음 명령을 실행할 수 있습니다. /home/baoguoxiao/www/php/demo
,外界可访问的目录是/home/baoguoxiao/www/php/demo/public
。然后访问的端口是8000
,入口文件是index.php
和index.html
。那么我们可以执行如下命令:
cd /home/baoguoxiao/www/php/demo/public php -S localhost:8000
然后这个时候就可以正常访问了。
那么现在有个问题,就是难道每次必须要进入public
文件夹才能启动web服务器吗,其实我们可以指定根目录的,那么可以使用如下命令:
cd /home/baoguoxiao/www/php/demo php -S localhost:8000 -t public/
那么现在有一个问题就是说,如果我们使用了单入口,而且还是用了PATHINFO模式。那么上面的可能就有问题了。
对此,我们可以使用如下方案:
cd /home/baoguoxiao/www/php/demo php -S localhost:8000 router.php
router.php 文件的代码
/** * 对URL进行解析,并获取请求的文件名 */$uri = urldecode(parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH));/** * 判断是否存在该文件,如果不存在,则直接继续加载入口文件 */if ($uri !== "/" && file_exists(__DIR__ . "$uri")) { return false; }/** * 加载入口文件 */require_once "./index.php";
通过这个路由文件,我们就可以支持目前常用的开发情况了。
框架参考
上面的方式是我们自己的实现,那么我们也可以看看相关知名框架的实现方法。
比如 Laravel 和 Symfony。
Laravel
在Laravel中的安装一节中介绍了一个命令可以使用PHP内置web服务器实现外部访问的命令。实现的命令是:
php artisan serve
我们可以看一下相关代码:
具体的文件路径为:vendor/laravel/framework/src/Illuminate/Foundation/Console/ServeCommand.php
/** * 执行命令. * * @return int * * @throws \Exception */ public function handle() { // 切换路径到 public 目录 chdir(public_path()); // 在命令台进行输出相关内容 $this->line("<info>Laravel development server started:</info> <http://{$this->host()}:{$this->port()}>"); // 执行外部程序,并且 $status 为系统的返回状态 passthru($this->serverCommand(), $status); // $status 为0 表示执行正常, 为其他大于0的数字表示出现了错误,有可能是端口被抢占了,这个时候就会接着判断是否进行再次尝试 if ($status && $this->canTryAnotherPort()) { // 对绑定的端口号加1 默认是8000, 如果失败则重试端口号为8001,再次失败重试端口号为8002,以此类推。 $this->portOffset += 1; // 再次调用此程序 return $this->handle(); } // 返回状态值 return $status; } /** * 获取完整的 server 命令. * * @return string */ protected function serverCommand() { return sprintf('%s -S %s:%s %s', // 获取PHP可执行命令的路径 ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false)), // 获取需要绑定的host $this->host(), // 获取需要绑定的端口 $this->port(), // 对需要执行的参数进行转义处理。这里的 server 就是我们之前说的路由文件,它在项目的根路径下 ProcessUtils::escapeArgument(base_path('server.php')) ); }
对上面的命令进行翻译一下,实际上就是执行的
cd ./public php -S 0.0.0.0:8000 ../server.php
note:
这里我们可以看到一个区别就是之前我自己写的代码,host 都是 localhost, 但是这里写的是 0.0.0.0。这两个有什么区别呢?
其实区别很简单,比如我之前写的 localhost 绑定的ip 是 127.0.0.1, 这个相当于一个回环地址,那么我们就只允许本机的IP进行访问。而 0.0.0.0,则表示我们对ip不进行限制,所有的IP都可以进行访问。
那我们接着再来看看项目根目录下面的server.php
:
/** * Laravel - A PHP Framework For Web Artisans * * @package Laravel * @author Taylor Otwell <taylor@laravel.com> */ $uri = urldecode( parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ); // 这个文件允许我们从内置 PHP web 服务器中模拟 Apache 的 "mod_rewrite" 功能. // 这提供了一种测试 Laravel 应用程序的便捷方法, // 而无需在此安装"真正的" web 服务器软件。 if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { return false; } require_once __DIR__.'/public/index.php';
发现跟我之前写的路由文件相同。没错,我就是从这里抄过来的。
基本上 Larvel 的实现方法就是这样了。
Symfony
如果你在使用 Symfony 框架话,发现Symfony有一个组件叫做web-server-bundle,这个组件的作用跟Laravel相同,也是不借助web服务器,实现通过浏览器访问应用程序。
基本的操作可以参考该页面
我在这里主要说一下Symfony是如何实现的.
在Symfony中有一段代码是这样的:
public function start(WebServerConfig $config, $pidFile = null) { // 获取默认的PID文件位置 $pidFile = $pidFile ?: $this->getDefaultPidFile(); // 判断是否在运行,如果运行则提示已经在监听了 if ($this->isRunning($pidFile)) { throw new \RuntimeException(sprintf('A process is already listening on http://%s.', $config->getAddress())); } // fork了一个子进程,如果成功,会有两个进程进行同时执行下面的文件,父进程,也就是当前执行的进程会返回子进程的PID,而子进程则返回的PID为0, // 如果失败,则子进程不会创建,并且父进程会返回的pid为-1。更多内容可查看 https://www.php.net/manual/zh/function.pcntl-fork.php $pid = pcntl_fork(); // 表示fork进程失败 if ($pid < 0) { throw new \RuntimeException('Unable to start the server process.'); } // 进入这个判断,表示执行的是父进程,表示不用继续向下执行 if ($pid > 0) { return self::STARTED; } // 从此往后是子进程运行,首先通过 posix_setsid 变为守护进程,意思是使其脱离终端的管理,自立门户,谁也没办法管理这个进程,除了PID。 if (posix_setsid() < 0) { throw new \RuntimeException('Unable to set the child process as session leader.'); } // 创建命令,命令类似Laravel,不过这里的路由文件跟Laravel类似。也是处理加载规则,并加载入口文件。具体的router.php 路径为: // vendor\symfony\web-server-bundle/Resources/router.php // 下面是禁用输出并且开始运行 $process = $this->createServerProcess($config); $process->disableOutput(); $process->start(); // 判断是否运行成功 if (!$process->isRunning()) { throw new \RuntimeException('Unable to start the server process.'); } // 写入PID文件 file_put_contents($pidFile, $config->getAddress()); // 检测PID文件,如果PID文件删除了,那么进程就立即退出。 while ($process->isRunning()) { if (!file_exists($pidFile)) { $process->stop(); } sleep(1); } // 返回停止的状态 return self::STOPPED; } /** * 启动PHP内置web服务器 * @return Process The process */ private function createServerProcess(WebServerConfig $config) { // 查找PHP的可执行程序 $finder = new PhpExecutableFinder(); if (false === $binary = $finder->find(false)) { throw new \RuntimeException('Unable to find the PHP binary.'); } $xdebugArgs = ini_get('xdebug.profiler_enable_trigger') ? ['-dxdebug.profiler_enable_trigger=1'] : []; // 实例化PHP要执行的命令 php_path -dvariables_order=EGPCS -S 127.0.0.1:8000 vendor\symfony\web-server-bundle/Resources/router.php $process = new Process(array_merge([$binary], $finder->findArguments(), $xdebugArgs, ['-dvariables_order=EGPCS', '-S', $config->getAddress(), $config->getRouter()])); // 设置工作目录 $process->setWorkingDirectory($config->getDocumentRoot()); // 设置超时时间 $process->setTimeout(null); // 设置环境变量 if (\in_array('APP_ENV', explode(',', getenv('SYMFONY_DOTENV_VARS')))) { $process->setEnv(['APP_ENV' => false]); $process->inheritEnvironmentVariables(); } // 返回相关变量 return $process; }
我在上面的代码中进行了注释, 描述了Symfony是如何启动的.
里面有一个问题就是使用pcntl_fork
, 该扩展在Windows中是不受支持的. 所以 Symfony框架会提示使用php bin/console server:run
命令运行程序.
未来展望
其实还有一个方式, 就是 Workman 是通过自身的实现的web服务器,它并没有借助php -S
rrreee
public
폴더에 들어가야 할까요? 실제로 루트 디렉터리를 지정하면 다음 명령을 사용할 수 있습니다. rrreee
이제 한 가지 문제는 단일 항목을 사용하면서 여전히 PATHINFO 모드를 사용한다는 것입니다. 그러면 위와 같은 문제가 발생할 수 있습니다. 이를 위해 다음 솔루션을 사용할 수 있습니다.rrreeerouter.php 파일 코드 rrreee 이 라우팅 파일을 통해 현재 일반적으로 사용되는 개발 상황을 지원할 수 있습니다.
Framework Reference🎜🎜위 방법은 자체적으로 구현한 방법이므로 관련 유명 프레임워크의 구현 방법도 살펴볼 수 있습니다. 🎜🎜Laravel 및 Symfony 등. 🎜Laravel
🎜설치 🎜 섹션에서는 PHP에 내장된 웹 서버를 사용하여 외부 액세스를 달성할 수 있는 명령을 소개합니다. 구현된 명령은 다음과 같습니다. 🎜rrreee🎜관련 코드를 살펴볼 수 있습니다. 🎜🎜구체 파일 경로는 다음과 같습니다: Vendor/laravel/framework/src/Illuminate/Foundation/Console/ServeCommand.php🎜rrreee🎜위 명령을 번역합니다. , 실제로 실행됩니다🎜rrreee🎜note:🎜🎜여기서 차이점을 볼 수 있는 것은 이전에 작성한 코드에서는 호스트가 모두 localhost인데 여기에 작성된 것은 0.0.0.0입니다. 이 둘의 차이점은 무엇인가요? 🎜🎜사실 차이점은 매우 간단합니다. 예를 들어 앞서 작성한 localhost에 바인딩된 IP는 127.0.0.1입니다. 이는 루프백 주소와 동일하므로 로컬 IP만 액세스하도록 허용합니다. 그리고 0.0.0.0은 IP에 제한이 없고 모든 IP에 접근이 가능하다는 뜻입니다. 🎜🎜그럼 프로젝트 루트 디렉터리 아래의
server.php
를 살펴보겠습니다.🎜rrreee🎜이전에 작성한 라우팅 파일과 동일한 것을 발견했습니다. 네, 여기에서 복사했습니다. 🎜🎜기본적으로 Larvel이 구현되는 방식은 다음과 같습니다. 🎜Symfony
🎜Symfony 프레임워크를 사용하는 경우 Symfony에 web-server-bundle🎜, 이 구성 요소는 Laravel과 동일한 기능을 가지며 웹의 도움 없이 브라우저를 통해 애플리케이션에 액세스할 수도 있습니다. 섬기는 사람. 🎜🎜기본적인 작업은 이 페이지🎜🎜🎜여기에서는 주로 Symfony가 어떻게 구현되는지에 대해 이야기합니다.🎜🎜Symfony에는 다음과 같은 코드가 있습니다.🎜rrreee🎜위 코드에 Symfony가 어떻게 시작되는지 설명하기 위해 주석을 달았습니다. 🎜🎜있습니다.pcntl_fork
🎜, 이 확장은 Windows에서 지원되지 않습니다. 따라서 Symfony 프레임워크는 프로그램을 실행하기 위해 php bin/console server:run
명령을 사용하라는 메시지를 표시합니다. 🎜Future Outlook🎜🎜사실 또 다른 방법이 있습니다. 즉, Workman은 자체적으로 구현된 웹 서버이며, php -S
명령에 의존하지 않습니다. 나는 코드의 이 부분을 완전히 이해하지 못했고, 이 부분은 몇 개의 별도 장에서 논의될 수 있다고 생각합니다. 앞으로도 이런 기회가 있기를 바랍니다. 🎜🎜요약🎜🎜웹 서버 액세스를 위한 PHP 명령 학습과 Laravel 및 Symfony 프레임워크 분석을 통해 Windows 개발 과정에서 이 방법을 사용하여 웹 서버에 대한 의존성을 제거할 수 있다는 것을 배웠습니다. 둘 다 Windows 환경에서 개발하고 PHP 기술을 배우는 것이 편리합니다. 🎜🎜이에 대해 궁금한 점이 있으면 댓글을 달고 소통할 수 있습니다. 🎜🎜PHP 관련 기술 기사를 더 보려면 🎜을 방문하세요. 🎜PHP Tutorial🎜🎜 학습을 위한 칼럼! 🎜위 내용은 PHP 내장 웹 서버의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

문자열은 문자, 숫자 및 기호를 포함하여 일련의 문자입니다. 이 튜토리얼은 다른 방법을 사용하여 PHP의 주어진 문자열의 모음 수를 계산하는 방법을 배웁니다. 영어의 모음은 A, E, I, O, U이며 대문자 또는 소문자 일 수 있습니다. 모음이란 무엇입니까? 모음은 특정 발음을 나타내는 알파벳 문자입니다. 대문자와 소문자를 포함하여 영어에는 5 개의 모음이 있습니다. a, e, i, o, u 예 1 입력 : String = "Tutorialspoint" 출력 : 6 설명하다 문자열의 "Tutorialspoint"의 모음은 u, o, i, a, o, i입니다. 총 6 개의 위안이 있습니다

이 튜토리얼은 PHP를 사용하여 XML 문서를 효율적으로 처리하는 방법을 보여줍니다. XML (Extensible Markup Language)은 인간의 가독성과 기계 구문 분석을 위해 설계된 다목적 텍스트 기반 마크 업 언어입니다. 일반적으로 데이터 저장 AN에 사용됩니다

정적 바인딩 (정적 : :)는 PHP에서 늦은 정적 바인딩 (LSB)을 구현하여 클래스를 정의하는 대신 정적 컨텍스트에서 호출 클래스를 참조 할 수 있습니다. 1) 구문 분석 프로세스는 런타임에 수행됩니다. 2) 상속 관계에서 통화 클래스를 찾아보십시오. 3) 성능 오버 헤드를 가져올 수 있습니다.

PHP의 마법 방법은 무엇입니까? PHP의 마법 방법은 다음과 같습니다. 1. \ _ \ _ Construct, 객체를 초기화하는 데 사용됩니다. 2. \ _ \ _ 파괴, 자원을 정리하는 데 사용됩니다. 3. \ _ \ _ 호출, 존재하지 않는 메소드 호출을 처리하십시오. 4. \ _ \ _ get, 동적 속성 액세스를 구현하십시오. 5. \ _ \ _ Set, 동적 속성 설정을 구현하십시오. 이러한 방법은 특정 상황에서 자동으로 호출되어 코드 유연성과 효율성을 향상시킵니다.

PHP에서는 예측할 수없는 토큰을 사용하여 CSRF 공격을 효과적으로 방지 할 수 있습니다. 특정 방법은 다음과 같습니다. 1. 형태로 CSRF 토큰을 생성하고 포함시킨다. 2. 요청을 처리 할 때 토큰의 유효성을 확인하십시오.
