Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PHP] Add cyberphp tests #9553

Merged
merged 6 commits into from
Jan 20, 2025
Merged
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
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
Loading