Skip to content

Commit 32c171e

Browse files
author
ahmard
committed
Swoole server implementation
Console helper added Environment file helper added Project kernel file added AbstractServer added to help with creation servers easily ServerInfo can now be populated with data directly to it Encoded CLI arguments can now be retrieved and decoded at once
1 parent fae8e80 commit 32c171e

27 files changed

+1106
-126
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
/.idea/
22
/vendor/
3-
/composer.lock
3+
/composer.lock
4+
/bin/.pid
5+
.env

README.md

+29
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,33 @@ Server::create('127.0.0.1', 9001)
6060
->onRequest($handler)
6161
->start()
6262
->logOutputToConsole();
63+
```
64+
65+
### Swoole
66+
An implementation of [Swoole](https://swoole.co.uk)
67+
68+
```php
69+
use PHPServer\Swoole\Http\Request;
70+
use PHPServer\Swoole\Server;
71+
72+
require 'vendor/autoload.php';
73+
74+
$handler = function (Request $request) {
75+
$html = 'Welcome,<br/>';
76+
$html .= "Method: {$request->getMethod()}<br/>";
77+
$html .= "Route: {$request->getUri()->getPath()}";
78+
$request->response()->html($html);
79+
};
80+
81+
Server::create('127.0.0.1', 9904)
82+
->watchFilesystemChanges([__DIR__])
83+
->onRequest($handler)
84+
->setServerConfig([
85+
'enable_static_handler' => true,
86+
'http_parse_post' => true,
87+
'worker_num' => 8,
88+
'package_max_length' => 10 * 1024 * 1024
89+
])
90+
->start()
91+
->logOutputToConsole();
6392
```

bin/swoole.php

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
use Dotenv\Dotenv;
4+
use PHPServer\Env;
5+
use PHPServer\ServerInfo;
6+
use PHPServer\Swoole\Console;
7+
use PHPServer\Swoole\Http\Request;
8+
use PHPServer\Swoole\Http\Response;
9+
use PHPServer\Terminal;
10+
use Swoole\Http\Request as SWRequest;
11+
use Swoole\Http\Response as SWResponse;
12+
use Swoole\Http\Server;
13+
use Swoole\Runtime;
14+
use Swotch\Watcher;
15+
16+
require 'vendor/autoload.php';
17+
18+
$swooleData = Terminal::getArgumentAndDecode('s', 'swoole');
19+
$serverData = Terminal::getArgumentAndDecode('i', 'server-info');
20+
21+
$serverInfo = ServerInfo::create($serverData);
22+
23+
function handleException(Throwable $exception, ?Request $request = null): void
24+
{
25+
try {
26+
$request?->response()->html($exception);
27+
} catch (Throwable $exception) {
28+
if (!Env::isInProduction()) {
29+
$request->response()->html($exception);
30+
return;
31+
}
32+
33+
$request->response()->html('Internal Server Error');
34+
} finally {
35+
Console::error($exception);
36+
}
37+
}
38+
39+
set_exception_handler('handleException');
40+
41+
try {
42+
43+
if (null !== $serverInfo->getEnvDirectory()) {
44+
$dotEnv = Dotenv::createImmutable(__DIR__)->load();
45+
}
46+
47+
//Runtime configuration
48+
Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL);
49+
50+
$server = new Server($serverInfo->getHost(), $serverInfo->getPort());
51+
52+
$server->on(
53+
'request',
54+
function (SWRequest $swRequest, SWResponse $swResponse) use ($serverInfo): void {
55+
$response = new Response($swResponse);
56+
$request = new Request($swRequest, $response);
57+
$response->setRequest($request);
58+
$serverInfo->getRequestCallback()($request);
59+
}
60+
);
61+
62+
$server->on('start', function (Server $server) use ($serverInfo, $swooleData) {
63+
Console::info("Swoole server started at http://{$serverInfo->getHost()}:{$serverInfo->getPort()}");
64+
65+
file_put_contents(__DIR__ . '/.pid', $server->getMasterPid());
66+
67+
//Run file watcher
68+
if (!empty($swooleData['watch_filesystem_changes'])) {
69+
go(function () use ($server, $swooleData) {
70+
Watcher::watch($swooleData['watch_filesystem_changes'])
71+
->onAny(fn($e) => $server->reload());
72+
});
73+
}
74+
});
75+
76+
$server->set(\PHPServer\Swoole\Server::cleanSwooleServerConfig($swooleData));
77+
78+
$server->start();
79+
} catch (Error $error) {
80+
dump($error);
81+
}

composer.json

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@
55
"license": "MIT",
66
"require": {
77
"php": "^8.0",
8+
"ext-pdo": "*",
89
"react/child-process": "^0.6.3",
910
"react/http": "^1.5",
1011
"opis/closure": "^3.6",
11-
"symfony/console": "^5.3"
12+
"symfony/console": "^5.3",
13+
"ahmard/quick-route": "^3.8",
14+
"nette/utils": "^3.2",
15+
"vlucas/phpdotenv": "^5.3"
1216
},
1317
"require-dev": {
1418
"phpstan/phpstan": "^0.12.98",
15-
"symfony/var-dumper": "^5.3"
19+
"symfony/var-dumper": "^5.3",
20+
"swoole/ide-helper": "^4.7",
21+
"ahmard/swotch": "^0.0.1"
1622
},
1723
"autoload": {
1824
"psr-4": {

phpstan.neon

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
parameters:
22
level: 6
33
checkMissingIterableValueType: false
4+
checkGenericClassInNonGenericObjectType: false
45
paths:
56
- bin
67
- src

src/AbstractServer.php

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace PHPServer;
4+
5+
use Closure;
6+
use JetBrains\PhpStorm\Pure;
7+
8+
abstract class AbstractServer implements ServerInterface
9+
{
10+
protected string|null $documentRoot = null;
11+
protected string|null $routerScript = null;
12+
protected string|null $envDir = null;
13+
protected Closure|null $requestCallback = null;
14+
15+
public function __construct(
16+
protected string $host,
17+
protected int $port
18+
)
19+
{
20+
}
21+
22+
#[Pure] public static function create(string $host, int $port): static
23+
{
24+
return new static($host, $port);
25+
}
26+
27+
public function setDocumentRoot(string $path): static
28+
{
29+
$this->documentRoot = $path;
30+
return $this;
31+
}
32+
33+
public function setEnvDirectory(string $path): static
34+
{
35+
$this->envDir = $path;
36+
return $this;
37+
}
38+
39+
public function onRequest(callable $callback): static
40+
{
41+
$this->requestCallback = $callback;
42+
return $this;
43+
}
44+
45+
public function start(): RunningServer
46+
{
47+
return new RunningServer($this, ServerProcess::create($this));
48+
}
49+
50+
public function getInfo(): ServerInfo
51+
{
52+
return ServerInfo::create()
53+
->setHost($this->host)
54+
->setPort($this->port)
55+
->setDocumentRoot($this->documentRoot)
56+
->setRequestCallback($this->requestCallback)
57+
->setRouterScript($this->routerScript);
58+
}
59+
}

src/BuiltIn/Server.php

+2-50
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,18 @@
33
namespace PHPServer\BuiltIn;
44

55
use Closure;
6-
use JetBrains\PhpStorm\Pure;
6+
use PHPServer\AbstractServer;
77
use PHPServer\ServerCommand;
8-
use PHPServer\ServerInfo;
9-
use PHPServer\ServerInterface;
10-
use PHPServer\ServerProcess;
11-
use PHPServer\RunningServer;
128
use PHPServer\Terminal;
139
use function PHPServer\base_path;
1410

15-
class Server implements ServerInterface
11+
class Server extends AbstractServer
1612
{
1713
protected static array $filledInfo = [];
1814
protected string|null $documentRoot = null;
1915
protected string|null $routerScript = null;
2016
protected Closure|null $requestCallback = null;
2117

22-
public function __construct(
23-
protected string $host,
24-
protected int $port
25-
)
26-
{
27-
}
28-
29-
#[Pure] public static function create(string $host, int $port): static
30-
{
31-
return new static($host, $port);
32-
}
3318

3419
public function getCommand(): ServerCommand
3520
{
@@ -58,37 +43,4 @@ public function getCommand(): ServerCommand
5843

5944
return $serverCommand;
6045
}
61-
62-
public function getInfo(): ServerInfo
63-
{
64-
return ServerInfo::create()
65-
->setHost($this->host)
66-
->setPort($this->port)
67-
->setDocumentRoot($this->documentRoot)
68-
->setRequestCallback($this->requestCallback)
69-
->setRouterScript($this->routerScript);
70-
}
71-
72-
public function setDocumentRoot(string $path): static
73-
{
74-
$this->documentRoot = $path;
75-
return $this;
76-
}
77-
78-
public function setRouterScript(string $filePath): static
79-
{
80-
$this->routerScript = $filePath;
81-
return $this;
82-
}
83-
84-
public function onRequest(callable $callback): static
85-
{
86-
$this->requestCallback = $callback;
87-
return $this;
88-
}
89-
90-
public function start(): RunningServer
91-
{
92-
return new RunningServer($this, ServerProcess::create($this));
93-
}
9446
}

0 commit comments

Comments
 (0)