Skip to content

Commit

Permalink
[php] Slim to v4, php8.1 and adapterman (#7660)
Browse files Browse the repository at this point in the history
* [php] Slim to v4

* Update to v4

* Add with adapterman
  • Loading branch information
joanhey authored Nov 2, 2022
1 parent 3eee10b commit 48a435f
Show file tree
Hide file tree
Showing 11 changed files with 467 additions and 63 deletions.
44 changes: 44 additions & 0 deletions frameworks/PHP/slim/benchmark_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,50 @@
"display_name": "slim",
"notes": "",
"versus": "php"
},
"workerman": {
"plaintext_url": "/plaintext",
"json_url": "/json",
"db_url": "/db",
"query_url": "/dbs?queries=",
"update_url": "/updates?queries=",
"fortune_url": "/fortunes",
"port": 8080,
"approach": "Realistic",
"classification": "Micro",
"database": "MySQL",
"framework": "slim",
"language": "PHP",
"flavor": "PHP8",
"orm": "Raw",
"platform": "workerman",
"webserver": "none",
"os": "Linux",
"database_os": "Linux",
"display_name": "slim-workerman",
"notes": "",
"versus": "php"
},
"workerman-pgsql": {
"db_url": "/db",
"query_url": "/dbs?queries=",
"update_url": "/updates?queries=",
"fortune_url": "/fortunes",
"port": 8080,
"approach": "Realistic",
"classification": "Micro",
"database": "postgres",
"framework": "slim",
"language": "PHP",
"flavor": "PHP8",
"orm": "Raw",
"platform": "workerman",
"webserver": "none",
"os": "Linux",
"database_os": "Linux",
"display_name": "slim-workerman-pgsql",
"notes": "Optimized for Workerman",
"versus": "php"
}
}]
}
12 changes: 10 additions & 2 deletions frameworks/PHP/slim/composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
{
"require": {
"slim/slim": "3.12.4",
"slim/php-view": "3.2.0"
"slim/slim": "^4.10",
"slim/php-view": "3.2.0",
"slim/psr7": "1.*",
"slim/http": "1.*",
"php-di/php-di": "^6.4"
},
"autoload": {
"psr-4": {
"Db\\": "db/"
}
}
}
92 changes: 92 additions & 0 deletions frameworks/PHP/slim/db/Raw.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php
namespace db;

use PDO;
use PDOStatement;

class Raw
{
private static PDO $instance;
public static PDOStatement $db;
public static PDOStatement $fortune;
public static PDOStatement $random;
/**
* @var []PDOStatement
*/
private static $update;

public static function init()
{
$pdo = new PDO(
'pgsql:host=tfb-database;dbname=hello_world',
'benchmarkdbuser',
'benchmarkdbpass',
[
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false
]
);

self::$fortune = $pdo->prepare('SELECT id,message FROM Fortune');
self::$random = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id = ?');
self::$instance = $pdo;
}

/**
* Postgres bulk update
*
* @param array $worlds
* @return void
*/
public static function update(array $worlds)
{
$rows = count($worlds);

if (!isset(self::$update[$rows])) {
$sql = 'UPDATE world SET randomNumber = CASE id'
. str_repeat(' WHEN ?::INTEGER THEN ?::INTEGER ', $rows)
. 'END WHERE id IN ('
. str_repeat('?::INTEGER,', $rows - 1) . '?::INTEGER)';

self::$update[$rows] = self::$instance->prepare($sql);
}

$val = [];
$keys = [];
foreach ($worlds as $world) {
$val[] = $keys[] = $world['id'];
$val[] = $world['randomNumber'];
}

self::$update[$rows]->execute([...$val, ...$keys]);
}

/**
* Alternative bulk update in Postgres
*
* @param array $worlds
* @return void
*/
public static function update2(array $worlds)
{
$rows = count($worlds);

if (!isset(self::$update[$rows])) {
$sql = 'UPDATE world SET randomNumber = temp.randomNumber FROM (VALUES '
. implode(', ', array_fill(0, $rows, '(?::INTEGER, ?::INTEGER)')) .
' ORDER BY 1) AS temp(id, randomNumber) WHERE temp.id = world.id';

self::$update[$rows] = self::$instance->prepare($sql);
}

$val = [];
foreach ($worlds as $world) {
$val[] = $world['id'];
$val[] = $world['randomNumber'];
//$update->bindParam(++$i, $world['id'], PDO::PARAM_INT);
}

self::$update[$rows]->execute($val);
}
}
16 changes: 16 additions & 0 deletions frameworks/PHP/slim/deploy/conf/cli-php.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.validate_timestamps=0
opcache.save_comments=0
opcache.enable_file_override=1
opcache.huge_code_pages=1

mysqlnd.collect_statistics = Off

memory_limit = 512M

opcache.jit_buffer_size = 128M
opcache.jit = tracing

disable_functions=header,header_remove,http_response_code,setcookie,session_create_id,session_id,session_name,session_save_path,session_status,session_start,session_write_close,session_regenerate_id,set_time_limit
116 changes: 65 additions & 51 deletions frameworks/PHP/slim/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,72 @@

require_once __DIR__.'/vendor/autoload.php';

