Using variables before include()ing them - php

I'm using a file, page.php, as an HTML container for several content files; i.e., page.php defines most of the common structure of the page, and the content files just contain the text that's unique to every page. What I would like to do is include some PHP code with each content file that defines metadata for the page such as its title, a banner graphic to use, etc. For example, a content file might look like this (simplified):
<?php $page_title="My Title"; ?>
<h1>Hello world!</h1>
The name of the file would be passed as a URL parameter to page.php, which would look like this:
<html>
<head>
<title><?php echo $page_title; ?></title>
</head>
<body>
<?php include($_GET['page']); ?>
</body>
</html>
The problem with this approach is that the variable gets defined after it is used, which of course won't work. Output buffering also doesn't seem to help.
Is there an alternate approach I can use? I'd prefer not to define the text in the content file as a PHP heredoc block, because that smashes the HTML syntax highlighting in my text editor. I also don't want to use JavaScript to rewrite page elements after the fact, because many of these pages don't otherwise use JavaScript and I'd rather not introduce it as a dependency if I don't have to.

Most people store the output of the included page into another variable. Have you tried putting all the content of the included page into the output buffer, then storing the ob_get_clean() into a variable like $page_html, then having your page look like this:
<?php include($_GET['page']); ?>
<html>
<head>
<title><?php echo $page_title; ?></title>
</head>
<body>
<?php echo $page_html; ?>
</body>
</html>
Edit: So the second page would look something like this:
<?php
$page_title="My Title";
ob_start();
?>
<h1>Hello world!</h1>
<?php $page_html=ob_get_clean(); ?>

The best thing I can think of would be to separate the inclusion of the file from the rendering. So your template looks like this:
<?php include($_GET['page']); ?>
<html>
<head>
<title><?php echo $page_title; ?></title>
</head>
<body>
<?php renderPage() ?>
</body>
</html>
And the file you are including looks like this:
<?php
$page_title="My Title";
function renderPage() {
?>
<h1>Hello world!</h1>
<?php
}
?>
This is also nice since you can pass parameters to renderPage() so that the template can pass info along to the page it is including.

Related

Is PHP Compliable with CSS?

i was wondering if i could use this command:
<?php
include_once "example.css"
?>
inside a PHP file so for example:
<!DOCTYPE CSS>
<?php
include_once "example1.css"
?>
<?php
include_once "example2.css"
?>
<?php
include_once "example3.css"
?>
I want to use this because the website I am trying to make is about 8000 lines of CSS long and I want to break it up into multiple CSS files for example about.css, footer.css etc. but the problem is when I try to link 10 different CSS files to one of my pages it glitches out because I have to many linked so can I do the above example with CSS and PHP?
One way to include a bunch of css files would be like so:
<?php
$css = [
'example1.css',
'example2.css',
'example3.css'
]
?>
<!DOCTYPE html>
<html>
<head>
<?php foreach($css as $file): ?>
<link type="text/css" rel="stylesheet" href="<?php echo($file) ?>">
<?php endforeach; ?>
</head>
<body>
<!-- Your content -->
</body>
</html>
BTW, there is no "CSS" doctype - a doctype always denotes some kind of HTML/XML document:
https://developer.mozilla.org/en-US/docs/Glossary/Doctype
Also, you might want to read about the basic structure of an HTML document:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Document_and_website_structure
Regarding the foreach syntax used above, see:
https://www.php.net/manual/en/control-structures.alternative-syntax.php
Yes, you can do this.
You can include any type of file, and it will be treated as if it were in inserted into the PHP script outside a <?php ?> section. So if the file doesn't contain any <?php, it will just be output literally.

web page slightly altered from index page

