PHP 5.3 Coding Standards: Anonymous functions in templates - php

I can not seem to find any documents stating if anonymous functions in templates are a good idea when templating HTML with PHP. I have the following code for example:
<html><body>
<?
$listMethod = function($items)
{
?>
<ul>
<?foreach ($items as $item):?>
<li><?=$item?></li>
<?endforeach;?>
</ul>
<?
};
?>
<?=$listMethod(array('1','2','3'))?>
<p> AND </p>
<?=$listMethod(array('a','b','c'))?>
</body></html>
Is this a good or bad way to create templates in PHP?

Bad bad way , it will be realy hard to debug them, edit, find, ... . You could include a template_functions.php file at the top of you're template and store all template related functions/helpers there .
Edit
Allso do not use short tags if you're into conding standards , most hosting companyes will allow them ( short tags ) but a few whont so you'll have problems .

Look at views as something that's just for output, nothing else.
Everything except echo, if and loops should concern you if in there. (Especially function definitions)

Is this a good or bad way to create templates in PHP?
That depends on whether or not you're intending to re-use that function in more than just one view. If you do, you might want to give the function a name, and put it somewhere so that multiple views can use it. If you don't want to use that function ever again, an anonymous function would do. Then again, I find anonymous functions to be less expressive than normal functions, so I don't think I'd use them for this precise purpose.
It's personal preference, though, and there's no consensus on this being good or bad.

Why scratch your left year with your right hand, as long as you have a left hand to do it? Best way is to define this as a classic function somewhere (myLeftyHelpers.php or whatever file). Although you made me wonder, I really do belive that the role of anonymus functions(if they work in PHP, never tried) are meant to act as function pointers, meaning that this way you can pass a function as a parameters to another function, that's the way I see them used. If someone thinks I am worng please correct me.

Related

Separating php from html

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';
}

Templating HTML using PHP

I'm trying to figure out what is the best way to clone/template HTML that is frequently repeated in my web app. For example, I have a voting <form> (see below) that needs to be located on several pages.
Two ways I thought of doing this:
a function call, e.g., voteForm($action, $user_id, $formType, $success);
an include statement, e.g., include '/myApp/views/voteForm.php'
I prefer an include statement b/c:
Then I don't have to decide on the function's parameters which may change over time forcing me to rewrite the function calls everywhere they exists in my app. With the include statement, I can just use the variables as they are wherever I put the included php file (avoiding redeclaring them which is a pain b/c there are often lots of variables).
I can write the HTML in HTML and not as a PHP string where I have to deal with escaping characters/json_encode issues.
Should I reconsider using include instead function() for any reasons (e.g., performance)? Are there are other templating solutions I'm not thinking of?
<form action="<?=$action?>" method='post' data-form-data='{'formType': '<?=$formType?>', 'success': '<?=$success?>'} >`
<input type='hidden' value='<?=$user_id?>' name='user_id'>
<input type='radio' value='1' name='vote'>
<input type='radio' value='-1' name='vote'>
</form>
It's really up to you--you could have a hybrid of a function that calls include for you (setting up any necessary variables that the include file may need for display purposes). e.g.
function createForm($action,$foo,$bar){
$form_action = $action;
$form_foo = $foo;
include('templates/form.inc');
}
As far as performance, there's no huge benefit that I'm aware of. Although If you're looking for a better way for templating, you may want to look at smarty or some other system that handles most of the 'tough work' for you.
Just keep in mind that when you have code outputting HTML you no longer have a separation of concerns. That is to say that if you decide to change the look and feel of the site at a later date you're not looking through just .inc (or whatever extension you've used) files, but now both .inc and .php files to apply changes.
I would try to avoid putting HTML into function calls. I think what your trying to achieve here would be best suited to an include statement - based on personal preference.
As for performance - it's hard to tell but you could use a PHP Profiler like XDebug to see whether a function or include is the most efficient.
http://xdebug.org/docs/profiler
For big blocks of generated HTML, I'd recommend using includes. I prefer to use function calls to get specific bits of data back.
The again, this is personal preference and cannot be answered with a truly 'correct' answer.
In terms of performance, I would guess not much difference at all unless you're making thousands of calls on each one in one go.
Hope that helps.

