Skip to content

Commit

Permalink
Merge pull request #9553 from eoioer/master
Browse files Browse the repository at this point in the history
[PHP] Add cyberphp tests
  • Loading branch information
msmith-techempower authored Jan 20, 2025
2 parents 27012ed + d5f024c commit 0c959df
Show file tree
Hide file tree
Showing 20 changed files with 1,322 additions and 0 deletions.
26 changes: 26 additions & 0 deletions frameworks/PHP/cyberphp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# CyberPHP Benchmarking Test

## Test URLs
### JSON

http://localhost:8080/json

### PLAINTEXT

http://localhost:8080/plaintext

### DB

http://localhost:8080/db

### QUERY

http://localhost:8080/queries/[count]

### UPDATE

http://localhost:8080/updates/[count]

### FORTUNES

http://localhost:8080/fortunes
57 changes: 57 additions & 0 deletions frameworks/PHP/cyberphp/app/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
return [
'app_name' => 'Cyber',
// Request middleware runs after obtaining request body and before parsing route
// Mainly used for blacklist, whitelist, system maintenance, request filtering, data access, etc.
'request_middleware' => [
// \app\common\middleware\IpBlacklistMiddleware::class,// IP blacklist middleware
// \app\middleware\RateLimitMiddleware::class,// Rate limit middleware
// \app\middleware\SecurityMiddleware::class, // Security protection (CSRF/XSS filtering/SQL injection) middleware
],
// Business middleware runs after parsing route and before executing controller method
// Mainly used for common business such as user authentication
'middleware' => [
// \app\common\middleware\Route1Middleware::class,
// \app\common\middleware\Route2Middleware::class,
],
'orm' => 'pdo',
'pdo' => [
'dsn' => 'pgsql:host=tfb-database;dbname=hello_world',
'username' => 'benchmarkdbuser',
'password' => 'benchmarkdbpass',
'options' => [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,PDO::ATTR_EMULATE_PREPARES => false]
],
'eloquent' => [
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => 'lavaman',
'username' => 'root',
'password' => 'root',
'charset' => 'utf8mb4',
'prefix' => '',
],
'thinkorm' => [
'default' => 'mysql',
'connections' => [
'mysql' => [
'type' => 'mysql', // Database type
'hostname' => '127.0.0.1',// Server address
'database' => 'lavaman',// Database name
'username' => 'root',// Database username
'password' => 'root',// Database password
'hostport' => '',// Database connection port
'params' => [],
'charset' => 'utf8mb4',// Database encoding default utf8
'prefix' => '',// Table prefix
],
],
],
'cookie' => [
'expires' => 0,
'path' => '/',
'domain' => '',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax' // None, Lax, Strict
]
];
74 changes: 74 additions & 0 deletions frameworks/PHP/cyberphp/app/controller/Index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
namespace app\controller;

use Cyber\Response;
class Index {

public function json()
{
return Response::json(['message' => 'Hello, World!']);
}

public function plaintext()
{
return Response::text('Hello, World!');
}

public function db()
{
$prepare = app()->dbWorld;
$prepare->execute([mt_rand(1, 10000)]);
$data = $prepare->fetch();
return Response::json($data);
}
public function fortunes()
{
$fortune = app()->dbFortune;
$fortune->execute();
$arr = $fortune->fetchAll(\PDO::FETCH_KEY_PAIR);
$arr[0] = 'Additional fortune added at request time.';
\asort($arr);
$html = '';
foreach ($arr as $id => $message) {
$message = \htmlspecialchars($message, \ENT_QUOTES, 'UTF-8');
$html .= "<tr><td>$id</td><td>$message</td></tr>";
}
return Response::html("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>$html</table></body></html>");
}

public function queries($q=1)
{
$statement = app()->dbWorld;
$query_count = max(min(intval($q), 500), 1);
$arr = [];
while ($query_count--) {
$statement->execute([mt_rand(1, 10000)]);
$arr[] = $statement->fetch();
}
return Response::json($arr);
}

public function updates($q=1)
{
static $updates = [];

$random = app()->dbWorld;
$count = max(min(intval($q), 500), 1);

$worlds = $keys = $values = [];
for ($i = 0; $i < $count; ++ $i) {
$values[] = $keys[] = $id = mt_rand(1, 10000);
$random->execute([$id]);
$row = $random->fetch();
$values[] = $row['randomNumber'] = mt_rand(1, 10000);
$worlds[] = $row;
}
if (!isset($updates[$count])) {
$sql = 'UPDATE World SET randomNumber = CASE id' . str_repeat(' WHEN ?::INTEGER THEN ?::INTEGER ', $count) . 'END WHERE id IN (' . str_repeat('?::INTEGER,', $count - 1) . '?::INTEGER)';
$updates[$count] = app()->db->prepare($sql);
}
$updates[$count]->execute([...$values, ...$keys]);

return Response::json($worlds);
}
}
84 changes: 84 additions & 0 deletions frameworks/PHP/cyberphp/app/helpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
declare(strict_types=1);