The question is fairly simple, yet I've been looking around for an hour and found nothing:
make a page that is exactly the same as the home page, but a specific div has altered content
example index.html:
<html>
<head>
<title>title</title>
<style type="text/css">
/* css goes here */
</style>
</head>
<body>
<div id="stay">I wont change</div>
<div id="change">I will change</div>
</body>
</html>
so I want to be able to code a page so that it inherits the entire html from the index page (WITHOUT COPYING THE CODE), but a specific div (here with the id #change) to have different content. How would I go about doing this?
You don't really "inherit" code snippets, but I understand that you're trying to reuse the page content. From your posted code, it's hard to tell exactly how the change differs from the index. Is it just a content change or does the index page not have that div?
You have a couple of options. If just the content of the div is changing, you could use the same php page and then use jquery to change the content of the div, so something like
index.php
<? php include("page.php"); ?>
other page
<? php include("page.php"); ?>
// javascript to modify div
You could break the page into chunks and just include them as needed, so you could have a top.php and a bottom.php, and the index page could do
<? php include("top.php"); ?>
<? php include("bottom.php"); ?>
And then your similar page could do something like
<? php include("top.php"); ?>
// custom stuff here
<? php include("bottom.php"); ?>
If neither of these solutions work you could always use a templating engine to create a page template, though that may be a little much for your situation.
I see you have tagged this question in php So, I will give you answer inclusive of php implementation.
Create 3 pages. index.php about.php and foo.php
The objective is to show some content in index.php but all content in about.php
Call this page foo.php
<html>
<head></head>
<body>
<p> Show this in index.php </p>
<?php if($_SERVER['PHP_SELF'] === 'about.php'): ?>
<p> Show this in about.php </p>
<?php endif; ?>
</body>
</html>
Now, all you have to do is ... include foo.php in both pages.
Make the page you want and you can go about doing this:
<html>
<head>
<title>title</title>
<style type="text/css">
/* css goes here */
</style>
</head>
<body>
<div id="stay">I wont change</div>
<?php
if(basename($_SERVER['PHP_SELF'] == "other-page.php")){ ?>
<div id="change">I will change</div>
<?php }else{ ?>
<div id="change">Original div</div>
<?php } ?>
</body>
</html>
That takes the file name and based on that you can change content (if is only for one page, otherwise write a function/class based on that).
There are many ways to do this. Here are two, each with their own advantages and disadvantages.
Firstly, if you don't want to modify the page at all, you can add a small PHP code segment which will include a page passed in through the GET variable. For example
<html>
<head>
<title>title</title>
<style type="text/css">
/* css goes here */
</style>
</head>
<body>
<div id="stay">I wont change</div>
<div id="change"><?php require($_GET['page']); ?></div>
</body>
</html>
would mean that using the URL mypage.php?page=home.php would automatically include the contents of a file called home.php into that div.
Another way to do it is to divide up that page into 2 sections, and including both of them in any other page you use. For example, splitting the code into 2 seperate files, such as
top.php:
<html>
<head>
<title>title</title>
<style type="text/css">
/* css goes here */
</style>
</head>
<body>
<div id="stay">I wont change</div>
<div id="change">
bottom.php:
</div>
</body>
</html>
then in your PHP file you can use the following
require("top.php);
MY CONTENT HERE
require("bottom.php);
remember that you will need to use echo to output html code on this method if it is within <?php and ?> tags
hope this helps.
You can't do this will plain HTML.
To do it in php, first create template file like so: (template.php)
<html>
<head>
<title>title</title>
<style type="text/css">
* css goes here */
</style>
</head>
<body>
<div id="stay">I wont change</div>
<div id="change"><?=$main_content?></div>
</body>
</html>
Now, let's say you want to make a "contact me" page.
<?php
// in contact.php
$main_content = "Contact me at my#email.com
include "template.php";
?>
This will write the contents of template.php to the page and echo out the value of $main_content inside div#change
Now, this is generally frowned upon because managing your variables becomes difficult as the size of the template increases. To keep things sane, use a templating engine as all of the other answers are suggesting.

PHP headers and footers

I want to use php to create a consistent header and footer across my site using the php incluse tags. When creating the header file, do I need the html and body tags or can I just start with the div id="header"....?
What you should worry about is the final outcome of the markup of the site, after you've included everything.
Example:
header.php
<div id="header"></div>
footer.php
<div id="footer"></div>
index.php
<html>
<head></head>
<body>
<?php include('header.php'); ?>
<div id="content"></div>
<?php include('footer.php'); ?>
</body>
</html>
For correct semantics, include the <html> and <body> tags, making sure to close them in the footer.php file
Yes you should. It's a good idea, though, to use variables within the include to set such things as <title>...
<?php
$pagetitle="My page";
include('header.php');
?>
Content here
<?php include('footer.php'); ?>
where header.php is
<html>
<head>
<title><?php echo $pagetitle; ?></title>
<!-- your meta tags etc -->
</head>
<body>
and footer is
<script>/* your javascript includes */</script>
</body>
</html>
You can have a section of HTML in a file like this.
<footer> This is my global footer! </footer>
Then in PHP you can use include() to include that html file. It will render the contents of the file to the output where you include it.
include 'globalFooter.html';
Do I need the html and body tags or can I just start with the div?
No you do not.
Your question is not completely clear, but you seem to be asking whether you need any special tags in the included file. The short answer is no—the included file is inserted into the including file verbatim, so it would contain whatever tags are required to render the header (or footer) you had in mind.
Whatever you do, the result should be valid HTML.
So if your index.php starts with <?php include "header.php" ?> then your header.php file should start with <!DOCTYPE html><html>... Same goes for the end.

Using better includes for pages?

As of right now, the way I use includes is to bring the header, footer, and some content for other pages.
This leads to more includes then I really want, because I need to add more content for the includes.
For example:
<!DOCTYPE html>
<?php include('header.php'); ?>
<body>
<?php include('body-top.php');
custom html
</?php include('footer.php');
</body>
It would be nice if I could add variables to the includes and on the pages I want the includes to show.
I am not good at PHP at all, so is there a better way to use Includes?
This can be easily done:
index.php
$title = 'Hello World!';
include 'content.php';
content.php
<!DOCTYPE html>
<html>
<head>
<title><?php echo $title; ?></title>
</head>
<body></body>
</html>
The problem with this approach is, you'll soon run into problems keeping track what went where, so using functions as suggested in other answers might be a good idea. However, for small projects it's IMHO good enough.
sounds like a job for Smarty
It looks like this
<?php
require 'Smarty/libs/Smarty.class.php';
$smarty = new Smarty;
$smarty->assign('title','Hello World');
$smarty->assign('hello','Hello World, this is my first Smarty!');
$smarty->display('test.tpl');
?>
test.tpl
<html>
<head>
<title>{$title}</title>
</head>
<body>
{$hello}
</body>
</html>
Or even better way, use some of the PHP MVC frameworks, which will give you even more stuff (not just template system)
Your includes are already very few, no need to optimize them.
Also don't pay attention to people suggesting Smarty or MVC's because that will increase dramatically the number of includes (in exchange for other benefits, of course)-
You can turn your included files into functions. PHP has a neat trick where anything between curly-brackets (i.e. { and }) is only executed when that part of the code is reached. This includes the HTML code outside of your PHP tags.
This could be our 'header.php' file, where we wrap our current code in a function.
<?php function doHeader($title) { ?>
<html>
<head>
<title><?php echo $title; ?></title>
</head>
<?php } ?>
Then we make a tester for it. Whatever our tester/caller chooses to pass as $title shows up in our output.
<?php
// All included here
include_once('header.php');
?><!DOCTYPE html>
<?php doHeader('My page title'); ?>
<body></body>
</html>
This produces the output,
<!DOCTYPE html>
<html>
<head>
<title>My page title</title>
</head>
<body></body>
</html>

How to change HTML title in PHP without breaking the XHTML markup validation?

Here is the structure of the web site:
PHP index file
//my class for analyzing the PHP query
$parameter = new LoadParameters();
//what this does is it accesses the database
//and according to the query, figures out what should be
//loaded on the page
//some of the things it sets are:
// $parameter->design - PHP file which contains the design
// HTML code of the page
// $parameter->content - Different PHP file which should be loaded
// inside the design file
$parameter->mysqlGetInfo($_SERVER['QUERY_STRING']);
//load the design file
include($parameter->design);
PHP design file
Just the generic structure. Obviously it has a lot more design elements.
<html>
<head>
...
</head>
<body>
<?php
//this loads the content into the design page
include($parameter->content);
?>
</body>
</html>
Question
So here is the problem I experience. The $parameter->content file is a dynamic PHP file, meaning the content also changes according to the query.
For instance if I have a image pages with queries like ?img=1 and ?img=2, my LoadParameter class will only look at the img part of the query and will know that the content of the page should be image.php. image.php however will look at the query again and figure out exactly what image to load.
This causes issues for me because I want to have a different <title></title> for different images. So my solution was just to set the <title></title> element in the content page. This works but it breaks the XHTML markup validation at W3C because it makes the structure of the site to be the following:
<html>
<head>
...
</head>
<body>
...
<title>sometitle</title>
...
</body>
</html>
And having <title></title> within <body></body> is not allowed.
So how can I change the title without breaking the XHTML markup validation?
Note: I can't use javascript because then Search engines would not be able to see the title of the page. I need to do it directly in PHP.
Thanx in advance.
why not do a second include to perform the title in the proper place?
<html>
<head>
<?php
inlcude($parameter->title);
?>
...
</head>
<body>
<?php
//this loads the content into the design page
include($parameter->content);
?>
</body>
</html>
Can't you just change the PHP code so that you can do something like:
<html>
<head>
<title><? print($parameter->title); ?></title>
</head>
<body>
<?php
//this loads the content into the design page
include($parameter->content);
?>
</body>
</html>
I'd move all of the <head> code into a 'common function' called something like html_head($title) and then have it put the title where it belongs.
Then simply call that function from within the pages and it's fixed.
Don't forget to include the <body> tag in that function, otherwise it won't work!
Elaborating ;)
function html_head($title) {?>
<html>
<head>
<title><?=$title?></title>
<!-- Put whatever you want... here! -->
</head>
<body>
<?}
Then in $parameter->content, call html_head("Title")
It would be easier if $parameter->content could be included without displaying its HTML code, but instead have a $parameter->display (or similar) function that displays the HTML code. That way, you can include the PHP code at the beginning of the file and not worry about being unable to access the title.
<?php
require_once($parameter->content);
?>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title><?php echo $parameter->title; ?></title>
</head>
<body>
<?php
echo $parameter->display;
?>
</body>
</html>
This is how I solved the issue.
I changed the PHP design to something like:
//get the content PHP file
//inside the file I set the following variables
//which are used below:
//$parameter->title - the string which contains the title
//$parameter->html - the string which contains the HTML content
include($parameter->content);
//string which will contain the html code of the whole page
$html = <<<EndHere
<html>
<head>
<title>
EndHere;
//add title
$html .= $parameter->title;
$html .= <<<EndHere
</title>
</head>
<body>
EndHere;
//add the content of the page
$html .= $parameter->html;
$html .= <<<EndHere
</body>
</html>
EndHere;
//output the html
echo $html;
And here is the basic structure of the Content PHP file. Since the only page which can possibly include the file is the my design page, I can reference $parameter in it.
//set the title
$parameter->title = "sometitle";
//set the content HTML
$parameter->html = "some HTML here";
It's not a very clean solution but it works fine.

Categories