I have 7 different pages. All pages are the same considering the layout, but are different considering the content. The content is provided by a database, depending on what the users click on.
I figured out you have to pass the variable using the URL, and by so defining which content to load, right?
So, this is my menu-item:
<a id="menupag" class="item1" href="index.php?page=groups?group1">
This is my index:
<div class="content">
<?php
include_once ('content/'.$_GET['page'].'.php');
?>
</div>
But for some reason, when I click on the menu-item, this message appears:
Warning: include_once(content/groups?group1.php): failed to open stream: No such file or directory in httpd.www/new/index.php on line 32
What do I have to do to let php ignore the last part of the URL (this part is only used to define which data the database has to return) and just listen to the index.php?page=groups?
You pass parameters in URL in a bad way:
You should change it into:
<a id="menupag" class="item1" href="index.php?page=groups&group=group1">
so you will have in $_GET superglobal two values:
$_GET['page']; // value: groups
$_GET['group']; // value: group1
However using:
include_once ('content/'.$_GET['page'].'.php');
is totally unsafe. The better solution is:
$allow = array('groups', 'about', 'users');
$page = in_array($_GET['page'], $allow) ? $_GET['page'] : 'default';
include_once ('content/'.$page.'.php');
For security reasons you should have a whitelist so people can't include files you don't want them to include. You could use an array for this.
$validPages = array("groups", "home");
if (in_array($_GET['page'], $validPages)
{
$include = $_GET['page'];
}
else
{
$include = "home"; //Your default
}
<div class="content">
<?php
include_once ('content/'.$include.'.php');
?>
</div>
In answer to your question, your querystring looks invalid. Shouldn't it be index.php?page=groups&group=group1?
If not then you need to check for a question mark by doing:
$include = explode('?', $include);
$include = $include[0];
Not good way to use
<a id="menupag" class="item1" href="index.php?page=groups?group1">
Use like
<a id="menupag" class="item1" href="index.php?page=groups&varame=group1">
Otherwise
$page = array_shift(explode('?' ,$_GET['page']));
Or
$page = explode('?' ,$_GET['page']);
// use $page[0];
Related
The title says it all: I want the page to determine the title, but the title is being set before the page is being read (I think). Is there a way to accomplish this, or am I doomed to include the header on each individual page?
Here's what I have:
php.ini:
auto_prepend_file = "header.php"
header.php:
<?php
if (isset($title) == false) {
$title = "foobar";
}
$title = "My Site : " . $title;
?>
<title><?php echo($title) ?></title>
index.php
<?php
$title = "Home"; // ideally this would make the title "My Site : Home"
?>
Instead of using auto_prepend_file, I would just use:
include 'header.php';
An important reason why I wouldn't use auto_prepend_file is, if you move to another server, you'll have to remember to edit the php.ini. If you just include the file, you can move your code to any server.
Also, just like Fred-ii- said, I wouldn't use parenthesis. Also, you are missing a semi-colon after the echo.
To take that a step further, I would create a file called something like $config.php or $vars.php. Include that before everything and have it define all your global variables and constants.
I would check this out: http://php.about.com/od/tutorials/ht/template_site.htm
This is not an ideal answer, but I could use CGI variables to get the name of the page, then turn that into a title.
function get_title($page){
$title = str_replace("/", "", $page);
$title = str_replace("_", " ", $title);
$title = str_replace(".php", "", $title);
$title = ucfirst($title);
if($title = "Index"){
$title = "Home";
} elseif ($title == "") {
$title = 'Foobar';
}
return $title;
}
$title = get_title($_SERVER["PHP_SELF"]);
$title = 'My Site: ' . $title;
As a follow-up to my original comment, I'm posting this as an answer because while it doesn't specifically solve the problem, it addresses the underlying cause.
Disclaimer: The code below has many problems, especially security, it's not meant to be copied directly but only explains the concept.
What you need to do is have a container file that includes your headers and whatever else, and each PHP file is included from there. For example, name your container index.php, and have the following in it:
<?php
include 'header.php';
if ($_GET['page'])
include $_GET['page'].'.php';
include 'footer.php';
?>
Then each PHP page you have will be wrapped in the index.php file, and you can add whatever you want in the header file which will be included in all of your files. That way you don't have to include anything in the individual page files.
The client will access your pages with a query string, such as: index.php?page=test
Again, for security reasons you will still want to include basic checks in each individual file, but technically this can be avoided in you plan for this. You definitely won't need to include huge headers in each file, like MySQL connections etc. Also for security you should have stringent checks on your $_GET variables to make sure that only the pages you want can be included.
I'd define a writeTitle (or similar) function in the header.php file which you're auto_prepending:
header.php
<?php
function writeTitle($title = 'foobar') {
$title = "My Site : " . $title;
return '<title>' . $title . </title>';
}
And then you can just call the function from your page scripts instead of setting a variable:
index.php
<?php
echo writeTitle('Home');
Still learning php as I go so this might just be something I haven't gotten to yet but it's the next roadblock in building my personal site. I have a basic understanding of includes such as linking:
<a href="art.php?id=image id&name=This is my title&menu=side-menu-portfolio">
to pull my includes but I've come to a small problem in that my generic art-gallery page needs to switch between a 'portfolio' header and an 'artwork' header. So I figured I could either build "art-gallery.php" AND "port-gallery.php" and go back and relink everything or just make it so that when you call the link like the above code I just specify which header goes with it. Unfortunately this would also require going back and changing every link. But I noticed that I did state:
...&menu=side-menu-portfolio...
and the pages are already calling side-menu-artwork or side-menu-portfolio so if I could just call in menu and cast aside the 'side-menu-" portion then it would just use artwork or portfolio and call the right header. Unfortunately this is where my limited knowledge of php and syntax come in. I have tried to produce the following code based on my php and js understanding:
<?php include("headlines/headline-" . $_GET[menu - "side-menu-" ] . ".php"); ?>
but I don't know if my syntax is just wrong or if what I'm trying to do is impossible to begin with. Note that when I try this I get
Function Include error of "Warning: include(headlines/headline-.php)"
so it looks like everything else is reading correctly, I just don't know if or how I can extract the word I want from the rest of the menu name.
Should be, Assumed your included file name is headline-side-menu-portfolio.php
<?php
$filename = str_replace("side-menu-", "", $_GET['menu']); // headline-portfolio
include("headlines/headline-" . $filename . ".php"); // headline-portfolio.php
?>
Something like this :
<?php include("headlines/headline-" . $_GET["menu"].".php"); ?>
<!--gives include("headlines/headline-side-menu-portfolio.php")-->
where
$_GET["menu"] = 'side-menu-portfolio'
Try this:
<?php include("headlines/headline-" . $_GET['menu'] . ".php"); ?>
Your code is wrong.
Instead of
<?php include("headlines/headline-" . $_GET[menu - "side-menu-" ] . ".php"); ?>
try
<?php include("headlines/headline-" . $_GET['menu'] . ".php"); ?>
You should check if the file exists before you try including it.
if (file_exists($filesrc)) { ... }
Better yet don't let the user change the menu through a $_GET variable. Instead link to a specific page or pass a variable then decide what menu to get. Like
switch ($_GET['menu']) {
case 'side-menu':
include("headlines/headline-side-menu.php");
break;
}
Just use
$_GET['menu']
, the "side-menu-" part is already in the content of your variable passed as param.
You propably want to do an if .... else so to include one header or another based on the $_GET variable menu.
So something like this will do this:
if($_GET['menu'] == 'side-menu-portfolio') {
include 'headliens/side-menu-portfolio.php';
} elseif($_GET['menu'] == 'side-menu-other') {
include 'headliens/side-menu-other.php';
}
okay....your are almost there....just quotes missing from include syntax...it should be
include("headlines/headline-.php"); /* notice the quotes*/
so it should be
<?php include("headlines/headline-" .$_GET['menu'].".php"); ?>
where $_GET['menu'] should be in the url, like:
art.php?id=image id&name=This-is-my-title&menu=side-menu-portfolio
so what's happening her ??
Upon execution of the line :
<?php include("headlines/headline-" .$_GET['menu'].".php"); ?>
$_GET is fetched from the url and replaced in the header tag, so now the header tag becomes :
<?php include("headlines/headline-"."side-menu-portfolio".".php"); ?> => <?php include("headlines/headline-side-menu-portfolio.php"); ?>
Also. may i suggest that for :
<a href="art.php?id=image id&name=This is my title&menu=side-menu-portfolio">
don't use space in the url, either replace it by - or _
I'm trying to build a personal website, (fairly new to HTML and PHP) and am having trouble building a dynamic menu bar. By dynamic, I mean that I want the page that the use is on be highlighted.
Right now I have a horizontal menu on my page (Home, Contact, etc...), and have the CSS set up so that when one of the links has the attribute class="active", then the item remains highlighted (so the user knows which page he or she is on).
For example, in a static HTML page I would copy and paste the following code to each other static page and just change where the class="active" attribute is to align with the proper page:
Home
Page Two
Contact
I obviously want to use PHP to be able to minimize the amount of duplicated code I have scattered around.
So far, I have followed the first answer on this page It has worked great. I am able to click on a menu item and the content comes up in the body of the page. However:
I can't get it to dynamically highlight the menu since the menu options (the <a href /> lines) are not being dynamically created through PHP.
When I go to the page directly through index.php, I get an error:
Notice: Undefined index: 'page' in C:\xampp\htdocs\index.php on line 43
Obviously, when I go the page directly, the ?page=home variable is not set in the line:
Home
So, the 'page' variable in GET has not been set. I've gotten around that with an if statement that checks if it is not set and sends the home page html. However, I don't think this is the best way to do it, and when I try to tackle part b), I'm thinking I need to change this completely. My entire PHP script is like this:
<?php
$current_page = 'home';
$pages = array('home', 'pagetwo', 'contact');
function setActiveHeader() {
global $current_page;
global $pages;
$arr_length = count($pages);
for($x=0;$x<$arr_length;$x++) {
if($pages[$x] == $current_page) {
echo "$pages[$x]";
} else {
echo "$pages[$x]";
}
}
}
function putPage($page) {
// put a list of allowed pages here
global $pages;
$page = trim($page);
$page = (in_array($page, $pages)) ? $page : 'home';
// set current page global variable
$GLOBALS['current_page'] = $page;
// output contents of page selected
echo #file_get_contents('.\html\\' . $page . '.html');
}
?>
I just try to call setActiveHeader() from the HTML, but that doesn't work right. The menu is output correctly, but the the correct item doesn't get highlighted, it just stays stuck on the home option highlighted. Not sure why it is not being updated. Is there a better way to go about doing this?
Your code only goes up to 37 lines, and we can't much without the line that the error is referencing, but I'll try my best.
Basically, what Undefined Index means, is that you're trying to access an element in an array that isn't set. I'm guessing that you're trying to access $pages['page'].
There are two ways to fix this. Add page to the $pages array on the fourth line:
pages = array('home', 'pagetwo', 'contact', 'page');
Or wrap the 43rd line with an if statement:
<?php
$pages = array('home', 'about');
if (isset($pages['page'])) {
echo $pages['page'];
}
?>
However, a far easier method would be to use CSS:
home.php
<html>
<head>
<title>Foo</title>
</head>
<body id="home">
<ul class="menu">
<li id="link-home"><a>Home</a></li>
</ul>
</body>
</html>
style.css
body#home {
// active link styling here
}
I have the following code to include pages dynamically:
<div id="content">
<div id="aside">
...
</div>
<div id="main">
<?php
$page = (isset($_GET['page'])) ? sanitize($_GET['page']) : 'home';
if (!include 'pages/'.$page.'.php') require 'pages/404.php';
?>
</div>
</div>
As you can see, the #aside has static content.
I want to include a specific content for the #aside depending on the page selected. For example, if the user goes to 'Home' and 'About', I want the 'default' aside. But if the user goes to 'Documents' I want a 'Sections' aside.
I know I can just include each aside from every page, but that's not effective. I also don't want the user to be hable to set the aside as the main content, so they have to be in different folders or something.
I'd like to know an effective and not so complicated way to do this.
Thanks for taking your time to read this.
You want to keep which sidebar goes on which page in a database, and then query that database for the correct sidebar to include.
A table structure may look like this:
Table sidebars: ID | path | name | more info on sidebar...
Table pages: ID | path | name | more info on page...
Table sidebars-to-pages: page_ID | sidebar_ID
This approach even allows you to place multiple sidebars on a specific page.
What if you did this?
<?php
ob_start();
$page = (isset($_GET['page'])) ? sanitize($_GET['page']) : 'home';
if (!include 'pages/'.$page.'.php') require 'pages/404.php';
$contents = ob_get_clean();
?>
<div id="content">
<div id="aside">
<?php include($aside); ?>
</div>
<div id="main">
<?php echo $contents; ?>
</div>
</div>
and $page.php would look like:
<?php $aside = "sidebars/default.php"; ?>
<p>HTML for #main<br />
goes here</p>
There are a few different ways to do this that are all more-or-less equal. I almost always use a config.php file for sites to hold whatever global information I want every page to have. At the top of every page, you just call
<?php
require_once('config.php');
?>
In that config.php file, you could have an array listing your page names and the file you want included for each page, as well as a function that returns the content, like so:
// this lets you call includes relative to the site root
set_include_path($_SERVER['DOCUMENT_ROOT']);
$defaultAsideContent = 'includes/default.php';
$asideContent = array(
'index.php' => 'includes/include-1.php',
'document.php' => 'includes/include-2.php'
);
function getAsideContent() {
global $asideContent;
global $defaultAsideContent;
$content = $defaultAsideContent;
// get the requested page
$pageFull = $_SERVER['REQUEST_URI'];
// strip URL variables
$pageParts = explode('?', $pageFull);
$page = $pageParts[0];
// loop throught the array and see if there is specific aside content for the page
foreach($asideContent as $key=>$value) {
if ($page == $key) {
$content = $asideContent[$key]);
}
}
include($content);
}
Lastly, wherever you want your aside content to show up, just do
<?php getAsideContent(); ?>
When you create a new page, if you want specific aside content, just edit your config file. Just FYI, didn't test this at all, probably has bugs, but you get the jist.
Thank you all for your answers and collaboration. Although none of the answers did exactly what I was looking for, they showed me other ways to approach this issue and guided me to decide what method to use.
I came up with what I think is the simpliest way to do this:
I set my folder structure as: pages/aside and pages/main
I set up an array($asides) with the aside files as the keys and the main content files as the values.
Then I check if the requested file exists in the main folder.
If it doesn't exist, I redirect the user to the 404 page. If it does exist, I loop through $asides to see which aside is asigned to that main content page.
If it doesn't belong to any of the establisged asides, then I include the default aside.
$asides = array(
'aside1' => array('page1', 'page2', 'page3', 'page4'),
'aside2' => array('page5', 'page6')
);
$page = (!empty($_GET['p'])) ? sanitize($_GET['p']) : 'page1';
if (file_exists("pages/main/{$page}.php")) {
foreach ($asides as $key => $value) {
if (in_array($page, $asides[$key])) {
$aside = $key;
break;
}
}
if (!isset($aside)) $aside = 'default';
?>
<div id="aside"><?php require "pages/aside/{$aside}.php"; ?></div>
<div id="main"><?php require "pages/main/{$page}.php"; ?></div>
<?php
} else {
header('Location: ?p=404');
}
The bounty goes to Madara Uchiha because in my opinion, his answer is simple an effective. Thanks again to all of you who helped me with this issue.
I normally use a GET variable i n the URL to determined what data to show in my template.
Today I am not passing a variable. I am including a file named inludes/leftmenu.php on every page but depending on the page name I want to show different data.
leftmenu.php looks like so:
$page = $_SERVER["REQUEST_URI"];
$page_name = get_page_name($_SERVER["REQUEST_URI"]);
if ($page_name == "classes.php")
{
<h2 class="left_h2">Class Schedules & Info</h2>
<ul class="left_ul">
<li>Immersion Programs</li>
<li>Afternoon Programs</li>
<li>Immersion Schedule</li>
<li>Afternoon Schedule</li>
</ul>
}else if($page_name == "about.php")
{
<h2 class="left_h2">About Us</h2>
<ul class="left_ul">
<li>About Us</li>
<li>Photo Scrapbook</li>
</ul>
}else if ($page_name == "news.php")
{
<h2 class="left_h2">News & Events</h2>
<ul class="left_ul">
<li>News</li>
<li>Events</li>
</ul>
}
You could use a PHP array:
$pages = array(
'/events.php' => 'includes/events_menu.php',
'/news.php' => 'includes/news_menu.php'
);
// lookup the appropriate include file
$uri = $_SERVER['REQUEST_URI'];
$include = $pages[$uri];
// produce a default page if the URI wasn't recognised
if (!isset($include)) {
$include = 'includes/default.php';
}
include($include);
I don't know if it's faster, but there are many ways to do this.
E.g. with an array:
$page_name = get_page_name($_SERVER['REQUEST_URI']);
$includes = array(
'events.php' => 'includes/events_menu.php',
'news.php' => 'includes/news_menu.php'
);
if(isset($includes[$page_name])) include($includes[$page_name]);
else die('this page does not exist');
PHP polulates $_GET with variables passed in the URL. Though I do not recommend having a user-passed variable as a function of what your code includes.
an array is a better method, ofcourse, but you may also look into realpath() and make sure it's in DOCUMENT_ROOT /includes
You can create array with paths and then use in_array function, which will reduce if statements.
If there's a menu for every single page, you could go with
include('includes/'.basename($page_name, ".php").'_menu.php');
You can use REQUEST_URI, but you have to keep in mind that it always starts with a / slash. Unless you apply basename() you therefore would have to write:
if ($page_name == "/events.php")
The if statements are a workable approach if you only need a few page names. Otherwise use an switch or an url->filename map (as an array).
If you are using a RewriteRule to map all incoming URLs to a single PHP script, you could also think about using PATH_INFO instead of REQUEST_URI.