Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 116 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,81 +13,134 @@ composer require phalcon/bridge-swoole
See comments inside code for more details.

```php
<?php
require_once __DIR__ . '/../vendor/autoload.php';

declare(strict_types=1);

use Phalcon\Di\Di;
use Phalcon\Db\Adapter\Pdo\Mysql;
use Phalcon\Db\Enum;
use Phalcon\Mvc\Micro;
use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Volt;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Http\Server;

$di = new Di();
$di->setShared('router', new Router(false));

$app = new Micro($di);

/**
* Define example GET endpoint with text response.
*/
$app->get('/', function() {
return 'Hello World';
});

/**
* Define example redirect.
*/
$app->get('/redirect', function () {
// Redirect is handled by Swoole's Request.
return ['redirect' => 'https://github.com'];
});

/**
* Define example json response.
*/
$app->get('/json', function () {
// Correct headers will be added from Swoole's Response.
return ['json' => true];
});

$http = new Server('0.0.0.0', 9501);
$http = new Server('0.0.0.0', 8080, SWOOLE_PROCESS);
$http->on('start', function () {
echo "Swoole http server is started at http://127.0.0.1:9501\n";
echo "Swoole http server is started at http://127.0.0.1:8080\n";
});

$http->on('request', function (Request $request, Response $response) use ($app) {
$app->setService('request', new \Phalcon\Bridge\Swoole\Request($request));
$app->setService('response', new \Phalcon\Bridge\Swoole\Response($response));

/**
* Without fallback 404 handler it will crush.
*/
$app->notFound(function () use ($response) {
$response->setStatusCode(404, 'Not Found');
});

/**
* Handle in Phalcon the request and pick response content.
* Then pass to Swoole and end response.
*/
$content = $app->handle($request->server['request_uri']);
if (!empty($content['redirect'])) {
$response->redirect($content['redirect'], 301);
return;
}

if (isset($content['content'])) {
if (is_array($content['content'])) {
$response->setHeader('Content-Type', 'application/json');
$content = json_encode($content['content']);
} else {
$content = (string)$content['content'];
$http->on('request', function (Request $request, Response $response) {
$content = '';
try {
// Create a completely fresh app instance for each request
$app = new Micro();

// Setting up the database connection
$app['db'] = function () {
return new Mysql([
'host' => 'tfb-database',
'dbname' => 'hello_world',
'username' => 'benchmarkdbuser',
'password' => 'benchmarkdbpass',
'options' => [
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'",
PDO::ATTR_PERSISTENT => true,
],
]);
};

// Setting up the view component
$app['view'] = function () {
$view = new View();
$view->setViewsDir(__DIR__ . '/../app/views/');
$view->registerEngines([
".volt" => function ($view) {
$volt = new Volt($view);
$volt->setOptions([
"path" => __DIR__ . "/../app/compiled-templates/",
"extension" => ".c",
"separator" => '_',
]);
return $volt;
}
]);
return $view;
};

$app->notFound(function () use ($app) {
$app->response->setStatusCode(404, 'Not Found');
});
// Re-register all routes for each request
$app->map('/plaintext', function () use ($app) {
$app->response->setContentType('text/plain', 'UTF-8');
return "Hello, World!";
});

$app->map('/json', function () use ($app) {
$app->response->setContentType('application/json', 'UTF-8');
return json_encode(['message' => 'Hello, World!']);
});

$app->map('/db', function () use ($app) {
$db = $app['db'];
$world = $db->fetchOne('SELECT * FROM world WHERE id = ' . mt_rand(1, 10000), Enum::FETCH_ASSOC);
$app->response->setContentType('application/json', 'UTF-8');
return json_encode($world);
});

$app->map('/queries', function () use ($app) {
$db = $app['db'];
$queries = $app->request->getQuery('queries', "int", 1);
$queries = min(max(intval($queries), 1), 500);
$worlds = [];
for ($i = 0; $i < $queries; ++$i) {
$worlds[] = $db->fetchOne('SELECT * FROM world WHERE id = ' . mt_rand(1, 10000), Enum::FETCH_ASSOC);
}
$app->response->setContentType('application/json', 'UTF-8');
return json_encode($worlds);
});

$app->map('/fortunes', function () use ($app) {
$fortunes = $app['db']->query('SELECT * FROM fortune')->fetchAll();
$fortunes[] = [
'id' => 0,
'message' => 'Additional fortune added at request time.'
];
usort($fortunes, function ($left, $right) {
return $left['message'] <=> $right['message'];
});
$app->response->setContentType('text/html', 'UTF-8');
return $app['view']->getRender('bench', 'fortunes', [
'fortunes' => $fortunes,
]);
});

// Set up bridge objects
$phalconResponse = new \Phalcon\Bridge\Swoole\Response($response);
$phalconRequest = new \Phalcon\Bridge\Swoole\Request($request);

$app->setService('request', $phalconRequest);
$app->setService('response', $phalconResponse);

// Handle the request
$content = $app->handle($request->server['request_uri']);

// Get headers and status
$headers = $app->response->getHeaders();
$statusCode = $app->response->getStatusCode();

foreach ($headers->toArray() as $header => $value) {
$response->setHeader($header, $value);
}
}

$response->end($content);
$response->setStatusCode($statusCode ?? 200);
$response->end($content);
} catch (Exception $e) {
echo "Exception: ", $e->getMessage();
$response->setStatusCode(500);
$response->end($content);
}
});

$http->start();
```
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
}
],
"require": {
"php": ">=8.0",
"php": ">=8.4",
"ext-json": "*",
"ext-phalcon": "^5.1",
"ext-swoole": "^5.0"
"ext-phalcon": "^5.2",
"ext-swoole": "^6.0"
},
"require-dev": {
"phalcon/ide-stubs": "^5.1",
"swoole/ide-helper": "^5.0"
"phalcon/ide-stubs": "^5.9",
"swoole/ide-helper": "^6.0"
},
"config": {
"optimize-autoloader": true,
Expand Down
46 changes: 18 additions & 28 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions src/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function __construct(SwooleRequest $swooleRequest)
* @throws Exception
*/
public function get(
string $name = null,
?string $name = null,
$filters = null,
$defaultValue = null,
bool $notAllowEmpty = false,
Expand Down Expand Up @@ -143,7 +143,7 @@ public function getBestLanguage(): string
* `$_SERVER["REMOTE_ADDR"]` and optionally in
* `$_SERVER["HTTP_X_FORWARDED_FOR"]`
*/
public function getClientAddress(bool $trustForwardedHeader = false)
public function getClientAddress(bool $trustForwardedHeader = false): bool|string
{
return $this->swooleRequest->server['remote_addr'];
}
Expand Down Expand Up @@ -227,9 +227,9 @@ public function getHTTPReferer(): string
* Gets decoded JSON HTTP raw request body.
*
* @param bool $associative
* @return mixed
* @return array|bool|\stdClass
*/
public function getJsonRawBody(bool $associative = false): mixed
public function getJsonRawBody(bool $associative = false): array|bool|\stdClass
{
$rawBody = $this->getRawBody();

Expand Down Expand Up @@ -312,12 +312,12 @@ public function getURI(bool $onlyPath = false): string
* @throws Exception
*/
public function getPost(
string $name = null,
?string $name = null,
$filters = null,
$defaultValue = null,
bool $notAllowEmpty = false,
bool $noRecursive = false,
) {
): mixed {
return $this->getHelper($this->swooleRequest->post, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
}

Expand All @@ -341,12 +341,12 @@ public function getPost(
* @throws Exception
*/
public function getPut(
string $name = null,
?string $name = null,
$filters = null,
$defaultValue = null,
bool $notAllowEmpty = false,
bool $noRecursive = false,
) {
): mixed {
return $this->getHelper($this->swooleRequest->post, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
}

Expand All @@ -371,10 +371,10 @@ public function getPut(
* @param bool $notAllowEmpty
* @param bool $noRecursive
* @return mixed
* @throws Exception
* @throws \Exception
*/
public function getQuery(
string $name = null,
?string $name = null,
$filters = null,
$defaultValue = null,
bool $notAllowEmpty = false,
Expand Down Expand Up @@ -725,7 +725,7 @@ final protected function hasFileHelper(mixed $data, bool $onlySuccessful): int
* @param bool $notAllowEmpty
* @param bool $noRecursive
* @return mixed
* @throws Exception
* @throws \Exception
*/
final protected function getHelper(
array $source,
Expand Down