/**
* Get the application instance
* If there is a configuration file, create the application instance
* If there is no configuration file, return the already created instance
* If there is no configuration file and no instance has been created, throw an exception
* @param string $bootstrap Configuration file
* @return \Cyber\App
*/
if (!function_exists('app')) {
function app(): \Cyber\App
{
return \Cyber\App::getInstance();
}
}

/**
* Get configuration information
* config(); // Returns all configurations
* config('app.name'); // Gets the value of app.name
* config('db.mysql.host'); // Gets the value of db.mysql.host
* @param string|null $key Configuration key name, supports multi-level configuration separated by dots, e.g., 'app.debug'
* @param mixed $default Default value, returned when the configuration item does not exist
* @return mixed
*/
if (!function_exists('config')) {
function config(?string $key = null, $default = null)
{
return \Cyber\App::getInstance()->getConfig($key) ?? $default;
}
}

function renderExceptionPage($e, $debug = true, $templateFile = ''): string
{
// Determine template path
$templateFile = !empty($templateFile) ? $templateFile : __DIR__ . '/views/errors/exception.html';
// Prepare template variables
$data = [
'code' => $e->getCode(),
'message' => $debug ? $e->getMessage() : 'The current server is experiencing an error, please contact the administrator or try again later.',
'error' => $e->getMessage(),
];
// Add more information in debug mode
if ($debug) {
$data['trace'] = [];
$data['file'] = $e->getFile();
$data['line'] = $e->getLine();
$traceFiles = $e->getTrace();
array_unshift($traceFiles, ['file' => $data['file'], 'line' => $data['line']]);
foreach ($traceFiles as $v) {
try {
if (isset($v['file']) && isset($v['line'])) {
$startline = max(1, $v['line'] - 10);
$contents = file($v['file']);
$data['trace'][] = [
'file' => $v['file'],
'line' => $v['line'],
'source0' => $contents ? array_slice($contents, 0, 1) : '',
'source' => [
'startline' => $startline,
'content' => array_slice($contents, $startline - 1, 16)
]
];
}
} catch (\Throwable $e) {
continue;
}
}
}
// Render error page
if (!file_exists($templateFile)) {
$msg = '<div style="margin:100px auto 20px;text-align:center"><h1>Error ' . $data['code'] . '</h1></div>';
$msg .= '<div style="margin:0px auto;text-align:center">Sorry, the server encountered an error</div>';
$msg .= '<div style="margin:50px auto;text-align:center"><h2><pre>' . htmlspecialchars($data['message']) . '</pre></h2></div>';
$msg .= '<div style="margin:100px auto;text-align:center"><a href="/"><button>Return to Home</button></a></div>';
return $msg;
}
extract($data);
ob_start();
include $templateFile;
return ob_get_clean();
}
14 changes: 14 additions & 0 deletions frameworks/PHP/cyberphp/app/route.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
use Cyber\Request;

