I have developed a PHP API to be consumed by a JavaScript frontend. I will make requests through fetch/ajax. When I start my server, I can't have an index.php file to call my route file because my application will be accessed through an index.html. How can I ensure that my frontend application can access, for example, the address www.example.com and display my HTML, and when my JavaScript makes an AJAX request to www.example.com/api/uri, it accesses my API?
My route file is inside app/routes/Router.php that is working fine
Here is the file:
<?php
namespace app\routes;
use app\helpers\Request;
use app\helpers\RouteParamParser;
use app\helpers\Uri;
class Router
{
const CONTROLLER_NAMESPACE = 'app\\controllers';
public static function load(string $controller, string $method, $request = null, $routeParams = [])
{
try {
// Check if controller exists
$controllerNamespace = self::CONTROLLER_NAMESPACE . '\\' . $controller;
if (!class_exists($controllerNamespace)) {
throw new \Exception("O Controller {$controller} não existe");
}
$controllerInstance = new $controllerNamespace;
if (!method_exists($controllerInstance, $method)) {
throw new \Exception("O método {$method} não existe no Controller {$controller}");
}
$controllerInstance->$method($routeParams, $request);
} catch (\Throwable $th) {
echo $th->getMessage();
}
}
public static function routes(): array
{
return [
'get' => [
'/api/locations' => ['controller' => 'LocationController', 'method' => 'index'],
'/api/locations/{id}' => ['controller' => 'LocationController', 'method' => 'show'],
'/api/departments' => ['controller' => 'DepartmentController', 'method' => 'index'],
'/api/departments/{id}' => ['controller' => 'DepartmentController', 'method' => 'show'],
'/api/personels' => ['controller' => 'PersonelController', 'method' => 'index'],
'/api/personels/{id}' => ['controller' => 'PersonelController', 'method' => 'show'],
],
'post' => [
'/api/locations' => ['controller' => 'LocationController', 'method' => 'store'],
'/api/departments' => ['controller' => 'DepartmentController', 'method' => 'store'],
'/api/personels' => ['controller' => 'PersonelController', 'method' => 'store'],
],
'put' => [
'/api/locations/{id}' => ['controller' => 'LocationController', 'method' => 'update'],
'/api/departments/{id}' => ['controller' => 'DepartmentController', 'method' => 'update'],
'/api/personels/{id}' => ['controller' => 'PersonelController', 'method' => 'update'],
],
'delete' => [
'/api/locations/{id}' => ['controller' => 'LocationController', 'method' => 'destroy'],
'/api/departments/{id}' => ['controller' => 'DepartmentController', 'method' => 'destroy'],
'/api/personels/{id}' => ['controller' => 'PersonelController', 'method' => 'destroy'],
],
];
}
public static function execute()
{
try {
$routes = self::routes();
$request = Request::get();
$uri = Uri::get('path');
if (!isset($routes[$request])) {
throw new \Exception('A rota não existe');
}
$routeParams = [];
$router = null;
// check if exact route exists
if (isset($routes[$request][$uri])) {
$router = $routes[$request][$uri];
} else {
// Search for route with params
foreach ($routes[$request] as $route => $routeConfig) {
$parsedRoute = RouteParamParser::getRouteParams($route);
if ($parsedRoute !== null) {
$pattern = str_replace('/', '\/', $route);
$pattern = preg_replace('/{.*?}/', '(.*?)', $pattern);
if (preg_match('/^' . $pattern . '$/', $uri, $matches)) {
$routeParams = $parsedRoute;
$router = $routeConfig;
break;
}
}
}
}
if (!$router) {
throw new \Exception("Route not found");
}
$controller = $router['controller'];
$method = $router['method'];
self::load($controller, $method, $request, $routeParams);
} catch (\Throwable $th) {
echo $th->getMessage();
}
}
}
I'm not sure if I made myself clear, but I think I managed to convey what I need.
my repo to the code is https://github.com/vsrromero/companyDirectoryV2/