Understanding the front controller with PHP - php

I'm very new with PHP, and I've managed to create a really rough CMS. At the moment, it's using many different pages and includes.
However, if possible I'd like to use a controller rather than having lots of pages (I've already got article.php/admin.php).
As an example, I'm trying to convert to something like this:
switch ( 'admin' ) {
case 'home':
include 'view/home.php';
break;
case 'admin':
include 'view/admin.php';
break;
case 'article':
include 'view/article.php';
break;
default:
echo 'default';
break;
}
This would be used with $_GET['page'], so the admin URL looks like: http://cms.dev/?page=admin
However, what happens if I need to go to a subdirectory of admin? For example, if these were hardcoded pages, I would go admin/new-post.php. Is there an equivalent I could get, using the $_GET method?
Sorry if this has not been explained well. Let me know and I will try and edit it. I've used a smorgsaboard of tutorials so I'm not 100% on any of this.

You can have forward slashes in your $_GET['page'] variable, so https://cms.dev/?page=admin/new-post.php should work fine.
Alternatively you can put this into your .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
And then get it from the REQUEST_URI:
$uri = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);

Related

PHP simple dynamic URL routing

Hi I'm trying to create a really simple rout for my database driven website. Wold be great if someone could help.
My dynamic link is the following:
/views/page.php?page_slug=link-one
As you can see below I was hoping my dynamic link would would but it doesn't. I get an error saying that the file/directory doesn't exist. I guess the question is how would I get a dynamic URL in there (variable) so that it re-routes? I might be going completely the wrong way around this.
Here is my htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php
index.php file below.
<?php
$request = $_SERVER['REQUEST_URI'];
switch ($request) {
case '':
case '/':
require __DIR__ . '/views/index.php';
break;
case '/link-one':
require __DIR__ . '/views/page.php?page_slug=link-one';
break;
}
Any help much appriciated.
Try removing the query from the request uri.
And you can't stick query parameters in the path to an included file. But you can populate the get parameter if you want the included script to behave like it was submitted. But from the looks of it I think you should avoid that.
$request = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
switch ($request) {
case '/':
require __DIR__ . '/views/index.php';
break;
case '/link-one':
$_GET['page_slug'] = 'link-one';
require __DIR__ . '/views/page.php';
break;
}
And maybe this .htaccess is better in the long run where query string is appended to the route. And this is the last rule not conflicting others that may follow:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

PHP routing system for blog posts

I have managed to create a simple routing system however I'm a bit stuck on how to make it more dynamic. In this case I have got a blog post set up in my routing which is hard coded. If i click a dynamic link in my website that requires the /views/blog/page.php how can I get the system to work out what the page_slug is and append the page_slug so that it works without hard coding the links into it?
switch ($request) {
case '':
case '/':
require __DIR__ . '/views/index.php';
break;
case '/blog/blog-post-one':
$_GET['page_slug'] = 'blog-post-one';
require __DIR__ . '/views/blog/page.php';
break;
}
I've added my .htaccess file below just in case
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

How to work with pretty URLs - PHP

i followed up multiple tutorials how to make pretty URL but never actualy make it work (prolly i didnt get something).
What i want:
From something like this:
http://www.example.com/api/v1/get.php?user=UserName&id=7Ka2la2
I want to make something like this:
http://www.example.com/UserName/get/7Ka2la2
What i did try:
As I mentioned I try to follow multiple tutorials but nothing worked for me. So i try something by my self.
//.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
</IfModule>
What it does:
it checks if the request filename isn't a file
and checks if it isn't a directory
then, the RewriteRule makes a call to index.php, no matter what was written in the URL
And in my index.php file it looks like this
<?php
function parse_path() {
$path = array();
if (isset($_SERVER['REQUEST_URI'])) {
$path = explode('/', $_SERVER['REQUEST_URI']);
}
return $path;
}
$path_info = parse_path();
echo '<pre>'.print_r($path_info, true).'</pre>';
switch($path_info[1]) {
case 'get': include 'get.php';
break;
default:
include '404.php';
}
So it basicly should just split url to array and then base on URL include right file (in this example its get.php). However like this i can load a file but i have nothing in my $_GET and $_POST which make my script useless for me.
Question:
My code will somehow do what i want so base on url it load content but $_GET and $_POST will not work correctly here. So my question is did I make it wrong way? If yea how should looks the right one and if not how I can access $_GET and $_POST variabiles
You can set$_GET yourself. $_POST is unaffected by the rewrite.
Try this if you like:
<?php
function parse_path() {
$path = array();
if (isset($_SERVER['REQUEST_URI'])) {
$path = explode('/', $_SERVER['REQUEST_URI']);
}
return $path;
}
$path_info = parse_path();
echo '<pre>'.print_r($path_info, true).'</pre>';
// SET UP $_GET HERE
$_GET['user'] = $path_info[0];
$_GET['id'] = $path_info[2];
switch($path_info[1]) {
case 'get': include 'get.php';
break;
default:
include '404.php';
}
But if you can still modify the code that looks for $_GET you might want to consider not using $_GET like this, and rather set up some sort of class that contains the values.
And you also might want to consider doing your url rewriting so as to map the original request to something that has get variables.
eg
//.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/(.+)/(.+)$ /api/v1/$2.php?user=$1&id=$3 [L]
</IfModule>