return [
['/', 'GET', 'app\controller\Index@hello'],
['/json', 'GET', 'app\controller\Index@json'],
['/plaintext', 'GET', 'app\controller\Index@plaintext'],
['/db', 'GET', 'app\controller\Index@db'],
['/fortunes', 'GET', 'app\controller\Index@fortunes'],
['/queries/', 'GET', 'app\controller\Index@queries'],
['/queries/{q}', 'GET', 'app\controller\Index@queries'],
['/updates/', 'GET', 'app\controller\Index@updates'],
['/updates/{q}', 'GET', 'app\controller\Index@updates'],
];
62 changes: 62 additions & 0 deletions frameworks/PHP/cyberphp/app/views/errors/exception.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>An Error Occurred</title>
<style>
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;line-height:1.6;margin:0;padding:0;background:#f8f9fa;color:#343a40}
pre{margin:0;padding:0;}
.container{max-width:80%;margin:50px auto;padding:20px;background:#fff;border-radius:8px;box-shadow:0 2px 4px rgba(0,0,0,0.1)}
.error-code{font-size:72px;font-weight:bold;color:#dc3545;margin:0;line-height:1}
.error-title{font-size:24px;color:#495057;margin:20px 0}
.error-message{font-size:16px;color:#6c757d;margin-bottom:30px;padding:15px;background:#f8f9fa;border-radius:4px;border-left:4px solid #dc3545}
.back-link{display:inline-block;margin-top:20px;padding:10px 20px;background:#007bff;color:#fff;text-decoration:none;border-radius:4px;transition:background-color 0.2s}
.back-link:hover{background:#0056b3}

.source-box{margin:10px 0;padding:0px;}
.source-box a{color:#369;font-weight:900;}
.source-file{padding:5px 10px;background:#f8f9fa;}
.source-code{padding:4px 0px;border: 0px solid #ddd;background: #f1f2f3;overflow-x: auto;}
.source-code ol,.source-code ul{margin: 0;color: #555;font-size:14px;}
.source-code code{border-left: 1px solid #ccc;padding-left:5px;font-family: "Consolas";}
.source-error{color:#000;background:#dc354533!important}
.source-error code{font-weight:900;}
</style>
</head>
<body>
<div class="container">
<h1 class="error-code">Error <?php echo htmlspecialchars($code); ?></h1>
<h2 class="error-title">Sorry, an error occurred</h2>
<div class="error-message"><?php echo htmlspecialchars($message); ?></div>
<!-- <?php echo htmlspecialchars($error); ?> -->
<?php if (isset($trace)) { ?>
<?php foreach ($trace as $k => $v) { ?>
<div class="source-box">
<div class="source-file">#<?= $k ?> <a href="view-source:file:///<?php echo $v['file']; ?>"><?php echo $v['file']; ?></a> Line <?php echo $v['line']; ?></div>
<div class="source-code">
<pre><?php
if (!empty($v['source0'])) {
echo '<ol start="0"><li><code>'.htmlentities($v['source0'][0]).'</code></li></ol>';
}
if (!empty($v['source'])) {
echo '<ol start="'.htmlentities($v['source']['startline']).'">';
foreach ((array) $v['source']['content'] as $key => $value) {
if (($key + $v['source']['startline']) == $v['line']) {
echo '<li class="source-error"><code>'.htmlentities($value).'</code></li>';
} else {
echo '<li><code>'.htmlentities($value).'</code></li>';
}
}
echo '</ol>';
}
?></pre>
</div>
</div>
<?php } ?>
<?php } ?>
<a href="/" class="back-link">Return to Home</a>
</body>

</html>
30 changes: 30 additions & 0 deletions frameworks/PHP/cyberphp/benchmark_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"framework": "cyberphp",
"tests": [
{
"default": {
"json_url": "/json",
"db_url": "/db",
"query_url": "/queries/",
"fortune_url": "/fortunes",
"update_url": "/updates/",
"plaintext_url": "/plaintext",
"port": 8080,
"approach": "Realistic",
"classification": "Micro",
"database": "Postgres",
"framework": "cyberphp",
"language": "PHP",
"flavor": "PHP8",
"orm": "Raw",
"platform": "workerman",
"webserver": "None",
"os": "Linux",
"database_os": "Linux",
"display_name": "cyberphp",
"notes": "",
"versus": "workerman"
}
}
]
}
Loading

0 comments on commit 0c959df

Please sign in to comment.