OOP/Maintainble alternatives to including pages with switch statement - php

I have pages in my website with URLs like this:
http://example.com/index.php?page=about
http://example.com/index.php?page=portofolio
http://example.com/index.php?page=location
http://example.com/index.php?page=mission
http://example.com/index.php?page=contact
http://example.com/index.php?page=register
http://example.com/index.php?page=login
Now, the objective is to include be it a simple about.html page containing a simple text about the company, or a form processor file called register.php when ?page=register is called.
This is how I am handling the contents.
$id= isset($_GET && !empty($_GET['page'])) ? htmlspecialchars($_GET['page']) : false;
switch($id){
case 'about':
include 'about.html';
break;
case 'porofolio':
include 'portofolio.html';
break;
case 'contact':
include 'contact_form.html';
include 'contact_process.php';
break;
case 'login':
if(isset($_SESSION['user_login'])){
echo 'You are already logged in';
}else{
include 'login_form.html';
include 'login_process.php';
}
default:
die('Page not found');
break;
}
Yes, I know It is horrible. I know trust me. That is why, I need better maintainable solution to this.
Now, if you are just curious what could be inside process_login.php It looks like:
if($_POST){
if(!empty($_POST['username']) && !empty($_POST['password'])){
try{
$pdo = new PDO(...);
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ? AND password = ?");
if($stmt->rowCount(){
$_SESSION['user_login'] = $_POST['username'];
header('location: success.php'); exit;
}
}
}
}
This is just an example I quickly wrote, so there may be some typo or another thing I've left. What I am interested to know is how to better create/emulate a practice of handling the switch statements, as it does not seem to me a good oop-oriented approach for such task. I want something maintainable, extensible approach.
If you are wandering why I have only have one page index.php, it is because I don't want to create static pages for all the pages, as they have the same layout, making the HTML improvement easier. Instead of one day, opening 7 files to change/add a single tag, it would make sense to do it only once.
second, if you wandering why I chose to include the about.html page instead of simple storing the plain text in database, is because I didn't want to create a field/table/connection just for that 10 line simple text, as I would be saving some overhead performance. (Although I am sure, you may not agree on this)
So, the general question is, how to get rid of that complexity with switch statement, which makes me end up creating files like login_process.php instead of dealing with it, in some OOP way that I am not aware of.
Sorry for the wall of text :( and thanks in advance.

The solution that you're looking for is really MVC and templating your views. Further, you're essentially creating your own router, your router is pretty simple compared to some of the complex routing schemes found in some of the major frameworks, so if you're looking to simplify further, that's going to be kinda difficult.
If you want to see how this is all done in a very OOP manner, checkout something like the Zend Framework 2, CakePHP, etc.

Related

Howto Setup Index.php dynamically?

I currently have this setup
<?php
$nav = filter_input(INPUT_GET, 'nav', FILTER_SANITIZE_STRING);
$Working_On = true;
//$Working_On = false;
if ($Working_On == true) {
$title = '- Under Construction';
$error_msg = "Website Under Construction.";
include('404.php');
exit;
} else {
switch ($nav) {
case "":
include('main.php');
break;
default:
$title = '- 404 Page Not Found';
include('404.php');
break;
}
}
I'd love to know if there is a better way more efficent way of orginising this type of setup so i can easily add more options ?
While accessing a page with
example.com/?nav=examplepage
is a valid approach (that I also used in past projects), today's standard is to use something like
example.com/examplepage
This creates URLs that are easier to understand by humans and more semantic than query parameters. Doing so will also prevent you from running into possible caching issues with URLs defined by query parameters.
It also brings you the benefit of including even more information in the URL without the need for query parameters, for example
example.com/posts/view/20
Such URLs are usually parsed by a "Router". There are many reference and open source implementations for PHP routing on the web, just search for "PHP Router", take a look and decide what best fits your needs.
Side note:
use type-safe checks, aka === instead of == to save you a lot of headache and follow security best practices; if you're still at the beginning of your project, you might want to take a look at https://phptherightway.com/
you exit() if the site is on maintenance. In that case you don't need to put the switch statement inside else{}, you can just put it after the if clause

How to show error when action= not found php

Hii everyone i am new here, and i am also new in coding world too 😁
But i what i have learned so far from php by myself it feels nice using php.
But i have a queation
I have a file name (home.php)
I used
$action = $_GET("action")
In this page and i have multiple actions available fr the page it goes like
home.php?action=main
home.php?action=new
But when someone tries puting new action there that i dont have in the file
Like
home.php?action=boom
Page comes blank
Any one give me any idea to set a action that will come when an actio not found in the file
Thank you very much
I know ifs a lot to ask
But its stack overflow 😍
A very simple solution can be :
$action = $_GET["action"];
switch ($action) {
case "main":
// do your main stuff here
break;
case "new":
// do your new stuff here
break;
default:
// the action is unknown, do what you have to do in that case here
}
But that makes you add each new action manually, probably not the best way to do it.
Still, it is a simple way to answer your question.
You can also try this :
$action = $_GET("action");
if($action=='main'){
// do your main stuff here
}else if($action=='new'){
// do your main stuff here
}else{
// do your main stuff here
}
if action does not match in any condition then by default it will go on else case.

Displaying same page differently for users with different roles

I wanted some suggestions from someone with experience in php.
I am making a website in php which will have 4 kinds of users :
1. guest(unregistered),
2. registered,
3. registered with special privilages,
4. admins
So the same page will be visible differently to all four of them.
Right now I am doing that by using if conditions.
In every page, I am checking the role of the user and then using many if statements to display the page accordingly.
It makes the code very big and untidy and I have to check conditions again and again in all the pages.
Is there a better way to do this?
How is this done in big professional websites?
Extended Question:
What is the most optimal way to do the same using a MVC framework like kohana 3.1? Does it have anything to do with acl?
It really depends on what you need.
For example if the page has big part that change completely, what I would suggest is to create different templates and include them depending on their "permissions"
$permission = $_SESSION['type_user'];
include '/path/to/file/with/permission/'.$permission.'/tpl.html';
and have something in the page similar to
<?php
//inside include.php you have the line similar to
//$permission = isset($_SESSION['type_user']) && $_SESSION['type_user']!=''?$_SESSION['type_user']:'common';
require_once '/mast/config/include.php';
include '/path/to/file/with/permission/common/header.html';
include '/path/to/file/with/permission/'.$permission.'/tpl_1.html';
include '/path/to/file/with/permission/common/tpl_2.html';
include '/path/to/file/with/permission/'.$permission.'/tpl_3.html';
include '/path/to/file/with/permission/common/footer.html';
?>
if the script is full of small parts like "show this text", or "show this button", you can create a function that will check the permissions for you
<?php
function can_user($action, $what){
switch($action){
case 'write':
return $your_current_if_on_what;
break;
case 'read':
default:
return $your_current_if_on_what;
break;
}
}
?>
and the template will look like:
[my html]
<?=can_user('read','button')?'My Button':''?>
[my html]
As a rule of thumb, if a piece of code is used more than 2 times, it needs to be put in a function/file separately, so if you have many "IFS" you need to create a function

PHP Case switch (efficiency)

The code below ensures that when a user accesses control panel, they are ran through a quick verification process to validate what their entities are. For instance, if a user is level 1 they are only given access to video feed which means nothing else is available to them.
When I look at the code though, I can see video feed being called when case 1 and 3 are called. I would possibly enjoy an alternative to make the code more efficient.
I was told a possible array could make things a little easier but then again this is faster.
switch ($_SESSION['permission']) {
case 1: // Level 1: Video Feed
include ("include/panels/videofeed.index.php");
break;
case 2: // Level 2: Announcements / Courses / Teachers
include ("include/panels/announcements.index.php");
include ("include/panels/courses.index.php");
include ("include/panels/teachers.index.php");
break;
case 3: // Level 3: Announcements / Video Feed / Courses / Teachers / Accounts / Logs
include ("include/panels/announcements.index.php");
include ("include/panels/videofeed.index.php");
include ("include/panels/courses.index.php");
include ("include/panels/teachers.index.php");
include ("include/panels/accounts.index.php");
include ("include/panels/log.index.php");
break;
case 4: // Level 4: Teachers
include ("include/panels/teachers.index.php");
}
It's fine the way it is. I think you don't mean "efficiency" when you refer to the "repeated" includes. You mean you could compact your code by using the switch fall-through.
While this might make your code smaller, it has no significant impact of efficiency (the time the script takes to run) and it will actually make the code harder to read. Leave it be.
Frist you may run better if you use require_once if its possible.
The second point is to shorten the url it seems that its every include the same.
Maybe try to use it in a function for example:
$permission_id = $_SESSION['permission']
function requireModule($moduleName, $path = 'include/panels/') {
$moduleName .= '.index.php';
require_once($path . $moduleName);
}
// if you want you can add an arry for it:
$permissionModules = array(
array('videofeed'),
array('announcements', 'courses', 'teachers'),
array('announcements', 'courses', 'teachers', 'accounts', 'log', 'videofeed'),
array('teachers')
);
// now we can put it in a more effectiv way
if(array_key_exists($permission_id, $permissionModules)) {
foreach($permissionModules[$permission_id] as $includes) {
requireModule($includes);
}
}
Wrong ? Correct me!

Access control of page in php

I want to control the access in php website.
I have a solution right now with switch case.
<?php
$obj = $_GET['obj'];
switch ($obj)
{
case a:
include ('a.php');
break;
default:
include ('f.php');
}
?>
But when i have so many pages, it becomes difficult to manage them. Do you have better solutions?
Right now, i develop the application using php4. And i want to use php5. Do you have any suggestions when i develop it using php5?
Thanks
$obj = $_GET['obj'];
$validArray = array('a','b','c','d','e');
if (in_array($obj,$validArray)) {
include ($obj.'.php');
} else {
include ('f.php');
}
The more pages you have the harder it will be to control this.
Your best off using a framework of some sort, my personal preference is CodeIgniter.
why not just address a page itself?
first page
another page
I am not saying that this is the best solution, but years ago I used to have a website which used a database to manage the key, the page to be included, and some informations like additional css for instance.
So the code was something like:
<?php
$page = htmlspecialchars($_GET['page']);
$stuffs = $db->query('select include,css from pages where pageid = "' . $page . '" LIMIT 1');
?>
So when we needed to add a page, we just created a new field in the database. That let us close a part of the website too: we could have a "available = {0,1}" field, and if zero, display a static page saying that this page was under maintenance.

Categories