need your help with PHP templating. I'm new to PHP (I'm coming from Perl+Embperl). Anyway, my problem is simple:
I have a small template to render some item, let it be a blog post.
The only way i know to use this template is to use 'include' directive.
I want to call this template inside a loop going thru all the relevant blog posts.
Problem: I need to pass a parameter(s) to this template; in this case reference to array representing a blog post.
Code looks something like this:
$rows = execute("select * from blogs where date='$date' order by date DESC");
foreach ($rows as $row){
print render("/templates/blog_entry.php", $row);
}
function render($template, $param){
ob_start();
include($template);//How to pass $param to it? It needs that $row to render blog entry!
$ret = ob_get_contents();
ob_end_clean();
return $ret;
}
Any ideas how to accomplish this? I'm really stumped :) Is there any other way to render a template?
Consider including a PHP file as if you were copy-pasting the code from the include into the position where the include-statement stands. This means that you inherit the current scope.
So, in your case, $param is already available in the given template.
$param should be already available inside the template. When you include() a file it should have the same scope as where it was included.
from http://php.net/manual/en/function.include.php
When a file is included, the code it
contains inherits the variable scope
of the line on which the include
occurs. Any variables available at
that line in the calling file will be
available within the called file, from
that point forward. However, all
functions and classes defined in the
included file have the global scope.
You could also do something like:
print render("/templates/blog_entry.php", array('row'=>$row));
function render($template, $param){
ob_start();
//extract everything in param into the current scope
extract($param, EXTR_SKIP);
include($template);
//etc.
Then $row would be available, but still called $row.
I use the following helper functions when I work on simple websites:
function function_get_output($fn)
{
$args = func_get_args();unset($args[0]);
ob_start();
call_user_func_array($fn, $args);
$output = ob_get_contents();
ob_end_clean();
return $output;
}
function display($template, $params = array())
{
extract($params);
include $template;
}
function render($template, $params = array())
{
return function_get_output('display', $template, $params);
}
display will output the template to the screen directly. render will return it as a string. It makes use of ob_get_contents to return the printed output of a function.
Related
i'm calling multiple functions from a function...as per my scope i want to call a specific function from parent function as per file that calls that function...
function dispcategories() {
include ('database/connection.php');
$select = mysqli_query($con, "SELECT * FROM categories");
while ($row = mysqli_fetch_assoc($select)) {
echo "<table class='category-table'>";
echo "<tr><td class='main-category' colspan='2'>".$row['category_title']."</td></tr>";
dispsubcategories($row['cat_id']);
dispsubcategoriesstate($row['cat_id']);
echo "</table>";
}
}
From dispcategories i want to call dispsubcategoriesstate() if and only if file updatestate.php calls dispcategories()...if any other file calls dispcategories() than it should not call to dispsubcategoriesstate()...
Hope everyone get the question it is possible to check file name threw if condition or not who calls the function
Including a file is just like typing it into your source code. You can use the magic constant __FILE__ to determine the current file, but this won't tell you what file the calling function was written in.
I'd suggest that you should rather pass a parameter to your function and then call the subroutine based on that.
Declare your function like this and replace the line dispsubcategoriesstate($row['cat_id']); with the block shown below
function dispcategories($fetchSubCategories = false) {
// your code goes here
if ($fetchSubCategories === true) {
dispsubcategoriesstate($row['cat_id']);
}
// the rest of your code goes here
}
When you call it from the file where you do not want sub-categories you will call it like you do now:
dispcategories();
Whenever you want it to fetch the subcategories you can pass the parameter through like this:
dispcategories(true);
I'm using an optional function argument and if this is confusing you should read the manual page.
In an attempt to speed up my workflow and help the back end guys with integration (I'm a front end dev) I'm attempting to extend the file includes function by wrapping comments around each file include to output it's filename:
function include_module($path) {
echo "\n\n<!-- MODULE: ".basename($path, '.php')." -->\n";
include($path);
echo "\n<!-- /MODULE: ".basename($path, '.php')." -->\n\n";
}
include_module('form-controls.php');
However this results in the loss of access to any variables set outside the function. I know I can do:
global $var
But that will only give me access to $var (I'm aware I could do $var['var1'], etc), is there any way to do 'global all' or can anyone think of a different approach to wrap the comments?
Cheers :)
Try this:
function include_module($path) {
foreach($GLOBALS as $name => $value) global $$name;
echo "\n\n<!-- MODULE: ".basename($path, '.php')." -->\n";
include($path);
echo "\n<!-- /MODULE: ".basename($path, '.php')." -->\n\n";
}
include_module('form-controls.php');
You can use the following to access the globals.
extract($GLOBALS, EXTR_REFS);
im working with a large team, and im making functions that return html code, and im echoing the result of those functions to get the final page. The thing is, i need some scrap of code developed by other member of the team, and i need it to be a string, but the code is available as a php file which im supposed to include or require inside my page.
Since im not writing an ht;ml page, but a function that generate that code, i need to turn the resulting html of the require statement into a string to concatenate it to the code generated by my function.
Is there any way to evaluate the require and concatenate its result to my strings?
Ive tried the function eval(), but didnt work, and read some thing about get_the_content(), but it isnt working either. I dont know if i need to import something, i think it have something to do with wordpress, and im using raw php.
thanks for all your help!!! =)
Try the ob_...() family of functions. For example:
<?php
function f(){
echo 'foo';
}
//start buffering output. now output will be sent to an internal buffer instead of to the browser.
ob_start();
//call a function that echos some stuff
f();
//save the current buffer contents to a variable
$foo = ob_get_clean();
echo 'bar';
echo $foo;
//result: barfoo
?>
If you want to put the echo'd result of an include into a variable, you could do something like this:
//untested
function get_include($file){
ob_start();
include($file);
return ob_get_clean();
}
or if you want to put the echo'd result of a function call into a variable, you could do something like this:
//untested
//signature: get_from_function(callback $function, [mixed $param1, [mixed $param2, ... ]])
function get_from_function($function){
$args = func_get_args();
shift($args);
ob_start();
call_user_func_array($function,$args);
return ob_get_clean();
}
Depending on how the other file works...
If the other file can be changed to return a value, then you should use:
$content = require 'otherfile';
If the other file simply uses echo or some other way to print directly, use:
ob_start();
require 'otherfile';
$content = ob_get_clean();
You can receive string with include or require but you have to update those files before including to add return statement.
the file to be included should return result like this
<?php
$var = 'PHP';
return $var;
?>
and you can receive the $var data by including that file
$foo = include 'file.php';
echo $foo; // will print PHP
Documentation section
I have this code:
$layout_template = template_get("Layout");
$output_template = template_get("Homepage");
$box = box("Test","Test","Test");
eval("\$output = \"$layout_template\";");
echo $output;
In the $template_layout variable is a call for the
variable $output_template, so then the script moves onto the $output_template variable
But it doesn't go any further, inside the $output_template is a call to the variable $box, but it doesn't go any further than one level
I would never want nested eval(), and especially not in any recursive logic. Bad news. Use PHP's Include instead. IIRC eval() creates a new execution context, with overhead whereas include() doesn't.
If you have buffers such as:
<h1><?php echo $myCMS['title']; ?></h1>
I sometimes have files like Index.tpl such as above that access an associative array like this, then you just do in your class:
<?php
class TemplateEngine {
...
public function setvar($name, $val)
{
$this->varTable[$name]=make_safe($val);
}
....
/* Get contents of file through include() into a variable */
public function render( $moreVars )
{
flush();
ob_start();
include('file.php');
$contents = ob_get_clean();
/* $contents contains an eval()-like processed string */
...
Checkout ob_start() and other output buffer controls
If you do use eval() or any kind of user data inclusion, be super safe about sanitizing inputs for bad code.
It looks like you are writing a combined widget/template system of some kind. Write your widgets (views) as classes and allow them to be used in existing template systems. Keep things generic with $myWidget->render($model) and so on.
I saw this on the PHP doc-user-comments-thingy and it seems like a bad idea:
<?php
$var = 'dynamic content';
echo eval('?>' . file_get_contents('template.phtml') . '<?');
?>
Perhaps someone can enlighten me on that one :P
I have a class designated for a certain site. In that site I have different functions to retrieve data from the database and store that data into an array. I have other functions within the same class that take the data and format it into html and returns the html containing the data from the database.
For example...
function GetUserProfile($userID){
$query = 'SELECT * FROM users WHERE userID='.$userID;
.......
blah blah blah
.......
$user = mysqli->fetch_assoc();
return $user;
}
function FormatUserProfile($user, $showDesc = false){
$profile = '< h1 >'.$user['userName'].'< / h1 >';
if($showDesc){
$profile .= '< div >'.$user['description'].'< / div >';
}
return $profile;
}
...
So if i had a function to solely gather information, and another function to solely format that gathered information.
Mainly because I will be showing the same data on different pages, but Different pages show different data, like a search would only bring up the users name, where as the users profile page would bring up the username and the description for example.
Is that good practice, or is there a better way to do this?
It's a good practice. Personally, I use the following template "engine":
<?php
class Template{
static function show($path, $arg = NULL){
include "templates/$path.php";
}
static function get($path, $arg = NULL){
ob_start();
self::show($path, $info);
$block = ob_get_contents();
ob_end_clean();
return $block;
}
}
In your case the template would be like this:
<?php
echo '<h1>'.$arg['user']['userName'].'</h1>';
if($arg['showDesc']){
echo '<div>'.$arg['user']['description'].'</div>';
}
?>
You could unpack the array with the template arguments, but I prefer to keep it all in one place, so the code is less confusing. (You always know what is coming from the input, and what's defined in the template this way. To keep things shorter, you might use $_ instead of $arg too.) For a small example like this, the benefit is not obvious, but for larger templates it save a lot of variable manipulation, as you can use PHP's own templating abilities.
You can use Smarty template engine or something
similar.
It's templates are stored separately and look like this: http://www.smarty.net/sampleapp/sampleapp_p5.php