So some background - I've decided to split an old PHP MVC project into a React frontend and php backend "server". For development - both are hosted locally, both are configured on different apache roots with some dummy hosts (api.loc/exp.loc) which are added in /etc/hosts. The so called "API server" uses an MVC Routing, which gets the requests /foo/bar and launches FooController->barAction().
For the API I send POST requests first through the fetch API, then through axios, both of which failed, and I discovered (using both xDebug and printing the $_POST as response), that PHP receives no $_POST. Nothing - empty array. I tried using the RESTClient addon for firefox to fire POST requests to the "server" and I get the same result.
In an attempt to fix the issue, after some research I've added the following headers on my index.php file, but to be honest I'm not 100% certain of their exact role.
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
header('Access-Control-Allow-Headers: Content-Type');
header('Content-Type: application/json');
Playing with these barely made any difference. This is how the routing is done (index.php):
$router = new Core\Router();
$url = $_SERVER['REQUEST_URI'];
$router->dispatch($url);
Router.php
public function dispatch($url)
{
$route = $this->extractRoute($url);
$controller = 'Application\Controllers\\' . $this->convertToStudlyCaps($route['controller']);
$action = $this->convertToCamelCase($route['action']);
$params = $route['params'];
$params = count($params) > 0 ? $this->processParams($route['params']) : null;
if (class_exists($controller)) {
$Controller = new $controller();
$callableAction = $action.'Action';
if (is_callable([$Controller, $callableAction])) {
$Controller->$callableAction($params);
} else {
echo json_encode("Invalid method [ {$action} ] specified");
}
} else {
echo json_encode("Invalid controller specified: [ {$controller} ]");
}
}
public function extractRoute($url)
{
$urlArray = explode('/', $url);
$result = [];
$result['controller'] = (array_key_exists(1, $urlArray) && $urlArray[1] !== '') ? $urlArray[1] : 'Index';
$result['action'] = (array_key_exists(2, $urlArray) && $urlArray[2] !== '') ? $urlArray[2] : 'index';
$result['params'] = array_slice($urlArray, 3);
return $result;
}
The requests reach the controller, but as stated above - with no $_POST available. $_GET receives only 'url' => '{urlpath}'
, regardless if I use $_GET.
I've checked php.ini post_max_size = 8M
So after some searching - I found a workaround, I can extract the $_POST data using
$data = file_get_contents('php://input');
What I really need help with is understanding why. I don't understand why there's no $_POST. I obviously lack the knowledge on what the exact problem is and I would greatly appreciate it if someone can point me in the right direction. Thank you in advance!