I just finished my first MVC project with PHP and MySQL. I created a router that allows me to when I visit an URL, call a function that render the expected file.
I'm doing it with lampp's PHP and MySQL, but not using Apache, otherwise I'm using the php server (php -S localhost:3000 -t public/
). There, my project works perfectly well, and the routing is working like normal.
Well, I deployed it on Heroku but the problem is that my routing just doesn't work; every time I try to go (clicking a button or just typing it on the searchbar) to, for example, /about-us
it just render "/"
(index) again.
Here's my index.php (here I have all of my urls and call the functions that render everything)
<?php
require_once __DIR__ . '/../includes/app.php';
use MVC\Router;
use Controllers\PropiedadController;
use Controllers\VendedorController;
use Controllers\PaginasController;
use Controllers\BlogController;
use Controllers\AuthController;
$router = new Router();
$router->get('/admin', [PropiedadController::class, 'index']);
$router->get('/propiedades/crear', [PropiedadController::class, 'crear']);
$router->post('/propiedades/crear', [PropiedadController::class, 'crear']);
$router->get('/propiedades/actualizar', [PropiedadController::class, 'actualizar']);
$router->post('/propiedades/actualizar', [PropiedadController::class, 'actualizar']);
$router->post('/propiedades/eliminar', [PropiedadController::class, 'eliminar']);
$router->get('/vendedores/crear', [VendedorController::class, 'crear']);
$router->post('/vendedores/crear', [VendedorController::class, 'crear']);
$router->get('/vendedores/actualizar', [VendedorController::class, 'actualizar']);
$router->post('/vendedores/actualizar', [VendedorController::class, 'actualizar']);
$router->post('/vendedores/eliminar', [VendedorController::class, 'eliminar']);
$router->get('/blog/crear', [BlogController::class, 'crear']);
$router->post('/blog/crear', [BlogController::class, 'crear']);
$router->get('/blog/actualizar', [BlogController::class, 'actualizar']);
$router->post('/blog/actualizar', [BlogController::class, 'actualizar']);
$router->post('/blog/eliminaradminpropiedades', [BlogController::class, 'eliminar']);
$router->get('/', [PaginasController::class, 'index']);
$router->get('/nosotros', [PaginasController::class, 'nosotros']);
$router->get('/anuncios', [PaginasController::class, 'propiedades']);
$router->get('/anuncio', [PaginasController::class, 'propiedad']);
$router->get('/blog', [PaginasController::class, 'blog']);
$router->get('/entrada', [PaginasController::class, 'entrada']);
$router->get('/contacto', [PaginasController::class, 'contacto']);
$router->post('/contacto', [PaginasController::class, 'contacto']);
//Login
$router->get('/login', [AuthController::class, 'login']);
$router->post('/login', [AuthController::class, 'login']);
$router->get('/logout', [AuthController::class, 'logout']);
$router->comprobarRutas();
Here's my router.php
<?php
namespace MVC;
class Router {
public $rutasGET = [];
public $rutasPOST = [];
public function get($url, $fn) {
$this->rutasGET[$url] = $fn;
}
public function post($url, $fn) {
$this->rutasPOST[$url] = $fn;
}
public function comprobarRutas() {
session_start();
$auth = $_SESSION['login'] ?? null;
//Arreglo de rutas protegidas
$rutas_protegidas = ['/admin', '/propiedades/crear', '/propiedades/actualizar', '/propiedades/eliminar', '/vendedores/crear', '/vendedores/actualizar', '/vendedores/eliminar/', '/blog/crear', '/blog/actualizar', '/blog/eliminar'];
$urlActual = $_SERVER['PATH_INFO'] ?? '/';
$metodo = $_SERVER['REQUEST_METHOD'];
if($metodo === 'GET') {
$fn = $this->rutasGET[$urlActual] ?? NULL;
} else {
$fn = $this->rutasPOST[$urlActual] ?? NULL;
}
if(in_array($urlActual, $rutas_protegidas) && !$auth) {
header('Location: /');
}
if($fn) {
call_user_func($fn, $this);
} else {
echoPre('ERROR 404');
}
}
public function render($view, $datos = []) {
foreach($datos as $key => $value) {
$$key = $value;
}
ob_start();
include __DIR__ . "/view/$view.php";
$contenido = ob_get_clean();
include __DIR__ . "/view/layout.php";
}
}
Here's my .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
Here's my Procfile
web: vendor/bin/heroku-php-apache2 public/
CodePudding user response:
So, the problem was that in my router.php I was looking for $_SERVER['PATH_INFO']
and that wasn't able on the Heroku's web (mine). So, what I did is change the following:
$urlActual = $_SERVER['PATH_INFO'] ?? '/'; to $urlActual = $_SERVER['REDIRECT_URL'] ?? '/';
Problem solved!
PATH_INFO was throwing "/" because it doesn't exist in $_SERVER and that's because I was constantly redirected to the index page.
CodePudding user response:
$urlActual = $_SERVER['PATH_INFO'] ?? '/';
RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [QSA,L]
Your router.php
is expecting the requested URL to be passed as path-info, but your .htaccess
file is not doing this. To pass the URL as path-info then change the RewriteRule
directive to read:
RewriteRule (.*) index.php/$1 [L]
$1
is a backreference that contains the URL-path (less the slash prefix) captured from the RewriteRule
pattern.
(The QSA
flag is not required here.)