I have two headers: one to display for a logged in user, and one to display when logged out/not a member. I also have a footer that should be duplicated on each page.I had the idea to use SSI to include the header and footer.
As of now, we haven't started much server-side processing, and thus don't keep track of logged in/logged out users. As such, for now, I just want to use the page that is including the header to determine which to display. I had the idea to use a PHP file as the header instead of an SHTML file, so I could do some processing to determine which header to show.
So is it possible to determine which page is calling the include with PHP?
Am I going about this all wrong? If so, what solution is more appropriate?
For example, each html page fits this general layout:
<html>
<header>
<!-- relevant header calls -->
<header>
<body>
<div id="body">
<!--#include virtual="header.php"-->
<!-- actual page content -->
</div>
<!--#include virtual="footer.shtml"-->
</body>
</html>
And in header.php I want something like:
<?php
if(/*page is a non-logged in page*/){
echo(/*logged out header*/);
} else {
echo(/*logged in header*/);
}
?>
So is it possible to determine which page is calling the include with PHP?
No idea. But if it is possible it will be via $_SERVER. Put this in your header.php for testing:
<?php
echo '<pre>';
print_r($_SERVER);
echo '</pre>';
However, if the page is being requested as *.html with Server-Side Includes I can't even begin to predict what kind of havoc this is going to play with PHP Sessions. I have doubts that session_start() will ever be able to set proper headers in this context, or if the PHP session cookie will ever be sent to the client or be passed through SSI back to PHP.
As far as I am aware/concerned SSI should only ever be used to include static content or dynamic content that does not rely on any sort of interaction with the user, including something as basic as if they're logged in or not. SSI is a kludge between static and dynamic pages and should be referred to as "kinda-sorta-dynamic-but-not-really".
Short answer: SSI is going to be a massive pain in the ass, ditch it and just use PHP include().
Edit: Your page would look something like this at the most basic level, and is not really any more complex than using SSI. If you took a more MVC-oriented approach [namely the C and V parts] it would become more manageable:
<?php
session_start();
// other initialization
?><html>
<head>
<!-- relevant header calls -->
<head>
<body>
<div id="body">
<?php
if($_SESSION['is_logged_in']){
echo(/*logged out header*/);
} else {
echo(/*logged in header*/);
}
?>
<!-- actual page content -->
</div>
<?php include("footer.php"); ?>
</body>
</html>
For the sake of ease in programming it's best to use one or the other. It's best to go with PHP exclusively because:
Massive support community at php.net
In most implementations it's faster than using the SSI because PHP is designed to do all of the processing and parsing of PHP code, whereas an SSI has to read your SHTML page (after it's written) and sift between comments and includes, then include all of the components.
If you're including PHP pages as SSIs you're making Apache wait on PHP, whereas if you were using PHP alone it would have already delivered the page.
You can do things with databases and a lot more with PHP.
PHP pages can't be accessed from the server without being processed, so there is less risk of someone exploiting your code vulnerabilities if you're using standard practices.
SSIs are plainly readable as code (and very limited).
You can include an SSI with PHP if you're running PHP as an Apache Module, using the function virtual(), but why would you want to? You can include() just about anything into PHP.
Example
I'm going to use an account management site as an example. To make the header dynamic you'll need to find the $var for the page calling it (I'm going to use $_SERVER['REQUEST_URI']). There are several reserved server variables in PHP that you can reference to make calls depending on circumstances. So let's say the authorized directory where all logged in pages go is called "auth" your common shell file might look like this:
<?php
//Check for the page the person is asking for
session_start();
$root = $_SERVER['DOCUMENT_ROOT'];
//Check for the "auth" directory
if(preg_match('!^/?auth!',$_SERVER['REQUEST_URI'])){
//Do some check to see if they've been authenticated... this one is not secure, but you get the idea
if($_SESSION['logged_in']){
//Require the correct header
require_once($root.'/includes/logged-in-header.php');
} else {
//They don't belong or they're not logged in, kick them back to the login page.
header("Location: /login.php?e=1");
die();
}
} else {
//It's not an authorization required page, so show the standard header.
require_once($root.'/includes/non-auth-header.php');
}
//let's find out the page that's loading the shell.
$pageName = preg_replace('!/([^/]+)$!',"$1",$_SERVER['SCRIPT_NAME']);
switch($pageName){
/*Auth pages*/
case "billing.php":
require_once($root.'/includes/billing.php');
break;
case "account.php":
require_once($root.'/includes/account.php');
break;
case "logout.php":
require_once($root.'/includes/logout.php');
break;
default:
//show the login page
require_once($root.'/includes/login.php');
}
require_once($root.'/../shell.php');
require_once($root.'/includes/footer.php');
?>
So if you were in the auth directory and you were not logged in, you would get the homepage. If you're in the auth directory on the billing.php page and you are logged in, the site would load the billing page.
The auth/billing.php code might look like this:
require_once("$_SERVER['DOCUMENT_ROOT'].'/../shell.php');
The include/billing.php code would contain all of workings of the page and it can be formatted in HTML, but you'd probably pull that stuff from a database.
Related
I'm new to php coding, web development, and search optimization - so newbie overall. In the process of learning php and web development I've been trying out different website architectures and layouts. One I'm working on uses an approach like the following:
I have one index.php page which always loads a header.php, sidebar.php, and footer.php. The index.php also contains a switch so that depending on the page variable the index.php is passed it loads different core content. So for example a examplesite.com/index.php?page=photos and examplesite.com/index.php?page=stories would both have the same header, footer, and side bar but one would have photos and one would have stories as the main content.
<?php $page = $_GET['page'];?>
<?php include("header.php"); ?>
<?php include("nav.php"); ?>
<?php
switch ($page)
{
case 'play':
include("photos.php");
break;
case 'cards':
include("stories.php");
break;
default:
include("frontpage.php");
}
?>
<?php include("footer.php"); ?>
My navigation is made up of href="index.php?page=..." links so choosing a menu button on the index page essentially calls itself passing it the new core to load.
I have no idea if this is a totally unorthodox approach but it all started because I was initially going to create a wordpress theme but then halfway through decided not to do it in wordpress.
What i'm concerned about are what drawbacks could be associated with this approach when it comes to search engines, indexing, seo etc.
What are other drawbacks or issues I should be thinking about that maybe I'm not?
Thanks in Advance!
I have no idea if this is a totally unorthodox approach
There is nothing essentially "unorthodox" in using a query string to load various pages. Billions of sites using this approach. Search engines can index such pages all right.
Nevertheless,
I have one index.php page which always loads a header.php, sidebar.php, and footer.php.
This is wrong concept.
Having an index.php file only to load header and footer makes no sense and makes your site plainly unusable.
Here are main faults in your design:
You're assuming that header.php would be called with the every page call. That's wrong.
You're assuming that header.php will always be static. That's wrong.
You forgot to create a template for the page itself.
The main rule everyone have to learn by heart:
Not a single character has to be sent into browser, until all data gets ready.
Why?
it's 2012 today. AJAX era. What if your code will have to send JSONed data instead of whole HTML page?
there is a thing called HTTP header. Sometimes we have to send them. And it's gets impossible if you already have your ornate HTML header sent.
Separating display logic from the business logic will let you use the same php code on many sites. You will have to change only templates and don't touch engine files. That's really great benefit.
Imagine you're going to make a custom <title> tag for your pages, based on the page content. Isn't it extremely common thing? But you can't make it without using templates.
So, you have to have one common site template containing header and footer and also dedicated templates for the every php script.
And these templates have to be called only when all business logic is done - i.e. you have got all your data ready.
An example layout is going to be like this:
.1. page itself.
it outputs nothing but only gathers required data and then calls a template:
<?
//include our settings, connect to database etc.
include dirname($_SERVER['DOCUMENT_ROOT']).'/cfg/settings.php';
//getting required data
$DATA=dbgetarr("SELECT * FROM links");
$pagetitle = "Links to friend sites";
//etc
//and then call a template:
$tpl = "links.tpl.php";
include "template.php";
?>
.2. template.php which is your main site template,
consists of your header and footer:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My site. <?=$pagetitle?></title>
</head>
<body>
<div id="page">
<? include $tpl ?>
</div>
</body>
</html>
.3. and finally links.tpl.php is the actual page template:
<h2><?=$pagetitle?></h2>
<ul>
<? foreach($DATA as $row): ?>
<li><?=$row['name']?></li>
<? endforeach ?>
<ul>
this way you'd need no index with includes at all
I want to use php to easily maintain my website, but I simply can't figure out the language - I've found some tuts online, and some other questions here, but none help me.
I've divided my site into some .php files, header/footer and such - And using
works fine..
Now I want the content of my site, to update according to which menu I click on at my site.
http://dawtano.com/pp/
If I click on "about" I want the "Hello World" to open inside my content div, but I can't get the right php code to do it.
I think you should do this---
Note: This will only work if the CSS styling are on the current directory! ()
<div>
<?php
$html_page = implode('', file('http://dawtano.com/pp/'));
echo $html;
?>
</div>
Hope this helps!
well currently your links are taking you to a separate page entirely. So why not just code it so that your include file is specific to the page. i.e, on about.php, use something like
include 'about_content.php
in your contetnt div.
If you're looking for your content to load dynamically into the content div you'll need to look into using ajax to fetch the content pages.
One popular way to construct the site is to have a single php script which displays content based upon a $_GET variable like 'page' or 'content', and then make the link as:
'http://dawtano.com/pp/index.php?page=helloworldcontent'
Using this method, you would need to check if the variable ($_GET['page']) is set using isset(), and then make sure the string is safe... as anybody with a browser could just type in some mumbo-magic script and hijack your site:
'http://dawtano.com/pp/index.php?page=somecleaverlycraftedhax'
Once it exists and is safe, add the '.php' to the file name and include that file... if it exists! If it doesn't exist, then you will need some code to handle that, probably by displaying a 'File not Found' message, or redirecting home, or something.
I prefer not to do this because it is a pain to make safe, and I feel like it is pretty ugly. What I do instead is put all the header/footer/navbar/title bar scripts into seperate 'display' functions, and put them in another file.
Then include this file with the function definitions, and call all the 'display' functions to set up the page. So every php script in your site might look like:
<?php
include 'html_display_functions.php';
/* put lines here to parse $_GET and $_POST, session_start()/$_SESSION, etc... */
print_html_pre_content();
print '<p>Hello, world!</p>';
print_html_post_content();
?>
Since every script will have this structure, you can just create a template file once. When you want to create a new page for your site, copy the template, rename the copy to the php filename you want, and add content between the two print functions.
You also keep the ability to modify the header/footer/navbar/title bar for the whole site in a central location, namely the included file with the functions.
You might be looking for some sort of Template Engine which allows you to create your pages out of variable parts. You could have a look at TBS, which is more or less what is suggested by the name. But there is a whole lot more engines out there which could do the job.
If that's already too much over the top, maybe Apache SSI (Server Side Includes) are a try for you.
A little suggestion from my side, I am often using Apaches mod_rewrite in connection with a single controller.php file. Apaches mod_rewrite will then send all request to the controller.php which will fetch the appropriate page parts for the requested page using TBS and return the respective page. So you have the controll of the page in one location only.
To your original question about.php could look like:
<?php
include('header.php');
?>
// original page content as html for about.php
// assuming header ends with the starting div <div> where you like the content to appear
// and footer starts with the closing div </div>
// if you need variable content here, simply use <?php echo $your_variable ?>
<?php
include('footer.php');
?>
The best way would be to use a switch statement:
http://php.net/manual/en/control-structures.switch.php
Something like this:
<?php
include("header.php");
$page = $_GET['page'];
switch($page)
{
case "about":
include "about.php";
break;
case "faq":
include "faq.php";
break;
case "help":
include "help.php";
break;
default:
include "home.php";
}
include("footer.php);
?>
Then just make all of your links look like this:
http://www.example.com/index.php?page=home
Just replace home with the correct page.
I'm currently using include 'header.php' and include 'footer.php' in every page, and as far as I know that's how most people do it. I thought of a way that I personally thought would be better, however. I thought of making index.php, then in the index include the page. This would both eliminate the need for a footer and eliminate the need for include twice in every page. I'm really new to php, however, so I don't know how I would do this. I tried using POST and GET methods, but it doesn't seem to work. What I want to achieve is including pages in the header using a URL such as http://mysite.com/index.php?page=history and then load history.php. If I need to clarify something, just ask. Sorry if I don't accept an answer right away, I'm really drowsy. I'll get to it when I can.
It is not a problem if you include 2 pages in a file, like header.php and footer.php...
Just writing 2 lines of code in each page is not a matter.
You can decide what pages you want to include dynamically in every page by using if statement, instead of passing the page name in the url.
If you'll do it via index.php, you will no doubt do it wrong.
Nothing bad - every newbie does it this way.
Just because you're thinking of includes, while you should be thinking of templates.
You can make it via index.php, no problem. But there should be not a single HTML tag in this index! As well as in the actual page.
No matter if you're doing it in separate pages or via index.php, the scenario should be the same:
Get all data necessary to display particular page.
Call a template.
Thus, your regular page would look like
code
code
code
include 'template.php';
while index.php would look like
get page name
sanitize page name
include page
include 'template.php';
now you can decide what to choose
First off i agree with Meager... Take a look at soem frameworks. Most will use a two step view which essentially does this althoug in a more complex and flexible way.
With that said it would look something like this:
<?php
$page = isset($_GET['page']) ? $_GET['page'] : 'home'; // default to home if no page
if(file_exists($page.'.php')) {
// buffer the output so we can redirect with header() if necessary
ob_start();
include($page.'.php');
$content = ob_get_clean();
}
else
{
// do something for error 404
}
?>
<html>
<head></head>
<body>
<?php echo $content; ?>
</body>
</html>
You could get more complex than that. One thing you want to do uis make sure you dont blindly assume that the page in the $_GET var is safe... make sure the file exists on your server or otherwise sanitize it...
On a WAMP server, I have a server-side include in a file, a.shtml, composed of the following code:
<!--#include virtual="./req.php"-->
The contents of req.php are:
<?php
Header("Location:index.php");
echo "still here";
?>
When I open a.shtml, I see the text still here, but the page has made no attempt to redirect itself. Why is this? And is there any way to make it work?
Thanks for the help
EDIT: The reason I want to do this is because I have some session variables that I want to influence the way the PHP script acts. If the session variables are not set, I need it to redirect to a login page. I know I can just write the entire thing in PHP, but I'd like to do it this way if possible. If it's not possible to change header information from an included PHP file from SSI, then I'll just do it entirely in PHP.
it's impossible
you don't need that.
just address tour script that set session variables directly, not through ssi
MAYBE (with capital letters Lol), you can pull this off if you call that script in an IFRAME and that IFRAME outputs some JScript like window.parent.location = <some_url_here> forcing its parent to change its location... Its just fast-thinking from my part, I might be wrong with IFRAMEs' parent-child relation to the original document, as I haven't tested the "idea" myself :)
If your req.php returns the following html code, the redirect will happen:
<html><head>
<title>HTTP 301 This page has been moved</title>
<meta http-equiv="Refresh" content="0;URL=https://www.example.com/index.php">
</head>
<body></body></html>
But: "Google Warning: Using The Meta Refresh Tag Is Bad Practice"
If jquery is added in globally used header.php across the site then How to stop to load jquery library only for those pages of site which doesn't need actually? If we can't use more than one header.
purpose of question is to not to penalize those page with slow loading which actually don't need.
Your site shouldn't need more than one global-header, if you opt to even use headers to begin with. If it does, just include jQuery on all pages. It's a small cached file, it won't hurt the browsing experience.
By using the google-hosted version, it may be the case that many of your uses already have it cached before they even reach your site.
I have been guilty of pounding my fist into the nail while asking everyone else to move the hammer that's in the way...
Why not tackle the problem from the other end and use jQuery to optimize the first load?
If you have big pages that are already taking a while to download, why not section off the less-performant areas and use $().load() to fill those in?
The page will load quicker (better user experience) and you don't have to be adding any additional processing to pages that don't need it.
Cheers,
-jc
assuming you are loading the jQuery file from a correctly-configured webserver (or from google's CDN), it will be cached and not re-downloaded on each page. Assuming a visitor will hit at least one page on your site that needs jQuery then you really won't gain anything by trying to remove it from loading on pages that don't use any javascript features from the library.
First, use the compressed jquery for production. It's much smaller. Second, IIRC, once jquery is downloaded with the first page, it will be cached and won't need to be retrieved from your server for each subsequent request.
Otherwise, if you really need to explicitly load jquery only on those pages that need it, you would have to have some way for the body of your page to tell header.php that it doesn't need to load jquery. If header.php is loaded before "body.php" then that's pretty hard to do without some fancy output buffering or such.
If you're using a templating system like Smarty you could have a conditional in the master page template to check a $loadjquery flag that you set in body.php before sending the whole page off to be rendered. But that's complicated too.
Your question is very general, some specific would be great, maybe even a link to the site. Personally if you are using a CMS I would try to make some sort of "flag" for that page, or if you are simply loading a page and then loading the header from that page, insert a variable before you load the header and use that as your flag for loading jQuery.
An example:
If a user wants to see www.mysite.com then the following file would be loaded: www.mysite.com/index.php with the following code:
<?php $needJQuery = true;
include('header.php');
echo 'content will go here';
include('footer.php'); ?>
header.php would include something such as this:
<?php if ($needJQuery) { ?>
<script src="/jquery/jquery-min-3.2.1.js" />
etc. for all the content that you need above/below.
<?php } ?>
For the pages that don't need jQuery loaded, you would either leave $needJQuery undefined or you would do as follows:
<?php $needJQuery = false; ?>
Hope this helps,
As stated earlier, modify the header file so it'll check for the presence of flag variable and only output the jquery headers if needed.
If you don't have the ability to modify the header file, you could load it with output buffering turned on and filter the output before it heads out to the client:
<?php
ob_start();
include('header.php');
$header = ob_get_flush();
$cleanheader = some_operation_that_removes_the_jquery_script_tags($header);
echo $cleanheader
?>