Rewrite URL in .htaccess just cause 404 error

I'm trying to learn how to rewrite URL in the .htaccess file. I have read some tutorials, but despite that I write as in the example code, nothing happens for me! I'm wondering what I'm doing wrong here? I get a 404-code when I'm trying the code below.
RewriteEngine On
RewriteRule /byggnader/1/ /?p=byggnad&id=1
This is just a test and I wonder if /byggnader/ must be an existing file or just a name in the URL. I'm using a page controler design. So URL /?p=byggnad&id=1 will open the PSelectedBuilding.php file inside the index.php file.
I preciate some feedback to be able to continue.
EDIT: Since it's not working despite the help below, I also add the code from the index.php file that handle the requests. Perhaps that could give a clue why!?
<?php
session_start();
// Allow only access to pagecontrollers through frontcontroller
$indexIsVisited = TRUE;
require_once('config.php');
// pagecontrol
$page = isset($_GET['p']) ? $_GET['p'] : 'start';
switch($page) {
case 'start': require_once('PIndex.php'); break;
case 'karta': require_once('PMap.php'); break;
case 'byggnader': require_once('PBuildings.php'); break;
case 'tips': require_once('PTips.php'); break;
case 'visa-byggnad': require_once('PHandleSessions.php'); break;
case 'byggnad': require_once('PSelectedBuilding.php'); break;
case 'visa': require_once('PSelectedBuilding.php'); break;
case 'visa2': require_once('PHandleSessions.php'); break;
default: require_once('PIndex.php'); break;
}
require_once("CreatePage.php"); // Call file that creates the page
?>
EDIT 2:
This works fine, but not when I'm using requests for some of the pages:
RewriteEngine On
RewriteRule bilder-byggnader-kopenhamn /?p=byggnader
RewriteRule karta-byggnader-kopenhamn /?p=karta
RewriteRule start /?p=start
RewriteRule tips /?p=tips
Remove leading slash from your rule. .htaccess is per directory directive and Apache strips the current directory path (thus leading slash) from RewriteRule URI pattern.
RewriteEngine On
RewriteRule ^byggnader/1/?$ /?p=byggnad&id=1 [L]
Try this one:
RewriteEngine On
RewriteCond %{QUERY_STRING} p=(\w+)&id=(\d+)
RewriteRule ^index.php /%1/%2? [R=301, L]
The RewriteCond mathches the Query String (as per your wish) extracting two variables which you can reuse to build your redirection target in the rewrite rule directive. The final question mark tells Apache not to reappend existing QS. R=301 says that the redirection is permanent, L that this is the last rule to be processed.
You may have to play with the index.php part since you never put the REQUEST_URI part in your question.

How do I restructure the htaccess to allow for the home page?

Ok so I have a site that has tons of pages and I want to create a php file fore each one...this works great..here is what i have, code wise
Here is my htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]
here is my index.php file
$parts = explode('/', $_REQUEST['url']);
switch ($parts[count($parts) - 1]) {
case 'restaurant':
include "pages/restaurant.php";
break;
case 'retail':
include "pages/retail.php";
break;
.......
.......
}
this works great and if i visit the url http://someurl.com/restaurant the proper file in pages/restaurant.php pulls up. The only problem is the home page http://someurl.com when i visit it i get a:
Forbidden
You don't have permission to access /structure on this server.
Is there a way to fix this in the .htaccess to address this issue and should i create a file maybe called home.php in the pages folder or should i just put the content of the home page in the index file in an else condition...any ideas
You forgot to specify a default switch case?
switch ($parts[count($parts) - 1]) {
case 'restaurant':
include "pages/restaurant.php";
break;
case 'retail':
include "pages/retail.php";
break;
default:
include "pages/default_page.php";
break;
.......
.......
}
1. Use this rule somewhere before existing rules:
RewriteRule ^$ index.php?url=home [L]
2. Create pages/home.php
3. Add this to your switch statement:
case 'home':
include "pages/home.php";
break;
P.S. I do not recommend using default: to handle home page. default: should be used to handle 404 page / unknown pages ONLY.
Do you have a default statement in that switch? My bet is you don't.
DirectoryIndex index.php
Do you have this code in your httpd.conf or .htaccess?
It seems like your default file is not index.php

Categories