How can I reference variables from another included file in PHP?

So I'm working on a PHP app and trying to make everything moduler. I have an index.php file that includes other php files. The first file included is settings.php which has my postgres credentials defined so they can be accessed elsewhere. The second file is connect.php that has a function you can pass sql to and it will return $result. The third file has functions that call the sql function and receive $result and parse it. In the third file, I can read the results of the $result however if I try if($result) it breaks and isset/empty have no effect.
Anyone have any ideas on a way to make this work, or is my structure just terrible?
Thanks so much!
Mike
let's say you have the following three files:
inc1.php
<?php
$foo = 'hello';
?>
inc2.php
<?php
echo $foo;
?>
main.php
include('inc1.php');
include('inc2.php');
it should echo "hello". however, passing variables around among files is a bad idea, and can lead to a lot of confusing, hard-to-follow code. If you need to pass variables around, use functions and/or objects so that you can at least see where they are coming from.
beyond that though, it's difficult to tell exactly what your problem is without seeing the code in question.
I would really try to switch to OOP. This makes things a lot of easier. If you just have to deal with classes, their methods and attributes you only have to include the classes and not this choas of functions. So I would recommend, give it a go ...

PHP Template Engine

I have been looking online for a tutorial to build a template engine. I know there are many engines that exist, like smarty, twig, and pattemplate, that could do exactly what I want, but I am looking to learn how to build one. I started with a template engine that added strings to an array and then displayed the array. Since then I built one using eval() (see below).
<// Define links & folders
define("ROOT_HTTP", "http://" . $_SERVER['HTTP_HOST'] . "/preprocessor");
define("TEMPLATE", "/template");
// Get the template file
$template = file_get_contents("template/template.php");
// Replace
$template = str_replace("<x Title x>", displayTitle(), $template);
$template = str_replace("<x Menu x>", displayMenu(), $template);
$template = str_replace("<x Content x>", displayContent(), $template);
$result = #eval("?>" . $template . "<?");
function displayMenu(){
return "Link1<br />" .
"Link2<br />" .
"Link3<br />";
}
function displayTitle(){
return "Site Title <?php echo date(\"m-d-y\", time()); ?>";
}
function displayContent(){
return file_get_contents("content.php");
}
It works fairly well but its not what I am looking to achieve. I would like to build something that is like the Joomla template with tags like <jdoc:include type="component" />. I would also like it to be able to handle errors inline meaning that it will display the line number of an error or when I call echo "text" it displays text in the correct position inside the template.
How do I create something along those lines?
http://www.phptal.org/ sounds very similar and has good code organization. if extension of mentioned system does not suit the needs, it would at least work as good tutorial
First of all: Immediately forget the idea about using a TE with XML-like tags. Really, it may look nice on the first glance but only causes too much work in the end and is really limiting.
Secondly I obviously recommend you to use Twig. It is clean, fast, extensible and offers all the features you need.
And lastly: I have written a small tutorial how to write a simple but powerful TE in another Stackoverflow question. It is really simple but for smaller projects it may suffice.
I cannot agree with NikiC's point of view.
XML is, although an old syntax, very powerful and brings a lot of advantages -- one of which is its similitude with properly written HTML.
There is nothing limiting in using an XML-based template syntax.
Besides, although Twig is, indeed, an excellent and famous project, it still lacks from a really good separation paradigm. It is still too dangerous and too easy to make mistakes from within the template and cause damages to the application as a whole.
Finally, the best template engine -- just as the best MVC framework -- is the one you feel really comfortable with.
I recommend having a look at FigDice]1, which was inspired by PHPTal, but takes things a few steps further, with an exclusive approach by giving the Web Designer (integrator, html-ist, etc.) a central position with the project -- much more flexible than the Twig-like approach.
I would be happy to read some feedback.
Thanks

How to setup site-wide variables in php?

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.

Categories