Is putting everything through index.php a bad idea?

Hi,
just begining to code up our new site and wondering about doing things slightly differently this time. If i use .htaccess i can hide index.php and run everything through it using variables. Eg www.example.com/beach would actually be www.example.com/index.php/beach

I think this is how Drupal etc must do it?

Would this cause major issues if a lot of people want to visit my site at the same time or is that not a problem.

This is my code so far. It’s basically looking at the URL and depending on the variable is including a different part of the template.

Can anyone see any problems with doing it this way? Is it ok to output a 404 not found and still load the rest of the template?

any thoughts appreciated. thanks

<?php 
//lets start the session as we will need it to remember beaches
session_start(); 

//include the database connections
require_once('connection/connect.php');
?>
<?php
//defualt theme
define("theme","sand",FALSE);
?>
<?
//use the variables in the URL string for the query
if ($_SERVER['REDIRECT_PATH_INFO']) $_SERVER['PATH_INFO'] = $_SERVER['REDIRECT_PATH_INFO'];
$data = explode("/",$_SERVER['PATH_INFO']);
$url1 = $data[1];
$url2 = $data[2];
$url3 = $data[3];

//Function to clean the strings
function clean($str){
  return addslashes(preg_replace("/[ \t\r\n\+]+/"," ", $str));
} 
list($url1,$url2,$url3) = array_map('clean', array($url1, $url2, $url3)); 
?>
<?php
//set the page default if not option apply
$page = 'content.php';


//now we need to check if any of the variables being sent in the url actually exist and if not thow an error page.
if(!($url1 =='')){

//check for beach if 
if($url1 == 'search-results'){
//specify which page template to use
$page = 'search.php';
}
elseif($url1 == 'beach'){
    
    if($url1 == 'beach' && $url2 ==''){
        //specify which page template to use
        $page = 'beach.php';
    }
    if($url1 == 'beach' && $url2 !==''){
        $page = 'beach.php';
    }
}

//check for beaches
else
{
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
$page = 'error.php';
}



}
?>
<?php 

//get the current theme
include('themes/'.constant("theme").'/templates/header.php');
include('themes/'.constant("theme").'/templates/banner.php');

//change the main part depending on the url variable
include('themes/'.constant("theme").'/templates/'.$page);

//include('themes/'.constant("theme").'/templates/content.php');
include('themes/'.constant("theme").'/templates/footer.php');

?>

ah just realised that i am going to have a problem with my logic.

if i do a query in beach.php and i need it to be not found then i can’t output the header before the page is output.

hmm will have to think a bit more

Because you should execute your page code before any output.
Example:

index.php

// execute controller (page):
$page = 'beach.php';
$output = include($page);

// render final output:
include('header.php');
echo $output;
include('footer.php');

beach.php

ob_start(); //enable output buffering
echo '<p>Result HTML</p>'; //render your html as usual, it will be printed into buffer
return ob_get_clean(); //return output buffer contents

With this approach you can send any headers inside your beach.php as it will be executed before any output.

thanks for the reply.

Maybe my lack of understanding but won’t that still not output before the page content is returned. In the case of wanting to return a 404 page not found if i did a query and no beach was found, would the header

($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
$page = 'error.php';

work within the $output variable before it is output below the header.php. Wouldn’t it have already started to output the page before the call for 404?

Does using the index.php page to generate all the pages in general seem an ok way to do it?

thanks

ah did a bit of research on output buffering http://stackoverflow.com/questions/4401949/whats-the-use-of-ob-start-in-php and if i understand correctly i think i understand your example now.

the one reply on SO was

Using ob_start allows you to keep the content in a server-side buffer until you are ready to display it.

This is commonly used to so that pages can send headers ‘after’
they’ve ‘sent’ some content already (ie, deciding to redirect half way
through rendering a page).

which makes sense. Didn’t know it was possible, learn something every day. (or 2 things today as also learnt that IE won’t display a custom 404 page if its below a certain file size!)

No. If you’re doing echo after ob_start() it doesn’t actually output anything to the browser. This output going to the internal buffer instead. And you’re fetching content of that buffer with ob_get_contents() and use that content later, when you ready to send it to browser.

Look at this simple code to understand it better:

ob_start();
echo "First echo.";
$first = ob_get_contents();
echo "Second echo.";
echo $first;

it will output: Second echo.First echo.

Sure. Most of modern web apps does that.

PS: i used ob_get_clean() in my first post, that is wrong, correct function is ob_get_contents()

Hi,
so i’m kind of understanding a bit more now, although it doesn’t seem to work at the moment when i try

<?php
ob_start();
echo "First echo.";
$first = ob_get_contents();
echo "Second echo.";
echo $first;

?>

it outputs ‘First echo.Second echo.First echo.’ (http://test.goodbeachguide.co.uk/working/test.php).

any thoughts as to why this would happen?
thanks

Use ob_get_clean() instead of ob_get_contents().
I was right in my first post and wrong in second :smile: Just confused myself, sorry

ah ok cool that works. So now to the more complicated problem of including a different file with it in…

I am currently outputting a ‘1’ for some reason instead of the text. Is that some kind of reference to which output buffer it is?

This is the include page (next.php)

<?php
ob_start();
echo "hello world";
return ob_end_clean();
?>

This is the primary page

<?php
// execute controller (page):
$output = include('next.php');


// render final output:
include('../themes/sand/templates/header.php');
//echo something so i can see where we are on the page
echo 'lemons';
echo '<br>';
//echo the buffer
echo $output;
include('../themes/sand/templates/footer.php');
?>

If just outputs ‘1’ under ‘lemons’??

if i put it all on the same page it works? any idea why when it’s an include it doesn’t work correctly?

thanks for your help

There should be ob_get_clean() in next.php, not ob_end_clean()

awesome thank you so much. Seems to work now. Seems a really useful function which i will need to read a lot more about as i think it will come in handy.

thanks

So got this all working in a basic form. Had to do a bit of thinking and trial and error to be able to include the error template within the included files but got there in the end.

Next problem though is how to get the meta data into the header template.

I think the only way i can do it is include another file which holds (queries) the required info. But am i missing a trick somewhere.

Is there a way of returning one part to the $output and other parts to $page_title and $page_description etc from the same file?

You can store that values somewhere (i prefer static class).
For example:

index.php:

require('page_class.php');

$page = "content.php";
$output = include($page);

include("header.php");
echo $output;
include("footer.php");

content.php:

<?php
    Page::setTitle('My page title');
    ob_start();
?>
<p> Hello world! </p>
<?php return ob_get_clean(); ?>

header.php:

<html><head>
    <title><?php echo Page::getTitle(); ?></title>
</head>

page_class.php:

class Page {

    private static $title = 'Default Title';

    public static function setTitle($new_title){
        self::$title = $new_title;
    }

    public static function getTitle(){
        return self::$title;
    }            

}

oh cool that’s awesome. Didn’t know that existed either… i guess that’s why i asked :slight_smile:

thank you so much for your time.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.