Forum Moderators: coopster
I've a few 'do I understand/have I got this right queries?'
My .html pages are now renamed to .php.
Previous hard-coded elements have been removed and saved to a text file (example: file.txt) - to be called with this code:
<?php include('file.txt');?>
Seems good to me.
Instead of previous code like
<a href="/" title="load the front page"><img src="/graphics/logo/logo.gif" width="208" height="50" alt="logo" /></a>
I now have <?php include('logo.txt');?>
Smaller page. Easier to understand.
And if I change the logo/link/whatever I just need to change the .txt file and not individual site pages. Why did I not do this before? Duh.
Question...
I've also seen .php, .inc and .htm or .html used instead of .txt.
Why? What's the difference? Advantages?
Where the include files are in a different directory to the webpage, I'm having some issues with naming the path.
I prefer to 'work with a leading slash' - so everything works relative to the root. This way, in avoiding relative nonsense like ../../ my links work and images get called from the correct place.
Doesn't work with includes though - presumably using a local path like /homepages/[username]/htdocs/. Ugly. Cumbersome. Alternatives?
Relative like ../ doesn't work. Good - too prone to error.
Absolute with [[domainname].com...] works.
As does
include $_SERVER[DOCUMENT_ROOT]."/includes/file.txt";
Slightly better. Still not ideal.
Question...
Is there a way to config so's I can use a simple leading /? .ini or .htaccess possibly?
Question...
Do viewer's browsers cache the includes? Thereby speeding page load? And, once a complete page (with includes) has been loaded, is the whole thing cached?
Question...
If includes are cached, am I thereby saving bandwidth?
the pages can be called seperately depending on their file types. e.g. .html file will act as a normal web page, .php will be processed at server-side, .txt will display the normal ASCII texts etc.
>> Do viewer's browsers cache the includes? Thereby speeding page load? And, once a complete page (with includes) has been loaded, is the whole thing cached?
php includes are processed at server-side. So when you inlude a page in php, it becomes a part of the calling page when its presented to the client browser. So only the final output will be cached (as a single page)
>> .php will be processed at server-side, .txt will display the normal ASCII texts etc.
So, if the file just contains html code, should I name it ,php, .inc or .txt?
>> So only the final output will be cached (as a single page)
So, it's effectively 'neutral' then. No savings on a regular static page.
I think .html would be better, cos you can use it both ways. If you think the file will not be used seperately go for .inc or .txt.. there's no difference between them.
>> So, it's effectively 'neutral' then. No savings on a regular static page.
capacity wise yes. but we are talking abt php, it's main use is to create dynamic pages. and includes are used to add either dynamic or static content within the calling page. so if you don't have anything dynamic to create then of course there is no need for php or includes. just go static.
>> Am I right in thinking the includes increase server load compared with a regular hard-coded html page.
obviously server-side processing (in this case, php) has to be done in the server, hence the server load would be a bit greater than that of a static html page (this difference is really insignificant for a simple php script). But in the real world php is much faster than many other server-side languages..so unless you are trying to include something like 50 pages at once, there will be no problem at all.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime('yourincludefile.txt').' GMT'); (before you've output anything)
If you don't want to do this, don't worry too much - your pages will seem a bit slower when going back, since they're not cached, but very few dynamic sites bother to muddle with cache-informative headers. Apache serving up static html pages does a fine job in general, but with php it becomes a whole new can of worms. Since you just have files that are included, this isn't so hard, since we just have to send back the last time the file was modified.
>> If you think the file will not be used seperately go for .inc or .txt.. there's no difference between them.
The files simply contain html code clipped from the previous hard-coded pages. As I'm now sold on the ease and speed of site-wide changes by using includes (similar to CSS versus tag soup) I can't see them being used alone.
>> ... if you don't have anything dynamic to create then of course there is no need for php or includes. just go static.
It's that ease-of-change flexibility that appeals.
>> unless you are trying to include something like 50 pages at once, there will be no problem at all.
There's maybe 10 elements... the 'head' content then the 'body' - header/navbar/main/footer etc
Thanks again. You;ve helped me understand this better.
Is there an easy solution to the path issue?
Not really, if you are on any kind of unix box, file seeks are very fast and the advantage of using includes are bigger than the small increase in disk seeks/reads. Also, chances are the files will be served direct from server cache in which case the overhead is next to nothing. What you can do to improve performance is, for example:
If you have a header and a footer section that is served on a lot of pages you can combine the two files into one include file and assign them to a variable in a php file, like:
include("$_SERVER[DOCUMENT_ROOT]/inc/header_footer.php);
Content of header_footer.php:
<?
$header = "Hello and welcome";
$footer = "copyright mr. foobar";
?>
You can then include the file at the top of your pages and echo the contents where you want...
$echo "$header";
// Body content here
$echo "$footer";
Last, if a page have not been modified the browser will take that *page* from cache if visiting the page again, irrespective of the fact that some content was delivered actively from an include file. But do note that if the browser loads a new page, the include is incurred again as this happens server-side (unlike an external css or js file called in html header, which is taken from browsers cache if not modified).
Nick
>> It's that ease-of-change flexibility that appeals.
I agree. There are different opinions on that, but if it serves you well, then there is nothing to worry.
>> Is there an easy solution to the path issue?
Well, I wouldn't call it exactly a solution, cos most of what you posted are actually solutions for this. I personally do not recommend editing php.ini just because the code looks 'ugly' using /home/username/public_html/file.php or $_SERVER[DOCUMENT_ROOT] for that matter. These are what most of the programmers use. Unless ofcourse you declare a global variable which has the root path that will eliminate the for $_SERVER[DOCUMENT_ROOT].
Storyman,
there is no particular difference when a file is named as php or html when the contents are in pure html code. PHP has nothing to process in them, so everythng is displayed as it is.
A couple of queries...
> user can directly access an html or txt file. A php file cannot be directly accessed by the user, which prevents them from opening and reading the file.
Hhhmmm. My browser happily opens a .php file. But .inc produces a 403... and it doesn't display includes when called from a .inc file. Perhaps this is server specific?
As the only content is stuff which is then inserted into the webpages, am I right in thinking here's probably no problem with viewers calling and opening the includes?
>last modified headers...
Using them seems easy and sane - except I don't know how. Do I add code to the includes to achieve this?
>Last, if a page have not been modified the browser will take that *page* from cache if visiting the page again, irrespective of the fact that some content was delivered actively from an include file.
Starting to get beyond my understanding now - so perhaps the 'last modified' isn't so important... but if it's easily done then seems sensible.
And that include/echo is sweet.
Thanks again, all.
And, which of these is correct/ Or both?
<? include $_SERVER[DOCUMENT_ROOT]."/inc/file.txt";?>
<? include($_SERVER["DOCUMENT_ROOT"].'/inc/file.txt');?>
I'm interested in anything that produces the cleanest code and saves having to repeat stuff. And it's likely that sometime I'll forget and simply have a leading / and hence screw the path.
So how do I 'declare a global variable'?
>there is no particular difference when a file is named as php or html when the contents are in pure html code. PHP has nothing to process in them, so everythng is displayed as it is.
Ah - that covers it.
Thanks.
I was referring to an approach that requires a bit of understanding on Variable Scopes [php.net]. However, If repitition is what's bothering you, the best thing to do is store the path in a normal variable like
$root = "/home/username/public_html/"; or
$root = $_SERVER[DOCUMENT_ROOT]."/";
and use it as
include($root."inc/file.php");
It's pretty much the same approach, but with less coding. You have to compromise on things like these cos sometimes you cannot go beyond the limits set by the language. I hope it pulls out favorably. :)
Like:
Make a file: inc/config.php and place all your global variables that you use on every page;
<?
$host = "localhost";
$database = "your_database";
$db_user_name = "user)name";
$db_password = "password";
if (! ($link = mysql_connect ($host, $db_user_name, $db_password))) {
echo "Connection Error: ".mysql_error();
die("");
}
if (! ($db = mysql_select_db($database))) {
echo "DB Select Error: ".mysql_error();
die("");
}
$root = "$_SERVER[DOCUMENT_ROOT]" . '/';
include("$_SERVER[DOCUMENT_ROOT]/inc/header_footer.php);
?>
And then at the top of every page you just call this one file to make all available:
include("$_SERVER[DOCUMENT_ROOT]/inc/config.php");
Arguably you still have the $_SERVER[DOCUMENT_ROOT bit but that's it, rest is clean and clear. I would not recommend changing paths in PHP, they are there for good reasons to protect the content of your server.
I have 7 years of PHP experience and this is actually pretty much how it's done, you'll probably discover that you'll have anonther file later for all your functions (inc/functions.php) that gets called along with config.php at the start of every page, that can come later...
Nick
i.e.
include "/inc/stuff.php";
Goes back to the server's root doc directory, then into "inc", then finds the page.
Likewise, these also work fine for me:
include "inc/stuff.php"; # moves into "inc", finds doc
include "../inc/stuff.php"; # out one, "inc", find doc
Also, yes, the reason your browser can read PHP files but not INC files does have to do with how the server is configured. PHP files are explicitly included in the config in order for the server to handle them properly. INC files are probably not in the config file, because they have no special MIME type, and use the generic "INC" extension. You could use the ".fudge" extension with the same result.
The way PHP include works is to simply find and include the file. What the file contains and how it is handled by the server are of no consequence to the include function. It's a go-getter, not a see-what's-insider.
Yes,
include "/inc/stuff.php";
include "../inc/stuff.php";
Normally works great as it is in the same path as the script, but there was talk about changing php.ini so maybe going back to basic sound programming practices is a good direction?
Anonther interesting issue that has cropped up is the .inc file, it's very easy to make it function as a PHP file, just create a text document and name it .htaccess and add the following line:
AddType application/x-httpd-php .php .php3 .php4 .inc .html
Save the document and upload it to the root of your server (Apache) and you'll find that both .inc and .html are parsed as PHP, if there are any PHP tags present, otherwise just as their normal types. I've even done this with gifs and set a cookie remotely before serving up the pic...
Would not say that the include() function is a "a go-getter, not a see-what's-insider" function, it very much does and parses any php tags it finds, to do a straight pass-through use fpassthru().
Nick
but what I can understand from the thread starters posts is that all he needs is to make a template (dynamic) that eliminates the need to add the same html code on each page. and probably make it easier to edit 'em. (a changeover from static to dynamic)
gulliver : "It's that ease-of-change flexibility that appeals."
I don't think he really uses any php functions or db's other than the hightlightd include().
Absolutely.
There's some stuff mentioned here that sounds great - and too complex for me to implement personally.
I'm sure I'm not the only one who's thought of 'going dynamic' then abandoned it because they weren't sure how best to to it or had problems.
I've spent some/a little time and effort trying to understand enough to be able to cut/paste code so's it works. The in-depth complexities make my headache.
I'm really appreciative of the help you've all provided - hopefully it'll help others too. My 'outstanding' query is 'the path thing'...
>store the path in a normal variable like
$root = "/home/username/public_html/"; or
$root = $_SERVER[DOCUMENT_ROOT]."/";
I've tried it in the html page and the file.txt - it either breaks out onto the page or doesn't work. Clearly I'm doing something wrong, so clarification will really help.
Lightbulb now burning - perhaps too bright.
Using your code as-is presents some problems with the structure of my html pages - though I hope I have a work-around.
The structure of the body of my html page is simply a list of CSS divs - within each of which is a php call. Example:
<div id="header"><? include($_SERVER[DOCUMENT_ROOT].'/inc/header.txt');?></div><!-- header ends -->
<div id="main"><? include($_SERVER[DOCUMENT_ROOT].'/inc/main.txt');?></div><!-- main ends -->
<div id="footer"><? include($_SERVER[DOCUMENT_ROOT].'/inc/foopter.txt');?></div><!-- footer ends -->
(This way, I get a very simple 'structure only' html page - and a bunch of external txt files with all the content. I can look at a page and not get lost - and make site-wide changes simply and speedily.)
With nested divs, my structure is more complex than this and hence I'm reluctant to modify it use your code as-is...
<?
$root = $_SERVER[DOCUMENT_ROOT]."/";
include($root."inc/file.txt");
include($root."inc/file2.txt");
?>
I could include the div tags within the include files - but I'd rather not as it makes the code messier.
Instead, I've tried a variant which seems to work - I need to know if it should and whether it's reliable or not.
In the head of my html page, before any other include calls, I've used
<? $root = $_SERVER[DOCUMENT_ROOT]."/";?>
The include calls then take this form...
<div id="logo"><? include($root."/inc/logo.txt");?></div><!-- logo ends -->
I've also included the content of the head section (meta tags, links to external CSS and js files, fav.ico etc).
It all works. Is this OK?
COMMENT
Well, can see that the discussion has moved on but decided to keep the post as someone might learn ;o)
Staying in topic is a good thing, thanks for getting things on track.
I actually created files named "test.php" and "logo.txt", put in your stuff and placed them in the root of my development server, including the "logo.txt" file with your html code and you know what?, I got a fat open_base_dir restriction error because I have error display set to "on" in the php.ini so all errors pops out on the screen.
Changing:
<? include(logo.txt);?>
To:
<? include("logo.txt");?>
This solved the problem, you can see it by going to:
[nbrandt.com...]
Contains -> <? include(logo.txt);?> WRONG, chucks the dunny.
And:
[nbrandt.com...]
<? include("logo.txt");?>
Contains -> <? include("logo.txt");?> COOL, finds the file and gets on...
Sorry about not catching this earlier, includes are not really used like this normally so bear with us and don't give up :o)
The closest I can come to an explanation is that as of many years qoutes always delimitets input so you know that:
"foo bar"
is not foo AND bar, they are encapsulated by the qoutes and HANG together as far as a computer is concerned because they are inside the double qoutes(how else would it know?)...
OK, by saying that double qoutes interpolates data and single qoutes doesn't one more step is taken so:
$var = 1;
echo "$var";
outputs 1
$var = 2;
echo '$var';
outputs $var
This is because the data is not interpolated (worked on by php) because of the use of single qoutes.
Along this line, having no qoutes is also mostly accepted and a default is used. It seems like this caused the problem in this instance as php probably split the txt file on the "." and then couldn't find the file it thought was named "logo"... with a forced definition using double qoutes it knows how to handle it and literally looks for "logo.txt".
So to a computer:
foo bar => foo and bar, just two bits of different three digit text that can break things in a script for sure.
"foo bar" => foo bar hanging together because of the double-qoutes and php interpolates it to see if it is the value of a variable.
'foo bar' = > foo bar hanging together and interpolated explicitly, php otputs the exact text, even if it is $foo_bar, for example.
To touch a bit deeper without drowning, it's very much about ASCII (text) delimiters, the underscore "_" keeps text symbols together whereas hyphen "-" doesn't and is much the same as a space " " or a full stop ".". Double qoutes and single qoutes are there to keep'em together and understanding them and using them is a good idea ... well, so is using DOCUMENT_ROOT but that is another story...
Nick
I still maintain the "go-getter" include() description.
It's the server that does the parsing of the file when the request is made by the include(). The include(), itself does not parse the file.
Your comment about the .htaccess file demonstrates what I mean: Without explicitly instructing the server to parse .inc files via PHP, they are simply text files (or whatever the server default type is), and any PHP in them would not be parsed.
You are correct, of course, about using .htaccess to override or supplement the server config on a per-directory basis.
I'm not trying to be persnicketty, but I'm gonna stand by my original statement, for now.
What's the difference to the web server between these:
$_SERVER[DOCUMENT_ROOT] and /?
A leading slash already indicates the document root.
i.e.
$_SERVER[DOCUMENT_ROOT]."/inc" and /inc indicate the same directory, one subdirectory into the document root.
Thanks!
PS: I do realize that aliasing can modify the interpretation of the leading slash, i.e. /cgi-bin is actually outside the document root, but the ScriptAlias is what defined that particular path. I'm referring to directory references within the document root. And ... it just now occurs to me that you might be using the PHP ref for scripts, etc. which are outside the docroot, and may make this question moot, as that is the point of the PHP ref ... Okay, it feels like that's what you're doing, and I'm looking dense ... Right? However in the context of the original post, and continuing posts that do not indicate using a directory outside the normal server structure, then I still fail to see why gulliver could not simply use the leading slash for his docroot ref.
In the frontend yes, (like html, where the files are virtual). But php runs in the backend, the only way include() could process both "disk path" & "url path" is by explicitly declaring them. So have you ever got include() to work with "/" within a directory tree? In my experience, I only get a php exception. But as the theory goes, it should work with virtual(), which could be an alternative in this case.
Gulliver>> It all works. Is this OK?
Absolutely fine, but I noticed you are using the same forward slash twice. (At the end of $root, and at the begining of the file name in include(). take off one of them.
$root = $_SERVER[DOCUMENT_ROOT]; //stripped the trailing slash
<div id="logo"><? include($root."/inc/logo.txt");?></div>
<!-- logo ends -->
Thanks. 'My eyes are dim, I cannot see'... in all the excitement I missed that. Duly corrected. Sort of.
My server chokes and spits an error message (Parse error: parse error, unexpected ';' in [page url] on line 4) if I use
<? $root = $_SERVER[DOCUMENT_ROOT].;?>
So I'll have to use
<? $root = $_SERVER[DOCUMENT_ROOT]."/";?>
and instead remove the leading / from the individual calls.
No idea why, but I've noticed some servers ignore extra / in the url and still deliver the page.
A couple further queries (and then I promise to leave you alone)
Is this case sensitive?
$_SERVER[DOCUMENT_ROOT]
And, is there a way to store
<? $root = $_SERVER[DOCUMENT_ROOT].;?>
in an include file and call it before the others with something like thi sin the head:
<? include($root."/inc/config.php");?>
[edited by: gulliver at 7:30 am (utc) on Sep. 10, 2004]
About declaring $root in a seperate file, that's fine too. I think a previous poster did mention abt it. It could also be helpful if you need to add common variables (gobal scope) in the future. However, you CANNOT call it in the following way.
<? include($root."/inc/config.php");?>
<? include($_SERVER[DOCUMENT_ROOT]."/inc/config.php");?>
there. It's upto you to decide, whether you really need this additional page or not. Let us know what u come up with.
Thanks. I decided on the extra page - it keeps the code 'more uniform' and has that extra flexibility to add other stuff should the need arise.