diff --git a/frameworks/PHP/cyberphp/README.md b/frameworks/PHP/cyberphp/README.md deleted file mode 100755 index bc25c16fc20..00000000000 --- a/frameworks/PHP/cyberphp/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# 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 diff --git a/frameworks/PHP/cyberphp/app/config.php b/frameworks/PHP/cyberphp/app/config.php deleted file mode 100644 index ba727ea087a..00000000000 --- a/frameworks/PHP/cyberphp/app/config.php +++ /dev/null @@ -1,57 +0,0 @@ - '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 - ] -]; \ No newline at end of file diff --git a/frameworks/PHP/cyberphp/app/controller/Index.php b/frameworks/PHP/cyberphp/app/controller/Index.php deleted file mode 100644 index b1466094bab..00000000000 --- a/frameworks/PHP/cyberphp/app/controller/Index.php +++ /dev/null @@ -1,74 +0,0 @@ - '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 .= "$id$message"; - } - return Response::html("Fortunes$html
idmessage
"); - } - - 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); - } -} diff --git a/frameworks/PHP/cyberphp/app/helpers.php b/frameworks/PHP/cyberphp/app/helpers.php deleted file mode 100644 index 0b55349f7e3..00000000000 --- a/frameworks/PHP/cyberphp/app/helpers.php +++ /dev/null @@ -1,84 +0,0 @@ -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 = '

Error ' . $data['code'] . '

'; - $msg .= '
Sorry, the server encountered an error
'; - $msg .= '

' . htmlspecialchars($data['message']) . '

'; - $msg .= '
'; - return $msg; - } - extract($data); - ob_start(); - include $templateFile; - return ob_get_clean(); -} \ No newline at end of file diff --git a/frameworks/PHP/cyberphp/app/route.php b/frameworks/PHP/cyberphp/app/route.php deleted file mode 100644 index e224ec394c3..00000000000 --- a/frameworks/PHP/cyberphp/app/route.php +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - An Error Occurred - - - -
-

Error

-

Sorry, an error occurred

