Perhaps this question is worded wrong, but I am having some trouble with my PHP switch statement below.
My goal is to have access to the $page variable across all files. I have tried to do this with sessions, but could not get it to work. An example of my code is shown below. Could this problem be solved with $_GLOBALS or $_SESSIONS? Please point me in the right direction.
Index.php
<?php
/* Fetch needed files. */
require_once 'app/paths.php';
require_once THEME_LAYOUT_PATH . 'container.phtml';
if(!isset($_GET['page']) || $_GET['page'] == ''){
$page = 'home';
} else {
$page = $_GET['page'];
}
$layoutPath = 'themes/neutron/layout/' . $page . '/' . $page . '.phtml';
switch($page)
{
case 'home':
include $layoutPath;
break;
case 'login':
include $layoutPath;
break;
case 'register':
include $layoutPath;
break;
default:
include 'themes/neutron/layout/404/404.phtml';
}
?>
Container.phtml
<html>
<?php if($page == 'login'){ ?> //Error: $page is undefined
<link rel = "stylesheet" type = "text/css" href = "<?php ASSETS_PATH . 'css/file.css' ?>">
<?php } ?>
</html>
You're requiring container.phtml before you set the $page variable. The files included in your switch statement should all have access to the global $page variable, assuming they aren't wrapped inside a class, function, or other construct.
Edit: Here's what your code would look like with this change:
<?php
if(!isset($_GET['page']) || $_GET['page'] == ''){
$page = 'home';
} else {
$page = $_GET['page'];
}
/* Fetch needed files. */
require_once 'app/paths.php';
require_once THEME_LAYOUT_PATH . 'container.phtml';
$layoutPath = 'themes/neutron/layout/' . $page . '/' . $page . '.phtml';
switch($page)
{
case 'home':
include $layoutPath;
break;
case 'login':
include $layoutPath;
break;
case 'register':
include $layoutPath;
break;
default:
include 'themes/neutron/layout/404/404.phtml';
}
?>
Related
I use a method like this instead of using a global variable:
$page = $_GET['page'];
switch ($page) {
case 'note':
include('note.php');
break;
case 'home':
include('home.php');
break;
default:
include('home.php');
break;
}
Is there a faster and more reliable way to include files?
You can validate and include like following:
$pageArr = ['note', 'home'];
if (in_array($_GET['page'], $pageArr)) {
include $_GET['page'] . '.php';
} else {
include 'default_file.php';
}
I'm trying to create a simple static website, but my lesser knowledge in back-end code had me question my abilities. Is there any kind of security risk or anything else I might be overseeing to use an array check instead of switch statement?
For example this is the code I've been using until recently
// Default page
$current_page = 'home';
if(array_key_exists('page', $_GET)) {
$current_page = $_GET['page'];
}
switch ($current_page) {
case 'home':
$page = 'pages/home.php';
break;
case 'about':
$page = 'pages/about.php';
break;
case 'contacts':
$page = 'pages/contacts.php';
break;
default:
$page = 'pages/404.php';
}
and this is the code I've replaced it with. It just makes more sense to me to have the code that would expand in the future (as more pages are added later on) separate from the actual check that never changes, on top of that I think it looks nicer.
$pages = array(
'home' => 'pages/home.php',
'about' => 'pages/about.php',
'contacts' => 'pages/contacts.php',
'404' => 'pages/404.php',
);
// Default page
$page = $pages['home'];
if(array_key_exists('page', $_GET)) {
$current_page = $_GET['page'];
if(array_key_exists($current_page, $pages)){
$page = $pages[$current_page];
} else {
$page = $pages['404'];
}
}
They are both safe, but the second is a bit easier to manage.
Another approach would be something like this:
$subFolder = 'pages';
$current_page = $subFolder . DIRECTORY_SEPARATOR . 'home';
if (array_key_exists('page', $_GET)) {
$current_page = $subFolder . DIRECTORY_SEPARATOR . $_GET['page'] . '.php';
}
if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . $current_page)) {
$page = $current_page;
} else {
$page = $subFolder . DIRECTORY_SEPARATOR . '404.php';
}
echo $page;
This does not require you to edit your code every time you add a new page. The code itself checks if the requested page exists in the pages directory.
I am trying to generate switch from list of files in directory
I have directory tree
../pages/
-home.php
-about.php
-service.php
-contact.php
../system/
-error404.php
-index.php
-functions.php
And I want to generate switch statement in function open_page() in functions.php to include file from PAGES into index.php.
What I need to generate is this function in functions.php:
open_page($page){
switch ($page) {
case '': require_once("pages/home.php"); break;
case 'home': require_once("pages/home.php"); break;
case 'about': require_once("pages/about.php"); break;
case 'service': require_once("pages/service.php"); break;
case 'contact': require_once("pages/contact.php"); break;
default: require_once("system/error404.php"); break;
}
}
My try:
//get all pages from dir PAGES
foreach (glob("pages/*.php") as $path) {
$file = explode("/", $path);
$filename = explode(".", $file[1]);
$pages[] = $filename[0];
}
switch ($page) {
case '': require_once("pages/home.php");
break;
foreach ($pages as $page){
case '{$page}': require_once ("pages/"{$page}".php");
}
default: require_once("system/error404.php");
break;
}
Thank you in advance.
EDIT:
index.php
<?php
include 'functions.php';
?>
<html>
<body>
<div id="menu">
<a href=index.php?page=home>Home</a>
<a href=index.php?page=about>About</a>
<a href=index.php?page=service>Service</a>
<a href=index.php?page=contact>Contact</a>
</div>
<div id="content">
<?php
open_page($_GET['page']);
?>
</div>
</body>
</html>
This isn't really an answer on how to do a loop in a switch but I believe you can solve your problem by doing this: You check to see if the file exists. If it does you load it. If not you load the error page.
function open_page($page = 'home') {
if (empty($page)) {
$page = 'home';
}
$file = "pages/{$page}.php"
if (file_exists($file)) {
require_once($file);
} else {
require_once("system/error404.php");
}
}
A switch is not required.
if($page=='')
$page = 'home';
$filename = "/path/to/{$page}.php";
if (file_exists($filename)) {
require_once($filename);
} else {
require_once("system/error404.php");
}
The logic is flawed for your switch block.
You could do something like this instead:
$page = basename($page);
if(empty($page)) {
$page = "home";
}
if(file_exists("pages/{$page}.php")) {
require_once("pages/{$page}.php");
else {
require_once("pages/error404.php");
}
Edit: Notice how I used basename around the $page variable. This is fairly important so that your $page can't be something like ../../some-other-file.php, for example.
Is it possible to determine what to show depending on the URL?
I have an index file which is:
<?php include './includes/header.php'; ?>
<?php include './includes/menu.php'; ?>
<?php include './includes/content.php'; ?>
<?php include './includes/sidebar.php'; ?>
<?php include './includes/footer.php'; ?>
Note: I have different "content.php"'s
Is it possible to do something like:
If Url = url {
show only content for the url
}
and then have case system like
case: home.php
show some
etc
I know Wordpress can do it. Is it possible with PHP and MySQL and HTML?
EDIT: Instead of content.php i would want show the desired HTML code gotten from my db
Use this function to see your current page. Then use the "switch" case for proper include file:
## Get Current Page / Section
function cur_page()
{
$cur_page='';
if(isset($_SERVER['PHP_SELF']) && $_SERVER['PHP_SELF']!='')
{
$temp_var1 = explode('/', $_SERVER['PHP_SELF']);
$cur_page = $temp_var1[count($temp_var1)-1];
}
else if(isset($_SERVER['SCRIPT_NAME']) && $_SERVER['SCRIPT_NAME']!='')
{
$temp_var1 = explode('/', $_SERVER['SCRIPT_NAME']);
$cur_page = $temp_var1[count($temp_var1)-1];
}
else if(isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI']!='')
{
$temp_var1 = explode('/', $_SERVER['REQUEST_URI']);
$cur_page = $temp_var1[count($temp_var1)-1];
$temp_var2 = explode('?', $cur_page);
$cur_page = $temp_var2[0];
}
else if(isset($_SERVER['SCRIPT_FILENAME']) && $_SERVER['SCRIPT_FILENAME']!='')
{
$temp_var1 = explode('/', $_SERVER['SCRIPT_FILENAME']);
$cur_page = $temp_var1[count($temp_var1)-1];
}
return $cur_page;
}//end func.....
Querying from database.
I don't recommend MySql, and I hope you learn PDO instead, but just
for this example
function get_me_title($page) {
$query = "SELECT * FROM title WHERE title = $page";
$result = mysql_query($query);
foreach($result as $row) {
return $row[$page];
}
}
Now, you can use function .get_me_title('whatever') to query from database, and echo below
if(isset($_GET['page_id'])) {
$page = $_GET['page_id'];
switch($page) {
case "contact";
echo get_me_title('contact');
break;
case "about";
echo get_me_title('about');
break;
case "portofolio";
echo get_me_title('portofolio')
break;
default:
echo 'you are in home page';
}
}else {echo '404 ERROR! The Page you have requested does not exist';}
Instead of including content.php, you can include needed page.
For example, if You build Your urls, where, for example, $_GET['page'] will refer to needed page, then simply You can do this.
$availablePages = array('default' => 'home', 'about');
if (isset($_GET['page']) && in_array($_GET['page'], $availablePages) {
$page = $_GET['page'] . '.php';
} else {
$page = $availablePages['default'] . '.php';
}
include $page;
I'm trying to build a really simple php controller page for a small site. Here is what I have so far. It seems to work well. Are there any issues I might be missing with doing it this way?
$page = $_GET['p'];
switch ($page)
{
case "":
ob_start();
include "inc/home.php";
$content = ob_get_contents();
ob_end_clean();
break;
case $page:
$page = str_replace("/", "", $page);
if (file_exists("inc/".$page.".php"))
{
ob_start();
include "inc/".$page.".php";
$content = ob_get_contents();
ob_end_clean();
}
else
include "inc/404.php";
break;
}
include("inc/header.php");
echo $content;
include("inc/footer.php");
UPDATE: Here is the final code based on comments that works well.
<?php
$page = (isset( $_GET['p']) && !empty($_GET['p'])) ? $_GET['p'] : 'home';
if( preg_match( '/[^a-z]/i', $page))
{
$page = '404';
}
if( !file_exists( "inc/".$page.".php"))
{
$page = '404';
}
ob_start();
include("inc/header.php");
include("inc/".$page.".php");
include("inc/footer.php");
?>
Your entire script can be rewritten as follows:
$page = ( isset( $_GET['p']) && !empty( $_GET['p'])) ? $_GET['p'] : 'home';
// Only allow alphabetic characters in a user supplied page
if( preg_match( '/[^a-z]/i', $page))
{
$page = '404';
}
if( !file_exists( "inc/".$page.".php"))
{
$page = '404';
}
include("inc/header.php");
include("inc/".$page.".php");
include("inc/footer.php");
However, this is also no longer susceptible to Local File Inclusion, as $page is restricted to only alphabetic characters, and the script will show the 404 page if anything else is submitted.
It's also more efficient as its not using output buffering.