Skip to content

Commit f55b73a

Browse files
author
ahmard
committed
Initial Commit
0 parents  commit f55b73a

File tree

8 files changed

+249
-0
lines changed

8 files changed

+249
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/.idea/
2+
/vendor/
3+
/composer.lock

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# PHP Server
2+
3+
## Installation
4+
```
5+
composer require ahmard/php-server
6+
```
7+
8+
## Usage
9+
### PHP Built-In Server
10+
11+
- With document root
12+
```php
13+
use PHPServer\BuiltIn\Server;
14+
15+
Server::create('127.0.0.1', '9900')
16+
->setDocumentRoot(__DIR__)
17+
->start();
18+
```
19+
20+
- Route request to single entry file
21+
```php
22+
use PHPServer\BuiltIn\Server;
23+
24+
Server::create('127.0.0.1', '9900')
25+
->setRouterScript(__DIR__ . 'public/index.php')
26+
->start();
27+
```
28+
29+
- Provide callable to be invoked when request is received
30+
```php
31+
use PHPServer\BuiltIn\Server;
32+
33+
Server::create('127.0.0.1', '9900')
34+
->onRequest(fn() => var_dump('Request Received'))
35+
->start();
36+
```

composer.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "ahmard/php-server",
3+
"description": "PHP local server helper",
4+
"type": "library",
5+
"license": "MIT",
6+
"require": {
7+
"php": "^8.0",
8+
"react/child-process": "^0.6.3"
9+
},
10+
"require-dev": {
11+
"phpstan/phpstan": "^0.12.98",
12+
"symfony/var-dumper": "^5.3"
13+
},
14+
"autoload": {
15+
"psr-4": {
16+
"PHPServer\\": "src/"
17+
}
18+
},
19+
"authors": [
20+
{
21+
"name": "ahmard",
22+
"email": "ahmard06@gmail.com"
23+
}
24+
]
25+
}

src/BuiltIn/Factory.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace PHPServer\BuiltIn;
4+
5+
use InvalidArgumentException;
6+
7+
class Factory
8+
{
9+
public static function create(Server ...$servers): Factory
10+
{
11+
return new Factory($servers);
12+
}
13+
14+
/**
15+
* @param Server[] $servers
16+
*/
17+
public function __construct(protected array $servers)
18+
{
19+
foreach ($this->servers as $server) {
20+
if (!$server instanceof Server) {
21+
$serverClass = $server::class;
22+
throw new InvalidArgumentException("$serverClass must be an instance of " . Server::class);
23+
}
24+
}
25+
}
26+
27+
public function serve(): void
28+
{
29+
foreach ($this->servers as $server){
30+
ServerProcess::create($server);
31+
}
32+
}
33+
}

src/BuiltIn/Server.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace PHPServer\BuiltIn;
4+
5+
use Closure;
6+
use JetBrains\PhpStorm\ArrayShape;
7+
use JetBrains\PhpStorm\Pure;
8+
9+
class Server
10+
{
11+
protected string|null $documentRoot = null;
12+
protected string|null $routerScript = null;
13+
protected Closure|null $requestCallback = null;
14+
15+
16+
#[Pure] public static function create(float|string $host, int $port): Server
17+
{
18+
return new Server($host, $port);
19+
}
20+
21+
public function __construct(
22+
protected float|string $host,
23+
protected int $port
24+
)
25+
{
26+
}
27+
28+
public function setDocumentRoot(string $path): Server
29+
{
30+
$this->documentRoot = $path;
31+
return $this;
32+
}
33+
34+
public function setRouterScript(string $filePath): Server
35+
{
36+
$this->routerScript = $filePath;
37+
return $this;
38+
}
39+
40+
public function onRequest(callable $callback): Server
41+
{
42+
$this->requestCallback = $callback;
43+
return $this;
44+
}
45+
46+
public function start(): StartedServer
47+
{
48+
return new StartedServer($this, ServerProcess::create($this));
49+
}
50+
51+
#[ArrayShape(['host' => "int|string", 'port' => "int", 'document_root' => "null|string", 'router_script' => "null|string", 'request_callback' => "\Closure|null"])]
52+
public function getInfo(): array
53+
{
54+
return [
55+
'host' => $this->host,
56+
'port' => $this->port,
57+
'document_root' => $this->documentRoot,
58+
'router_script' => $this->routerScript,
59+
'request_callback' => $this->requestCallback,
60+
];
61+
}
62+
}

src/BuiltIn/ServerProcess.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace PHPServer\BuiltIn;
4+
5+
use JetBrains\PhpStorm\Pure;
6+
use React\ChildProcess\Process;
7+
8+
class ServerProcess
9+
{
10+
public static function create(Server $server)
11+
{
12+
dump(self::getConsoleCommand($server));
13+
$process = new Process('echo foo');
14+
$process->start();
15+
16+
$process->stdout->on('data', function ($chunk) {
17+
// echo $chunk;
18+
});
19+
20+
$process->on('exit', function ($exitCode, $termSignal) {
21+
//echo 'Process exited with code ' . $exitCode . PHP_EOL;
22+
});
23+
24+
return $process;
25+
}
26+
27+
#[Pure] protected static function getConsoleCommand(Server $server): string
28+
{
29+
$config = $server->getInfo();
30+
$command = "php -S {$config['host']}:{$config['port']}";
31+
32+
if (isset($config['document_root'])) {
33+
$command .= " -t {$config['document_root']}";
34+
} else {
35+
if (isset($config['router_script'])) {
36+
$command .= " {$config['router_script']}";
37+
}
38+
}
39+
40+
return $command;
41+
}
42+
}

src/BuiltIn/StartedServer.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace PHPServer\BuiltIn;
4+
5+
use React\ChildProcess\Process;
6+
7+
class StartedServer
8+
{
9+
public function __construct(
10+
protected Server $server,
11+
protected Process $process
12+
)
13+
{
14+
}
15+
16+
/**
17+
* @return Process
18+
*/
19+
public function getProcess(): Process
20+
{
21+
return $this->process;
22+
}
23+
24+
/**
25+
* @return Server
26+
*/
27+
public function getServer(): Server
28+
{
29+
return $this->server;
30+
}
31+
}

test.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
use PHPServer\BuiltIn\Server;
4+
5+
require 'vendor/autoload.php';
6+
7+
Server::create('127.0.0.1', '9900')
8+
->setDocumentRoot(__DIR__)
9+
->start();
10+
11+
Server::create('127.0.0.1', '9901')
12+
->setRouterScript('index.php')
13+
->start();
14+
15+
Server::create('127.0.0.1', '9902')
16+
->setDocumentRoot(__DIR__)
17+
->start();

0 commit comments

Comments
 (0)