$app = new Slim\App(array(
'db' => function ($c) {
$pdo = new PDO('mysql:host=tfb-database;dbname=hello_world;charset=utf8', 'benchmarkdbuser', 'benchmarkdbpass', array(
PDO::ATTR_PERSISTENT => true,
));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

return $pdo;
},

'view' => function ($c) {
return new Slim\Views\PhpRenderer("templates/");
}
));
use DI\Container;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Slim\Views\PhpRenderer;

//global $app; // workerman

$container = new Container();

$container->set('db', new PDO(
'mysql:host=tfb-database;dbname=hello_world;charset=utf8',
'benchmarkdbuser',
'benchmarkdbpass',
[
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
//PDO::ATTR_EMULATE_PREPARES => false, // workerman
]));

$container->set('view', new PhpRenderer('templates'));

AppFactory::setContainer($container);
$app = AppFactory::create();


// Test 1: Plaintext
$app->get('/plaintext', function ($request, $response) {
return $response
$app->get('/plaintext', fn(Request $request, Response $response) =>
$response
->write('Hello, World!')
->withHeader('Content-Type', 'text/plain')
;
});
);

// Test 2: JSON serialization
$app->get('/json', function ($request, $response) {
return $response
->withJson(array('message' => 'Hello, World!'))
->withHeader('Content-Type', 'application/json') // fixes utf-8 warning
;
});
$app->get('/json', fn(Request $request, Response $response) =>
$response
->withJson(['message' => 'Hello, World!'])
);

// Test 3: Single database query
$app->get('/db', function ($request, $response) {
$sth = $this->db->prepare('SELECT * FROM World WHERE id = ?');
$sth->execute(array(mt_rand(1, 10000)));
$app->get('/db', function (Request $request, Response $response) {
$sth = $this->get('db')->prepare('SELECT * FROM World WHERE id = ?');
$sth->execute([mt_rand(1, 10000)]);
$world = $sth->fetch();
# Cast fields to int so they don't get wrapped with quotes
$world['id'] = (int) $world['id'];
$world['randomNumber'] = (int) $world['randomNumber'];

return $response
->withJson($world)
->withHeader('Content-Type', 'application/json') // fixes utf-8 warning
;
->withJson($world);
});

// Test 4: Multiple database queries
$app->get('/dbs', function ($request, $response) {
$app->get('/dbs', function (Request $request, Response $response) {
$queries = $request->getParam('queries');
if (is_numeric($queries)) {
$queries = max(1, min($queries, 500));
} else {
$queries = 1;
}

$sth = $this->db->prepare('SELECT * FROM World WHERE id = ?');
$worlds = array();
$sth = $this->get('db')->prepare('SELECT * FROM World WHERE id = ?');
$worlds = [];
for ($i = 0; $i < $queries; ++$i) {
$sth->execute(array(mt_rand(1, 10000)));
$sth->execute([mt_rand(1, 10000)]);
$world = $sth->fetch();
# Cast fields to int so they don't get wrapped with quotes
$world['id'] = (int) $world['id'];
Expand All @@ -71,52 +77,60 @@
}

return $response
->withJson($worlds)
->withHeader('Content-Type', 'application/json') // fixes utf-8 warning
;
->withJson($worlds);
});

// Test 5: Updates
$app->get('/updates', function ($request, $response) {
$app->get('/updates', function (Request $request, Response $response) {
$queries = $request->getParam('queries');
if (is_numeric($queries)) {
$queries = max(1, min($queries, 500));
} else {
$queries = 1;
}

$sth = $this->db->prepare('SELECT * FROM World WHERE id = ?');
$updateSth = $this->db->prepare('UPDATE World SET randomNumber = ? WHERE id = ?');
$sth = $this->get('db')->prepare('SELECT * FROM World WHERE id = ?');
$updateSth = $this->get('db')->prepare('UPDATE World SET randomNumber = ? WHERE id = ?');

$worlds = array();
$worlds = [];
for ($i = 0; $i < $queries; ++$i) {
$id = mt_rand(1, 10000);
$random_number = mt_rand(1, 10000);
$sth->execute(array($id));
$sth->execute([$id]);
$world = $sth->fetch();
# Cast fields to int so they don't get wrapped with quotes
$world['id'] = (int) $world['id'];
$world['randomNumber'] = $random_number;

$updateSth->execute(array($world['randomNumber'], $world['id']));
$updateSth->execute([$world['randomNumber'], $world['id']]);

$worlds[] = $world;
}

return $response
->withJson($worlds)
->withHeader('Content-Type', 'application/json') // fixes utf-8 warning
;
->withJson($worlds);
});

// Test 6: Fortunes
$app->get('/fortunes', function ($request, $response) {
$fortunes = $this->db->query('SELECT * FROM Fortune')->fetchAll(PDO::FETCH_KEY_PAIR);
$app->get('/fortunes', function (Request $request, Response $response) {
$fortunes = $this->get('db')->query('SELECT * FROM Fortune')->fetchAll(PDO::FETCH_KEY_PAIR);

$fortunes[0] = 'Additional fortune added at request time.';
asort($fortunes);

return $this->view->render($response, "fortunes.php", ["fortunes" => $fortunes]);
return $this->get('view')->render($response, 'fortunes.php', ['fortunes' => $fortunes]);
});

$app->run();
$app->run(); // comented with workerman

// used by Workerman
function run(): string
{
global $app;
ob_start();

$app->run();
header(HeaderDate::$date); // To pass the bench, nginx auto add it

return ob_get_clean();
}
Loading

0 comments on commit 48a435f

Please sign in to comment.