Closed Nyxalis closed 1 month ago
I kinda had AI help with this since I had 0 idea but it works!!
/bootstrap/app.php
<?php
function config($key = null, $default = null) {
static $config = [];
if (empty($config)) {
foreach (glob(__DIR__ . '/../config/*.php') as $file) {
$name = basename($file, '.php');
$config[$name] = require $file;
}
}
if (is_null($key)) {
return $config;
}
$keys = explode('.', $key);
$result = $config;
foreach ($keys as $keyPart) {
if (isset($result[$keyPart])) {
$result = $result[$keyPart];
} else {
return $default;
}
}
return $result;
}
/public/index.php
<?php
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../bootstrap/app.php';
use Dumbo\Dumbo;
$app = new Dumbo();
/**
* All Routes will be imported into here.
* Each Route File will have it's work prefix endpoint
*/
require_once '../router/api.php';
//require_once '../router/web.php';
$app->run();
api.php
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use Dumbo\Dumbo;
use App\Controllers\UserController;
use Dumbo\Helpers\BearerAuth;
// $token = "mysupersecret";
// $app->use(BearerAuth::bearerAuth($token));
$protectedRoutes = new Dumbo();
$protectedRoutes->get("/", function ($c) {
return $c->json(
[
"message" => "Welcome to the protected routes!",
"dbhost" => config('database.dbhost'),
"redishost" => config('redis.dbhost')
]
);
});
@Nyxalis Yeah it will be helpful. We can work on this if @notrab agrees. If you need any help, I am here. I know Laravel as I work mostly with it.
I like the thought behind this, but coming from a JS and Hono world (please correct me if I'm wrong) but I think this could be done another way.
I don't think it's clear from the docs, but you can use get
and set
on the $context
to store your own stuff, like this:
<?php
$app = new Dumbo();
// Set configuration values
$app->set('DB_URL', 'mysql://user:pass@localhost/mydb');
$app->set('API_KEY', 'your-secret-key');
$app->set('DEBUG', true);
// Get configuration values
$dbUrl = $app->get('DB_URL');
$apiKey = $app->get('API_KEY');
$debug = $app->get('DEBUG');
// Use configuration in your routes
$app->get('/api/data', function(Context $ctx) {
$apiKey = $ctx->get('API_KEY');
// Use $apiKey in your logic...
return $ctx->json(['message' => 'API key is set']);
});
$app->run();
Would this be enough to achieve what you're looking to do?
In JS land we have the the dotenv
package which loads various different environment variables depending on the runtime. You can even pass it .env.development
and .env.production
to simulate the different environments. Does PHP let us do this?
@notrab Having different enviroments definitely possible. Can't the get and set method be used config files? Since I don't think everything should be in an .env
file.
For example, config for authentication for password hashing or something like that, being in a config php file and returning the values like this:
return [
'hash' => 'something'
'password_min' => 9
]
The Get and Set could be used within this
return [
'dbhost' => $app-get('DBHOST)
]
Or something similar.
@notrab the set()
method is undefined and I dance for that. The set()
method is defined inside the Context
but not in Dumbo
class.
To make it work, add this inside the Dumbo
class
<?php
class Dumbo
{
+ /** @var array<string, mixed> Variables stored in the context */
+ private $configs = [];
+
+ public function set(string $key, $value): void
+ {
+ $this->configs[$key] = $value;
+ }
+
+ public function getConfig(): array
+ {
+ return $this->configs;
+ }
+
public function handle(ServerRequestInterface $request): ResponseInterface
{
if ($this->removeTrailingSlash) {
$uri = $request->getUri();
$path = $uri->getPath();
if (strlen($path) > 1 && substr($path, -1) === "/") {
$newPath = rtrim($path, "/");
$newUri = $uri->withPath($newPath);
return new Response(301, ["Location" => (string) $newUri]);
}
}
try {
$route = $this->router->findRoute($request);
$context = new Context(
$request,
$route ? $route["params"] : [],
$route ? $route["routePath"] : "",
+ $this->getConfig()
);
$fullMiddlewareStack = $this->getFullMiddlewareStack();
if ($route) {
$fullMiddlewareStack = array_unique(
array_merge(
$fullMiddlewareStack,
$route["middleware"] ?? []
),
SORT_REGULAR
);
$handler = $route["handler"];
} else {
$handler = function () {
return new Response(404, [], "404 Not Found");
};
}
$response = $this->runMiddleware(
$context,
$handler,
$fullMiddlewareStack
);
return $response instanceof ResponseInterface
? $response
: $context->getResponse();
} catch (HTTPException $e) {
return $this->handleHTTPException($e, $request);
} catch (\Exception $e) {
return $this->handleGenericException($e, $request);
}
}
}
And get the config in the Context
:
<?php
class Context
{
+ /** @var array<string, mixed> Variables stored in the context */
- private $variables = [];
+ private $configs = [];
public function __construct(
private ServerRequestInterface $request,
private array $params,
private string $routePath,
+ array $configs = []
) {
$this->response = new Response();
$this->req = new RequestWrapper($request, $params, $routePath);
+ $this->configs = array_merge($this->configs, $configs);
}
public function set(string $key, mixed $value): void
{
- $this->variables[$key] = $value;
+ $this->configs[$key] = $value;
}
public function get(string $key): mixed
{
- $this->variables[$key] ?? null;
+ return $this->configs[$key] ?? null;
}
I'm going to close this now that we have better support for config across root and grouped routes.
Just like laravel, maybe a
config
folder where we can put different configs files. Example:/config/database.php
We can then access like this:
This would be such a usefull and helpfull feature.