I am building a website using php. I would want to separate the php from the html. Smarty engine, I guess does that, but right now its too complicated for me. Looking for a quick fix and easy to learn solution, one which is an accepted standard as well. Anyone helping please.
Consider frameworks or choose a template engine
Use a framework. Depending on your project, either a micro framework like Slim or something more complete like Laravel.
What I sometimes do when writing complex systems with quite much php code is separating it the following way (don't know your exact project, but it might work for you):
You create a php file with all the functions and variables you need. Then, you load every wepgage through the index.php file using .htaccess (so that a user actually always loads the index.php with a query string). Now, you can load the html page using file_get_contents (or similar) into a variable (I call this $body now); this variable can be modified using preg_replace.
An example: In the html file, you write {title} instead of <title>Sometext</title>
The replacement replaces {title} with the code you actually need:
$body = str_replace('{title}', $title, $body);
When all replacements are done, simply echo $body...
Just declare a lot of variables and use them in the template:
In your application:
function renderUserInformation($user)
{
$userName = $user->userName;
$userFullName = $user->fullName;
$userAge = $user->age;
include 'user.tpl.php';
}
In user.tpl.php:
User name: <?=$username?><br>
Full name: <?=userFullName?><br>
Age: <?=$userAge?>
By putting it in a function, you can limit the scope of the variables, so you won't pollute your global scope and/or accidentally overwrite existing variables.
This way, you can just 'prepare' the information needed to display and in a separate php file, all you need to do is output those variables.
Of course, if you must, you can still add more complex PHP code to the template, but try to do it as little as possible.
In the future, you might move this 'render' function to a separate class. In a way, this class is a view (a User View, in this case), and it is one step in creating a MVC structure. (But don't worry about that for now.)
Looking for a quick fix and easy to learn solution
METHOD 1 (the laziest; yet you preserve highlighting on editors like notepad++)
<?php
// my php
echo "foo";
$a = 4;
// now close the php tag -temporary-
// to render some html in the laziest of ways
?>
<!-- my html -->
<div></div>
<?php
// continue my php code
METHOD 2 (more organized; use template files, after you passed some values on it)
<?php
// my php
$var1 = "foo";
$title = "bar";
$v = array("var1"=>"foo","title"=>"bar"); // preferrable
include("template.php");
?>
template.php
<?php
// $var1, $var2 are known, also the array.
?>
<div>
<span> <?php echo $v["title"]; ?> </span>
</div>
Personally, i prefer method 2 and im using it in my own CMS which uses lots and lots of templates and arrays of data.
Another solution is of course advanced template engines like Smarty, PHPTemplate and the likes. You need a lot of time to learn them though and personally i dont like their approach (new language style)
function renderUserInformation($user)
{
$userName = $user->userName;
$userFullName = $user->fullName;
$userAge = $user->age;
include 'user.tpl.php';
}
Related
What's the best way to create a temporary variable inside a .phtml template while abiding by Magento's architecture?
Example
File: /template/catalog/product/view.phtml
<?php
$myVar = $_product->getAttributeText('color');
if ( empty($myVar) ) {
// does not exist
} else {
// show the attribute
}
?>
Beyond this expression $myVar isn't needed anywhere else.
Note: I'm not looking for alternative ways to write this code that avoid creating vars. For the sake of argument, assume a scenario where creating a temporary var is necessary.
What should $myVar be?
$myVar
$namespaced_myVar
$_myVar
Magento's registry pattern http://alanstorm.com/magento_registry_singleton_tutorial
Something else...
Looking for a "real world" solution more than a purist answer. How would you write this?
Answer
Combined between Ben's answer and this bit from Alan/Vinai's conversation https://twitter.com/VinaiKopp/status/225318270591442945 — this is how I'm going to write it:
If the anything more than basic logic is needed, I'll extend the class with new methods.
Otherwise, I'll create new vars in the local scope like so:
$mynamespace_myVar = 'xyz';
This is what I like about it:
The $mynamespace_ reminds me I created this and not Magento
It also makes it highly unlikely another developer overwrites my vars
This is what I don't like:
It's un-pure and potentially corruptible, but I probably only need this <5 times for an entire site so it's reasonably shielded.
Not using $_ to show the var is local to this template is not "the Magento way" but it makes the code more readable.
So my templates will mostly have code like this:
$gravdept_someNiceData = true;
Some history: https://stackoverflow.com/a/3955757/833795
Re 1, 2, & 3: Differentiating between these choices involves getting into "purist answer" territory, as they are all local variables.
Using the registry pattern is uncalled for, as the desired scope is stated to be local to the rendering of the template.
Based on your example, an appropriate construction in Magento might be:
<?php if ($_product->getColor()): ?>
<h2> I HAZ COLOR </h2>
<?php else: ?>
<h2> I NO HAZ COLOR </h2>
<?php endif ?>
If there is anything but the simplest test of return values it's appropriate to add this logic as a method of the block class (using a rewrite), as it is in fact view logic which you've mentioned should be local to this context only.
I am a PHP dev trying to start using HAML, using this implementation:
http://phphaml.sourceforge.net/
HAML looks awesome, but I don't understand if/how it supports partials (or includes, as they are called in the PHP world).
I would like to have a master template HAML file that then goes and loads up a bunch of partials for all the little pieces. (Then I can reuse those pieces in other templates too.)
In PHP or Ruby this would be really easy, is there any way to do this with HAML? thanks!
dylan
You could create a global render_haml_partial method by analogy with phpHaml's existing display_haml method that might look something like:
function render_haml_partial($sFilename, $aVariables = array(), $sTmp = true, $bGPSSC = false)
{
$sPath = realpath($sFilename);
$haml = new HamlParser(dirname($sPath), $sTmp);
$haml->append($GLOBALS);
if ($bGPSSC)
{
$haml->append($_GET);
$haml->append($_POST);
$haml->append($_SESSION);
$haml->append($_SERVER);
$haml->append($_COOKIE);
}
$haml->append($aVariables);
return $haml->fetch($sFilename);
}
This method could be placed in phpHaml's HamlParser.class.php file so it is available to all your templates.
The only difference between this and display_haml is that it invokes fetch instead of display at the end and returns the result so you can then insert it in-place into the invoking template.
You would then use it in your PHP/HAML templates as follows:
= render_haml_template("path to partial")
This would then be very similar to the Rails/HAML syntax:
= render :partial => 'path to partial'
Note that using display_haml directly does not have quite the same effect since it renders the template directly to the output instead of returning the result to the caller. Thus you could do the following:
- display_haml("path to partial")
But this doesn't capture the result of the render.
I'm guessing that somebody who cares enough about phpHaml might add such a render_haml_partial or something similar eventually - I might suggest it to the author some time.
Quite an old question, but I've updated the source code of phpHaml to reflect this new functionality!
Check out the commit #github
https://github.com/endorama/phphaml/commit/8d95d5ebff06275db8b14438e566c6e41ec91b7f
Update- Thanks for all the responses. This Q is getting kind of messy, so I started a sequel if anyone's interested.
I was throwing together a quick script for a friend and stumbled across a really simple way of doing templating in PHP.
Basically, the idea is to parse the html document as a heredoc string, so variables inside of it will be expanded by PHP.
A passthrough function allows for expression evaluation and function and static method calls within the string:
function passthrough($s){return $s;}
$_="passthrough";
The code to parse the document inside a heredoc string is ridiculously simple:
$t=file_get_contents('my_template.html');
eval("\$r=<<<_END_OF_FILE_\n$t\_END_OF_FILE_;\n");
echo $r;
The only problem is, it uses eval.
Questions
Can anyone think of a way to do this sort of templating without using eval, but without adding a parser or a ton of regex madness?
Any suggestions for escaping stray dollar signs that don't belong to PHP variables without writing a full-on parser? Does the stray dollar sign problem render this approach not viable for 'serious' use?
Here's some sample templated HTML code.
<script>var _lang = {$_(json_encode($lang))};</script>
<script src='/blah.js'></script>
<link href='/blah.css' type='text/css' rel='stylesheet'>
<form class="inquiry" method="post" action="process.php" onsubmit="return validate(this)">
<div class="filter">
<h2>
{$lang['T_FILTER_TITLE']}
</h2>
<a href='#{$lang['T_FILTER_ALL']}' onclick='applyFilter();'>
{$lang['T_FILTER_ALL']}
</a>
{$filter_html}
</div>
<table class="inventory" id="inventory_table">
{$table_rows}
<tr class="static"><th colspan="{$_($cols+1)}">
{$lang['T_FORM_HELP']}
</th></tr>
{$form_fields}
<tr class="static">
<td id="validation" class="send" colspan="{$cols}"> </td>
<td colspan="1" class="send"><input type="submit" value="{$lang['T_SEND']}" /></td>
</tr>
</table>
</form>
Why use templating?
There's been some discussion of whether creating a templating layer is necessary in PHP, which, admittedly, is already pretty good at templating.
Some quick reasons templating is useful:
You can control it
If you preprocess the file before it goes to the interpreter, you have more control over it. You can inject stuff, lock down permissions, scrape for malicious php / javascript, cache it, run it through an xsl template, whatever.
Good MVC design
Templating promotes separation of view from model and controller.
When jumping in and out of <?php ?> tags in your view, it's easy to get lazy and do some database queries or perform some other server action. Using a method like the above, only one statement may be used per 'block' (no semicolons), so it's much more difficult to get caught in that trap. <?= ... ?> have pretty much the same benefit, but...
Short tags aren't always enabled
...and we want our app to run on various configurations.
When I initially hack a concept together it starts out as one php file. But before it grows I'm not happy unless all php files have only one <?php at the beginning, and one ?> at the end, and preferably all are classes except stuff like the controller, settings, image server, etc.
I don't want much PHP in my views at all, because designers become confused when dreamweaver or whatever poops the bed when it sees something like this:
<a href="<?php $img="$img_server/$row['pic'].png"; echo $img; ?>">
<img src="<?php echo $img; ?>" /></a>
This is hard enough for a programmer to look at. The average graphic designer won't go anywhere near it. Something like this is a much easier to cope with:
<img src="{$img}" />
The programmer kept his nasty code out of the html, and now the designer can work his design magic. Yay!
Quick update
Taking everyone's advice into consideration, I think preprocessing the files is the way to go, and the intermediate files should be as close as normal "php templating" as possible, with the templates being syntactic sugar. Eval still in place for now while I play with it. The heredoc thing has sort of changed its role. I'll write more later and try to respond to some of the answers, but for now...
<?php
class HereTemplate {
static $loops;
public function __construct () {
$loops=array();
}
public function passthrough ($v) { return $v; }
public function parse_markup ($markup, $no_escape=null, $vars=array()) {
extract($vars);
$eot='_EOT_'.rand(1,999999).'_EOT_';
$do='passthrough';
if (!$no_escape) $markup=preg_replace(
array(
'#{?{each.*(\$\w*).*(\$\w*).*(\$\w*).*}}?#',
'#{?{each.*(\$\w*).*(\$\w*).*}}?#',
'#{?{each}}?#',
'#{{#', '#}}#',
'#{_#', '#_}#',
),
array(
"<?php foreach (\\1 as \\2=>\\3) { ?>",
"<?php foreach (\\1 as \\2) { ?>",
"<?php } ?>",
"<?php echo <<<$eot\n{\$this->passthrough(", ")}\n$eot\n ?>",
"<?php ", " ?>",
),
$markup);
ob_start();
eval(" ?>$markup<?php ");
echo $markup;
return ob_get_clean();
}
public function parse_file ($file) {
// include $file;
return $this->parse_markup(file_get_contents($file));
}
}
// test stuff
$ht = new HereTemplate();
echo $ht->parse_file($argv[1]);
?>
...
<html>
{{each $_SERVER $key $value}
<div id="{{$key}}">
{{!print_r($value)}}
</div>
{each}}
</html>
PHP was itself originally intended as a templating language (ie a simple method of allowing you to embed code inside HTML).
As you see from your own examples, it got too complicated to justify being used in this way most of the time, so good practice moved away from that to using it more as a traditional language, and only breaking out of the <?php ?> tags as little as possible.
The trouble was that people still wanted a templating language, so platforms like Smarty were invented. But if you look at them now, Smarty supports stuff like its own variables and foreach loops... and before long, Smarty templates start to have the same issues as PHP templates used to have; you may as well just have used native PHP in the first place.
What I'm trying to say here is that the ideals of a simple templating language aren't actually that easy to get right. It's virtually impossible to make it both simple enough not to scare off the designers and at the same time give it enough flexibility to actually do what you need it to do.
If you don't wont to use a big template engines like Twig (which I sincerely recommend) you can still get good results with little code.
The basic idea that all the template engines share is to compile a template with friendly, easy-to-understand syntax to fast and cacheable PHP code. Normally they would accomplish this by parsing your source code and then compiling it. But even if you don't want to use something that complicated you can achieve good results using regular expressions.
So, basic idea:
function renderTemplate($templateName, $templateVars) {
$templateLocation = 'tpl/' . $templateName . '.php';
$cacheLocation = 'tplCache/' . $templateName . '.php';
if (!file_exists($cacheLocation) || filemtime($cacheLocation) < filemtime($templateLocation)) {
// compile template and save to cache location
}
// extract template variables ($templateVars['a'] => $a)
extract($templateVars);
// run template
include 'tplCache/' . $templateName . '.php';
}
So basically we first compile the template and then execute it. Compilation is only done if either the cached template doesn't yet exist or there is a newer version of the template than the one in the cache.
So, let's talk about compiling. We will define two syntaxes: For output and for control structures. Output is always escaped by default. If you don't want to escape it you must mark it as "safe". This gives additional security. So, here an example of our syntax:
{% foreach ($posts as $post): }
<h1>{ $post->name }</h1>
<p>{ $post->body }</p>
{!! $post->link }
{% endforeach; }
So, you use { something } to escape and echo something. You use {!! something} to directly echo something, without escaping it. And you use {% command } to execute some bit of PHP code without echoing it (for example for control structures).
So, here's the compilation code for that:
$code = file_get_contents($templateLocation);
$code = preg_replace('~\{\s*(.+?)\s*\}~', '<?php echo htmlspecialchars($1, ENT_QUOTES) ?>', $code);
$code = preg_replace('~\{!!\s*(.+?)\s*\}~', '<?php echo $1 ?>', $code);
$code = preg_replace('~\{%\s*(.+?)\s*\}~', '<?php $1 ?>', $code);
file_put_contents($cacheLocation, $code);
And that's it. You though have to note, that this is more error prone than a real template engine. But it will work for most cases. Furthermore note that this allows the writer of the template to execute arbitrary code. That's both a pro and a con.
So, here's the whole code:
function renderTemplate($templateName, $templateVars) {
$templateLocation = 'tpl/' . $templateName . '.php';
$cacheLocation = 'tplCache/' . $templateName . '.php';
if (!file_exists($cacheLocation) || filemtime($cacheLocation) < filemtime($templateLocation)) {
$code = file_get_contents($templateLocation);
$code = preg_replace('~\{\s*(.+?)\s*\}~', '<?php echo htmlspecialchars($1, ENT_QUOTES) ?>', $code);
$code = preg_replace('~\{!!\s*(.+?)\s*\}~', '<?php echo $1 ?>', $code);
$code = preg_replace('~\{%\s*(.+?)\s*\}~', '<?php $1 ?>', $code);
file_put_contents($cacheLocation, $code);
}
// extract template variables ($templateVars['a'] => $a)
extract($templateVars, EXTR_SKIP);
// run template
include 'tplCache/' . $templateName . '.php';
}
I haven't tested the above code ;) It's only the basic idea.
I'm gonna do something silly and suggest something that requires no templating engine at all and requires only at most 5 characters more per variable/call than what you have there - replace {$foo} with <?=$foo?> and then you can use include for all your templating needs
If all you need is variable replacement though this is a templating function i actually use:
function fillTemplate($tplName,$tplVars){
$tpl=file_get_contents("tplDir/".$tplName);
foreach($tplVars as $k=>$v){
$tpl = preg_replace('/{'.preg_quote($k).'}/',$v,$tpl);
}
return $tpl;
}
if you want to be able to call functions or have loops, there is basicly no way around calling eval short of pre-processing.
There is no ultimate solution. Each has pros and cons. But you already concluded what you want. And it seems a very sensible direction. So I suggest you just find the most efficient way to achieve it.
You basically only need to enclose your documents in some heredoc syntactic sugar. At the start of each file:
<?=<<<EOF
And at the end of each template file:
EOF;
?>
Achievement award. But obviously this confuses most syntax highlighting engines. I could fix my text editor, it's open source. But Dreamweaver is a different thing. So the only useful option is to use a small pre-compiler script that can convert between templates with raw $varnames-HTML and Heredoc-enclosed Templates. It's a very basic regex and file rewriting approach:
#!/usr/bin/php -Cq
<?php
foreach (glob("*.tpl") as $fn) {
$file = file_get_contents($fn);
if (preg_match("/<\?.+<<</m")) { // remove
$file = preg_replace("/<\?(=|php\s+print)\s*<<<\s*EOF\s*|\s+EOF;\s*\?>\s*/m", "", $file);
}
else { // add heredoc wrapper
$file = "<?php print <<<EOF\n" . trim($file) . "\nEOF;\n?>";
}
file_put_contents($fn, $file);
}
?>
This is a given - somewhere you will need templates with a slight amount of if-else logic. For coherent handling you should therefore have all templates behave as proper PHP without special eval/regex handling wrapper. This allows you to easily switch between heredoc templates, but also have a few with normal <?php print output. Mix and match as appropriate, and the designers can work on the majority of files but avoid the few complex cases. For exampe for my templates I'm often using just:
include(template("index")); // works for heredoc & normal php templ
No extra handler, and works for both common template types (raw php and smartyish html files). The only downside is the occasional use of said converter script.
I'd also add a extract(array_map("htmlspecialchars",get_defined_vars())); on top of each template for security.
Anyway, your passthrough method is exceptionally clever I have to say. I'd call the heredoc alias $php however, so $_ is still available for gettext.
{$php(1+5+7*3)} is more readable than Smarty
I think I'm going to adopt this trick myself.
<div>{$php(include(template($ifelse ? "if.tpl" : "else.tpl")))}</div>
Is stretching it a bit, but it seems after all possible to have simple logic in heredoc templates. Might lead to template-fileritis, yet helps enforcing a most simple template logic.
Offtopic: If the three <<<heredoc&EOF; syntax lines still appear too dirty, then the best no-eval option is using a regular expression based parser. I do not agree with the common myth that that's slower than native PHP. In fact I believe the PHP tokenizer and parser lag behind PCRE. Especially if it's solely about interpolating variables. It's just that the latter isn't APC/Zend-cached, you'd be on your own there.
Personally, I wouldn't touch with a stick any templating system where forgetting to escape a variable creates a remote code execution vulnerability.
Personally i'm using this template engine: http://articles.sitepoint.com/article/beyond-template-engine/5
I really like it a lot, especially because of it's simplicity. It's kinda similar to your latest incarnation, but IMHO a better approach than using heredoc and putting yet another layer of parsing above the PHP one. No eval() either, but output buffering, and scoped template variables, too. Use like this:
<?php
require_once('template.php');
// Create a template object for the outer template and set its variables.
$tpl = new Template('./templates/');
$tpl->set('title', 'User List');
// Create a template object for the inner template and set its variables.
// The fetch_user_list() function simply returns an array of users.
$body = new Template('./templates/');
$body->set('user_list', fetch_user_list());
// Set the fetched template of the inner template to the 'body' variable
// in the outer template.
$tpl->set('body', $body->fetch('user_list.tpl.php'));
// Echo the results.
echo $tpl->fetch('index.tpl.php');
?>
The outter template would look like this:
<html>
<head>
<title><?=$title;?></title>
</head>
<body>
<h2><?=$title;?></h2>
<?=$body;?>
</body>
</html>
and the inner one (goes inside the outter template's $body variable) like this:
<table>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Banned</th>
</tr>
<? foreach($user_list as $user): ?>
<tr>
<td align="center"><?=$user['id'];?></td>
<td><?=$user['name'];?></td>
<td><?=$user['email'];?></td>
<td align="center"><?=($user['banned'] ? 'X' : ' ');?></td>
</tr>
<? endforeach; ?>
</table>
If you don't like / can't use short-tags then replace them with echos. That's as close to dirt-simple as you can get, while still having all the features you'll need IMHO.
Dead-simple templating using a function:
<?php
function template($color) {
$template = <<< ENDTEMPLATE
The colors I like are {$color} and purple.
ENDTEMPLATE;
return $template . "\n";
}
$color = 'blue';
echo template($color);
$color = 'turquoise';
echo template($color);
This outputs:
The colors I like are blue and purple.
The colors I like are turquoise and purple.
Nothing fancy, but it does work using standard PHP without extensions. Additionally, the use of functions to encapsulate the templates should help with proper MVC separation. Also (and this is what I needed for my coding today) I can save the filled-out template away for output to a file (later on in my program).
This is a minimal implementation of mustache to just substitute variables.
// Example:
// miniMustache(
// "{{documentName }} - pag {{ page.current }} / {{ page.total }}",
// array(
// 'documentName' => 'YourCompany Homepage',
// 'page' => array('current' => 1, 'total' => 10)
// )
// )
//
// Render: "YourCompany Homepage - pag 1 / 10"
function miniMustache($tmpl, $vars){
return preg_replace_callback( '/\{\{([A-z0-9_\.\s]+)\}\}/',
function ($matches) use ($vars) {
//Remove white spaces and split by "."
$var = explode('.',preg_replace('/[\s]/', '', $matches[1]));
$value = $vars;
foreach($var as $el){
$value = $value[$el];
}
return $value;
},
$tmpl);
}
In some cases, it is more than enough. In case you need full power: https://github.com/bobthecow/mustache.php
I've experienced first hand the extent of the horror and foot-shooting that the ugliness of PHP can cause. I'm onto my next project (you may be wondering why I'm not just switching languages but that's not why I'm here) and I've decided to try doing it right, or at least better, this time.
I've got some models defined, and I've started on a main controller. I'm at a fork in my decisions about how to implement the view. So far, the main controller can be given lists of display functions to call, and then it can spew out the whole page with one call. It looks like:
function Parse_Body()
{
foreach ($this->body_calls as $command)
{
$call = $command['call'];
if (isset($command['args'])) $call($command['args']);
else $call();
}
}
My dilemma is this:
Would it be better to have all of my display functions return the HTML they generate, so that the main controller can just echo $page; or should the display files use raw HTML outside of PHP, which gets output as soon as it's read?
With the former, the main app controller can precisely control when things get output, without just relinquishing complete control to the whim of the displays. Not to mention, all those lists of display functions to call (above) can't really be executed from a display file unless they got passed along. With the latter method, I get the benefit of doing HTML in actual HTML, instead of doing huge PHP string blocks. Plus I can just include the file to run it, instead of calling a function. So I guess with that method, a file is like a function.
Any input or advice please?
Would it be better to have all of my
display functions return the HTML they
generate, so that the main controller
can just echo $page; or should the
display files use raw HTML outside of
PHP, which gets output as soon as it's
read?
One of the advantages of php is that the processing is similar to the output:
So:
<h1> <?= $myHeading; ?> </h1>
Is more clear than:
echo "<h1>$myHeading</h1>";
An even more than:
echo heading1($myHeading); //heading1() being an hypothethical user defined function.
Based on that I consider that it is better to in the view to have HTML and and just print the appropriate dynamic fields using php.
In order to get finner control over the output you can use: ob_start as gurunu recommended.
You could of course use any of the several php MVC frameworks out there.
My prefered one, now is: Solarphp
but Zend Framework and Cakephp could help you too.
And finally if you don't want to use any framework
You could still use a pretty slim templating engine: phpSavant.
That will save you a few headaches in the development of your view.
th
You can get the benefit of both, obtaining a string of HTML while also embedding HTML within PHP code, by using the output control functions:
From the PHP manual # http://www.php.net/manual/en/ref.outcontrol.php:
<?php
function callback($buffer)
{
// replace all the apples with oranges
return (str_replace("apples", "oranges", $buffer));
}
ob_start("callback");
?>
<html>
<body>
<p>It's like comparing apples to oranges.</p>
</body>
</html>
<?php
ob_end_flush();
?>
First buffer everything. then replace tags using a parser at end of script.
<?php
$page_buffer = '';
function p($s){
global $page_buffer;
$page_buffer .= $s;
}
$page_buffer = str_replace(
array('<$content$>','<$title$>'),
array($pagecontent,$pagetitle),
$page_buffer);
echo $page_buffer;
?>
Samstyle PHP Framework implements output buffering and View model this way
And did I mention about benefits of buffering your output in a variable before "echo-ing"? http://thephpcode.blogspot.com/2009/02/php-output-buffering.html
I want to define something like this in php:
$EL = "\n<br />\n";
and then use that variable as an "endline" marker all over my site, like this:
echo "Blah blah blah{$EL}";
How do I define $EL once (in only 1 file), include it on every page on my site, and not have to reference it using the (strangely backwards) global $EL; statement in every page function?
Most PHP sites should have a file (I call it a header) that you include on every single page of the site. If you put that first line of code in the header file, then include it like this on every page:
include 'header.php';
you won't have to use the global keyword or anything, the second line of code you wrote should work.
Edit: Oh sorry, that won't work inside functions... now I see your problem.
Edit #2: Ok, take my original advice with the header, but use a define() rather than a variable. Those work inside functions after being included.
Sounds like the job of a constant. See the function define().
Do this
define ('el','\n\<\br/>\n');
save it as el.php
then you can include any files you want to use, i.e
echo 'something'.el; // note I just add el at end of line or in front
Hope this help
NOTE please remove the '\' after < br since I had to put it in or it wont show br tag on the answer...
Are you using PHP5? If you define the __autoload() function and use a class with some constants, you can call them where you need them. The only aggravating thing about this is that you have to type something a little longer, like
MyClass::MY_CONST
The benefit is that if you ever decide to change the way that you handle new lines, you only have to change it in one place.
Of course, a possible negative is that you're calling including an extra function (__autoload()), running that function (when you reference the class), which then loads another file (your class file). That might be more overhead than it's worth.
If I may offer a suggestion, it would be avoiding this sort of echoing that requires echoing tags (like <br />). If you could set up something a little more template-esque, you could handle the nl's without having to explicitly type them. So instead of
echo "Blah Blah Blah\n<br />\n";
try:
<?php
if($condition) {
?>
<p>Blah blah blah
<br />
</p>
<?php
}
?>
It just seems to me like calling up classes or including variables within functions as well as out is a lot of work that doesn't need to be done, and, if at all possible, those sorts of situations are best avoided.
#svec yes this will, you just have to include the file inside the function also. This is how most of my software works.
function myFunc()
{
require 'config.php';
//Variables from config are available now.
}
Another option is to use an object with public static properties. I used to use $GLOBALS but most editors don't auto complete $GLOBALS. Also, un-instantiated classes are available everywhere (because you can instatiate everywhere without telling PHP you are going to use the class). Example:
<?php
class SITE {
public static $el;
}
SITE::$el = "\n<br />\n";
function Test() {
echo SITE::$el;
}
Test();
?>
This will output <br />
This is also easier to deal with than costants as you can put any type of value within the property (array, string, int, etc) whereas constants cannot contain arrays.
This was suggested to my by a user on the PhpEd forums.
svec, use a PHP framework. Just any - there's plenty of them out there.
This is the right way to do it. With framework you have single entry
point for your application, so defining site-wide variables is easy and
natural. Also you don't need to care about including header files nor
checking if user is logged in on every page - decent framework will do
it for you.
See:
Zend framework
CakePHP
Symfony
Kohana
Invest some time in learning one of them and it will pay back very soon.
You can use the auto_prepend_file directive to pre parse a file. Add the directive to your configuration, and point it to a file in your include path. In that file add your constants, global variables, functions or whatever you like.
So if your prepend file contains:
<?php
define('FOO', 'badger');
In another Php file you could access the constant:
echo 'this is my '. FOO;
You might consider using a framework to achieve this. Better still you can use
Include 'functions.php';
require('functions');
Doing OOP is another alternative
IIRC a common solution is a plain file that contains your declarations, that you include in every source file, something like 'constants.inc.php'. There you can define a bunch of application-wide variables that are then imported in every file.
Still, you have to provide the include directive in every single source file you use. I even saw some projects using this technique to provide localizations for several languages. I'd prefer the gettext way, but maybe this variant is easier to work with for the average user.
edit For your problem I recomment the use of $GLOBALS[], see Example #2 for details.
If that's still not applicable, I'd try to digg down PHP5 objects and create a static Singleton that provides needed static constants (http://www.developer.com/lang/php/article.php/3345121)
Sessions are going to be your best bet, if the data is user specific, else just use a conifg file.
config.php:
<?php
$EL = "\n<br />\n";
?>
Then on each page add
require 'config.php'
the you will be able to access $EL on that page.