-
- - - $v) { ?> -
-
# Line
-
-
  • '.htmlentities($v['source0'][0]).'
  • '; - } - if (!empty($v['source'])) { - echo '
      '; - foreach ((array) $v['source']['content'] as $key => $value) { - if (($key + $v['source']['startline']) == $v['line']) { - echo '
    1. '.htmlentities($value).'
    2. '; - } else { - echo '
    3. '.htmlentities($value).'
    4. '; - } - } - echo '
    '; - } - ?>
    -
    -
    - - - Return to Home - - - \ No newline at end of file diff --git a/frameworks/PHP/cyberphp/benchmark_config.json b/frameworks/PHP/cyberphp/benchmark_config.json deleted file mode 100755 index 689f889ef03..00000000000 --- a/frameworks/PHP/cyberphp/benchmark_config.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "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" - } - } - ] -} diff --git a/frameworks/PHP/cyberphp/bootstrap.php b/frameworks/PHP/cyberphp/bootstrap.php deleted file mode 100644 index f9d1a350d25..00000000000 --- a/frameworks/PHP/cyberphp/bootstrap.php +++ /dev/null @@ -1,41 +0,0 @@ - __DIR__ .'/app/route.php', - - // Application configuration file location can be modified freely - - // Key represents the name of the sub-application; sub-applications not listed cannot be accessed - 'config' => [ - // Default configuration - '' => require 'app/config.php', - // If a sub-application does not mention a configuration, the content of the default configuration file will be used - // 'admin'=> (require 'app/admin/config.php') + (require 'app/config.php'), - - // Or only use the default configuration - // 'phone'=> require 'app/config.php', - - // Or do not use the default configuration, directly use your custom sub-application configuration, you can change the name freely - // 'phone'=> require 'app/config_phone.php', - - // Or this way, each configuration item is introduced separately - // 'admin'=> [ - // 'app_name' => 'admin', - // 'request_middleware' => require 'app/admin/config_request_middleware.php', - // 'middleware' => require 'app/admin/config_middleware.php', - // 'database' => require 'app/admin/config_database.php', - // 'cookie' => require 'app/admin/config_cookie.php', - // 'database' => require 'app/admin/config_database.php', - // ], - ], - - // Create route manager - 'Route' => \DI\create(\Cyber\Route::class), - 'Middleware' => \DI\create(\Cyber\Middleware::class), - - // Create request object for handling HTTP requests - 'Request' => \DI\create(\Cyber\Request::class), - // Create response object for generating HTTP responses - 'Response' => \DI\create(\Cyber\Response::class), -]; \ No newline at end of file diff --git a/frameworks/PHP/cyberphp/composer.json b/frameworks/PHP/cyberphp/composer.json deleted file mode 100644 index 68678af9697..00000000000 --- a/frameworks/PHP/cyberphp/composer.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "eoioer/cyberphp", - "authors": [ - { - "name": "eoioer", - "email": "eoioer@qq.com" - } - ], - "type": "project", - "description": "The Fastest and Smallest PHP Framework", - "license": "MIT", - "require": { - "php": ">=8.3", - "php-di/php-di": "^7.0", - "nikic/fast-route": "^1.3", - "workerman/workerman": "^4.1" - }, - "autoload": { - "psr-4": { - "app\\": "app/", - "Cyber\\": "src/" - }, - "files": [ - "app/helpers.php" - ] - }, - "minimum-stability": "stable", - "prefer-stable": true -} diff --git a/frameworks/PHP/cyberphp/cyberphp.dockerfile b/frameworks/PHP/cyberphp/cyberphp.dockerfile deleted file mode 100644 index e1c91791a05..00000000000 --- a/frameworks/PHP/cyberphp/cyberphp.dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -FROM ubuntu:24.04 - -ENV TEST_TYPE default - -ARG DEBIAN_FRONTEND=noninteractive - -RUN apt-get update -yqq && apt-get install -yqq software-properties-common > /dev/null -RUN LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php > /dev/null && \ - apt-get update -yqq > /dev/null && apt-get upgrade -yqq > /dev/null - -RUN apt-get install -yqq php8.4-cli php8.4-pgsql php8.4-xml > /dev/null - -COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer - -RUN apt-get update -yqq && apt-get install -y php-pear php8.4-dev libevent-dev git > /dev/null -RUN pecl install event-3.1.4 > /dev/null && echo "extension=event.so" > /etc/php/8.4/cli/conf.d/30-event.ini - -WORKDIR /cyberphp -COPY --link . . - -RUN composer install --optimize-autoloader --classmap-authoritative --no-dev --quiet -COPY php.ini /etc/php/8.4/cli/conf.d/10-opcache.ini - -EXPOSE 8080 - -CMD php /cyberphp/server.php start \ No newline at end of file diff --git a/frameworks/PHP/cyberphp/php.ini b/frameworks/PHP/cyberphp/php.ini deleted file mode 100644 index f4817cc9e3a..00000000000 --- a/frameworks/PHP/cyberphp/php.ini +++ /dev/null @@ -1,11 +0,0 @@ -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 \ No newline at end of file diff --git a/frameworks/PHP/cyberphp/public/favicon.ico b/frameworks/PHP/cyberphp/public/favicon.ico deleted file mode 100644 index ada4d61b845..00000000000 Binary files a/frameworks/PHP/cyberphp/public/favicon.ico and /dev/null differ diff --git a/frameworks/PHP/cyberphp/public/index.php b/frameworks/PHP/cyberphp/public/index.php deleted file mode 100644 index cbfd55373c0..00000000000 --- a/frameworks/PHP/cyberphp/public/index.php +++ /dev/null @@ -1,23 +0,0 @@ -run(); - if (!$response instanceof Response) { - $response = Response::html($response ?? ''); - } - echo $response->send(); -} catch (Exception $e) { - echo renderExceptionPage($e); -} catch (Throwable $e) { - echo renderExceptionPage($e); -} diff --git a/frameworks/PHP/cyberphp/server.php b/frameworks/PHP/cyberphp/server.php deleted file mode 100644 index e9a354b2ce9..00000000000 --- a/frameworks/PHP/cyberphp/server.php +++ /dev/null @@ -1,85 +0,0 @@ -count = 4; - -// Initialize ThinkPHP application -$app = \Cyber\App::bootstrap(__DIR__.'/bootstrap.php'); - -/** - * Callback function to handle HTTP requests - * @param TcpConnection $connection Client connection object - * @param WorkermanRequest $request HTTP request object - */ -$http_worker->onMessage = function(TcpConnection $connection, WorkermanRequest $request) use ($app) { - // Initialize request object - $_GET = $request->get(); // Get GET parameters - $_POST = $request->post(); // Get POST parameters - $_FILES = $request->file(); // Get file uploads - $_COOKIE = $request->cookie(); // Get COOKIE - - // Merge server variables - $_SERVER = array_merge($_SERVER, [ - 'RAW_BODY' => $request->rawBody(), // Raw request body - 'REQUEST_METHOD' => $request->method(), // Request method - 'REQUEST_URI' => $request->uri(), // Request URI - 'QUERY_STRING' => $request->queryString(), // Query string - 'REMOTE_ADDR' => $connection->getRemoteIp(), // Client IP - 'REMOTE_PORT' => $connection->getRemotePort(), // Client port - 'SERVER_PROTOCOL' => 'HTTP/'.$request->protocolVersion(), // Protocol version - ]); - - // Handle request headers - foreach ($request->header() as $key => $value) { - $_SERVER['HTTP_' . strtoupper(str_replace('-', '_', $key))] = $value; - } - - try { - ob_start(); // Start output buffering - $response = $app->run(); // Run ThinkPHP application - - // Handle response - if(!$response instanceof Response){ - // If not a Response object, directly output content - echo $response; - $content = ob_get_clean(); - $connection->send($content); - }else{ - // If it is a Response object, send HTTP response - echo $response->send(); - $content = ob_get_clean(); - $connection->send(new Workerman\Protocols\Http\Response( - $response->getStatusCode(), // Status code - $response->getHeaders(), // Response headers - $content // Response content - )); - } - } catch (Exception $e) { - // Catch exceptions and render error page - $connection->send(renderExceptionPage($e)); - } catch (Throwable $e) { - // Catch all errors - $connection->send(renderExceptionPage($e)); - } -}; - -/** - * Run all Worker instances - * This method will block the current process until all Workers stop - */ -Worker::runAll(); diff --git a/frameworks/PHP/cyberphp/src/App.php b/frameworks/PHP/cyberphp/src/App.php deleted file mode 100644 index 288e969e0a9..00000000000 --- a/frameworks/PHP/cyberphp/src/App.php +++ /dev/null @@ -1,154 +0,0 @@ -start_time = time(); - - /* Build container instance */ - $this->container = new Container($containerConfig); - - /* Load route configuration */ - $routes = require $this->container->get('route_path'); - /* Create route manager */ - $this->route = $this->container->get('Route'); - /* Call route dispatcher */ - $this->route->dispatcher($routes); - - /* Configuration */ - $this->config = $this->container->get('config'); - /* Request object */ - $this->request = $this->container->get('Request'); - - /* Database */ - $pdo = new PDO(...$this->getConfig('pdo')); - $this->db = $pdo; - $this->dbWorld = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id=?'); - $this->dbFortune = $pdo->prepare('SELECT id,message FROM Fortune'); - - } - /** - * Run application - */ - public function run() - { - $this->timestamps = time(); - /* cli mode maintains database connection */ - if (php_sapi_name() === 'cli' and time() - $this->start_time > 1) { - $this->start_time = time(); - $pdo = new PDO(...$this->getConfig('pdo')); - $this->db = $pdo; - $this->dbWorld = $pdo->prepare('SELECT id,randomNumber FROM World WHERE id=?'); - $this->dbFortune = $pdo->prepare('SELECT id,message FROM Fortune'); - } - - /* Return response */ - return $this->route->handleRoute(); - } - - /** - * Get the current application configuration - * $app->getConfig(); // Returns the entire configuration content of the current application - * $app->getConfig('app_name'); // Get the value of ['app_name'] in the current application configuration - * $app->getConfig('cookie.expires'); // Get the value of ['cookie']['expires'] - * $app->getConfig(null, 'admin'); // Returns the entire configuration content of the admin application - * $app->getConfig('app_name', 'admin'); // Get the value of ['app_name'] in the admin application configuration - * $app->getConfig('cookie.expires','admin'); // Get the value of ['cookie']['expires'] in the admin application configuration - */ - public function getConfig($key = null, $appName = null): mixed - { - $appName = $appName ?? $this->appName ?? ''; - $config = $this->config[$appName] ?? null; - // Get the entire application configuration - if ($key === null) { - return $config; - } - // Split the key into an array - $keys = explode('.', $key); - // Traverse the key array and get the configuration layer by layer - foreach ($keys as $k) { - if (is_array($config) && array_key_exists($k, $config)) { - $config = $config[$k]; - } else { - return null; // If a layer does not exist, return null - } - } - return $config; // Return the final configuration value - } - /** - * Initialize the application - * @param string $bootstrap Configuration file - * @return self - */ - public static function bootstrap($bootstrap = null): self - { - if (!$bootstrap) { - throw new \Exception('App::bootstrap parameter does not exist'); - } - if (self::$instance === null) { - /* Load container configuration file */ - if (!file_exists($bootstrap) || !is_readable($bootstrap)) { - throw new \Exception("App::bootstrap parameter {$bootstrap} path error"); - } - $containerConfig = require_once $bootstrap; - self::$instance = new self($containerConfig); - return self::$instance; - }else{ - throw new \Exception('Application has started'); - } - } - /** - * Get the application singleton instance - * @return self - */ - public static function getInstance(): self - { - if (self::$instance === null) { - throw new \Exception('Application has not started'); - } - return self::$instance; - } -} diff --git a/frameworks/PHP/cyberphp/src/Middleware.php b/frameworks/PHP/cyberphp/src/Middleware.php deleted file mode 100644 index c482ebe1347..00000000000 --- a/frameworks/PHP/cyberphp/src/Middleware.php +++ /dev/null @@ -1,48 +0,0 @@ -request; - foreach ($requestMiddlewares as $middleware) { - if (!class_exists($middleware)) { - throw new \Exception("The parameter class {$middleware} for processing the request middleware does not exist"); - } - $instance = app()->container->get($middleware); - if (!method_exists($instance, 'handle')) { - throw new \Exception("The parameter class {$middleware} for processing the request middleware does not have a handle method"); - } - /* Call the handle method of the request data middleware */ - $request = $instance->handle($request); - } - return $request; - } - - public function handle(array $Middlewares, callable $finalHandler) - { - $request = app()->request; - $container = app()->container; - // Start wrapping the handler from the last middleware layer by layer - $response = array_reduce( - array_reverse($Middlewares), - function($next, $middleware) use ($request,$container) { - if (!class_exists($middleware)) { - throw new \Exception("The middleware parameter class {$middleware} does not exist"); - } - $instance = $container->get($middleware); - if (!method_exists($instance, 'handle')) { - throw new \Exception("The middleware parameter class {$middleware} does not have a handle method"); - } - return function() use ($instance, $request, $next) { - return $instance->handle($request, $next); - }; - }, - $finalHandler - ); - // Execute the middleware chain - return $response(); - } -} \ No newline at end of file diff --git a/frameworks/PHP/cyberphp/src/Request.php b/frameworks/PHP/cyberphp/src/Request.php deleted file mode 100644 index ec54d88b94c..00000000000 --- a/frameworks/PHP/cyberphp/src/Request.php +++ /dev/null @@ -1,232 +0,0 @@ - $value) { - if (strpos($key, 'HTTP_') === 0) { - $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5))))); - $headers[$key] = $value; - } - } - ksort($headers); - return $headers; - } - return $_SERVER['HTTP_'.strtoupper(str_replace('-', '_', $key))] ?? $default; - } - /** - * Set request header - * @param string $key Header information name - * @param string $value Header information value - * @return void - */ - public function setHeader(string $key, string $value): void - { - if(is_array($key)){ - foreach ($key as $k => $v) { - $_SERVER['HTTP_' . strtoupper(str_replace('-', '_', $k))] = $v; - } - }else{ - $_SERVER['HTTP_' . strtoupper(str_replace('-', '_', $key))] = $value; - } - } -} diff --git a/frameworks/PHP/cyberphp/src/Response.php b/frameworks/PHP/cyberphp/src/Response.php deleted file mode 100644 index d2b689aacdb..00000000000 --- a/frameworks/PHP/cyberphp/src/Response.php +++ /dev/null @@ -1,218 +0,0 @@ - 'OK', - 201 => 'Created', - 204 => 'No Content', - - // 3xx Redirection - 301 => 'Moved Permanently', - 302 => 'Found', - 304 => 'Not Modified', - - // 4xx Client Errors - 400 => 'Bad Request', - 401 => 'Unauthorized', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 408 => 'Request Timeout', - 422 => 'Unprocessable Entity', - 429 => 'Too Many Requests', - - // 5xx Server Errors - 500 => 'Internal Server Error', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout' - ]; - - protected string $content = ''; - protected int $statusCode = 200; - protected array $headers = []; - protected bool $sent = false; - - public function __construct(string $content = '', int $statusCode = 200, array $headers = []) - { - $this->content = $content; - $this->statusCode = $statusCode; - $this->headers = $headers; - } - - /** - * Get status code description - */ - public function getStatusText(): string - { - return self::HTTP_STATUS[$this->statusCode]; - } - /** - * Get response body - */ - public function getStatusCode(): int - { - return $this->statusCode; - } - /** - * Get response body - */ - public function getContent(): string - { - return $this->content; - } - - /** - * Get all response headers - */ - public function getHeaders(): array - { - return $this->headers; - } - - /** - * Add response header - * - * @throws Exception - */ - public function withHeader(string $name, string|array $value): static - { - // Validate header name legality - if (!preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/', $name)) { - throw new Exception('Header name can only contain letters, numbers, and special characters'); - } - if (empty($name)) { - throw new Exception('Header name cannot be empty'); - } - - $clone = clone $this; - $clone->headers[$name] = is_array($value) ? $value : [$value]; - return $clone; - } - - /** - * Add multiple response headers - */ - public function withHeaders(array $headers): static - { - $clone = clone $this; - foreach ($headers as $name => $value) { - $clone = $clone->withHeader($name, $value); - } - return $clone; - } - - /** - * Create JSON response - * - * @throws Exception - */ - public static function json(mixed $data, int $status = 200, array $headers = []): static - { - try { - $json = json_encode($data, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE); - } catch (\JsonException $e) { - throw new Exception('Unable to encode data to JSON', 0, $e); - } - - $headers['Content-Type'] = 'application/json; charset=utf-8'; - $headers['Date'] = gmdate(DATE_RFC7231); - return new static($json, $status, $headers); - } - - /** - * Create HTML response - */ - public static function html(string $html, int $status = 200, array $headers = []): static - { - $headers['Content-Type'] = 'text/html; charset=utf-8'; - $headers['Date'] = gmdate(DATE_RFC7231); - return new static($html, $status, $headers); - } - - /** - * Create text response - */ - public static function text(string $text, int $status = 200, array $headers = []): static - { - $headers['Content-Type'] = 'text/plain; charset=utf-8'; - $headers['Date'] = gmdate(DATE_RFC7231); - return new static($text, $status, $headers); - } - /** - * Create file response - */ - public static function file(string $file, string $filename, int $status = 200, array $headers = []): static - { - $headers['Content-Type'] = 'application/octet-stream'; - $headers['Date'] = gmdate(DATE_RFC7231); - $headers['Content-Disposition'] = 'attachment; filename="' . $filename . '"'; - return new static(file_get_contents($file), $status, $headers); - } - - /** - * Create redirect response - * - * @throws Exception - */ - public static function redirect(string $url, int $status = 302, array $headers = []): static - { - if (!filter_var($url, FILTER_VALIDATE_URL) && !str_starts_with($url, '/')) { - throw new Exception('Invalid URL format'); - } - return new static('', $status, array_merge($headers, ['Location' => $url])); - } - - /** - * Send response - * - * @throws Exception - */ - public function send(): void - { - if ($this->isSent()) { - throw new Exception('Response already sent'); - } - if (!headers_sent()) { - // // 发送状态码 - http_response_code($this->statusCode); - - // // 确保有 Content-Type 头 - if (!isset($this->headers['Content-Type'])) { - $this->headers['Content-Type'] = ['text/html; charset=utf-8']; - } - - // // 发送响应头 - foreach ($this->headers as $name => $values) { - $values = (array) $values; - foreach ($values as $value) { - header($name . ': ' . $value, false); - } - } - } - - // // 发送响应内容 - echo $this->content; - - // $this->sent = true; - } - - /** - * Check if the response has been sent - */ - public function isSent(): bool - { - return $this->sent; - } -} diff --git a/frameworks/PHP/cyberphp/src/Route.php b/frameworks/PHP/cyberphp/src/Route.php deleted file mode 100644 index b1b70f4f873..00000000000 --- a/frameworks/PHP/cyberphp/src/Route.php +++ /dev/null @@ -1,61 +0,0 @@ -dispatcher = FastRoute\simpleDispatcher(function (RouteCollector $r) use ($routes) { - foreach ($routes as $route) { - // Check the number of array members. Three members indicate a single route configuration. - if (count($route) == 3) { - $r->addRoute(preg_split('/\s*,\s*/', $route[1]), $route[0], $route[2]); - // Two members indicate a group route. - } elseif (count($route) == 2) { - $r->addGroup($route[0], function (RouteCollector $r) use ($route) { - foreach ($route[1] as $childRoute) { - $r->addRoute(preg_split('/\s*,\s*/', trim($childRoute[1])), $childRoute[0], $childRoute[2]); - } - }); - } - } - }); - } - public function handleRoute() - { - $request = app()->request; - $container = app()->container; - // Parse the current route - $routeInfo = $this->dispatcher->dispatch($request->getMethod(), $request->getPathInfo()); - if ($routeInfo[0] == 0) { - throw new \Exception('Page not found', 404); - } elseif ($routeInfo[0] == 2) { - throw new \Exception('Request method error', 405); - } elseif ($routeInfo[0] == 1) { - $handler = $routeInfo[1]; - $vars = $routeInfo[2]; - $parameters = [...array_values($vars)]; - - // Create a closure to pass to your middleware to execute the final handler - $finalHandler = function() use ($handler, $parameters, $container) { - // If handler is a string (controller@method) - if (is_string($handler)) { - list($controller, $method) = explode('@', $handler); - $ctrl = $container->get($controller); - return $ctrl->$method(...$parameters); - } elseif (is_callable($handler)) { - return $handler(...$parameters); - } else { - throw new \Exception('Route handler configuration error'); - } - }; - return $finalHandler(); - } - } -} \ No newline at end of file diff --git a/frameworks/PHP/cyberphp/src/Utility.php b/frameworks/PHP/cyberphp/src/Utility.php deleted file mode 100644 index 17ab3948176..00000000000 --- a/frameworks/PHP/cyberphp/src/Utility.php +++ /dev/null @@ -1,47 +0,0 @@ - 'Handling JSON data', - 'mbstring' => 'Handling multibyte strings', - 'pdo' => 'Database connection', - 'pdo_mysql' => 'MySQL database support', - 'openssl' => 'Encryption and HTTPS support' - ]; - // Check required extensions - $missingExtensions = []; - foreach ($requiredExtensions as $extension => $purpose) { - if (!extension_loaded($extension)) { - $missingExtensions[] = sprintf( - "- %s (%s)", - $extension, - $purpose - ); - } - } - // If there are missing required extensions, throw an exception - if (!empty($missingExtensions)) { - throw new \Exception(sprintf( - "Missing required PHP extensions:\n%s\nPlease install these extensions before running the program.", - implode("\n", $missingExtensions) - )); - } - return true; - } -}