Dynamic variable names in Smarty - php

I want to be access some variables I've assigned dynamically from PHP in Smarty, here is an example:
$content_name = 'body'
$smarty->assign('content_name',$content_name);
$smarty->assign($content_name.'_title',$title);
$smarty->assign($content_name.'_body',$body);
// assigned values
// $content_name = home
// $home_title = $title
// $home_body = $body
The reason I want to access these dynamically is because I call multiple versions of a function that includes the code above, they all use the same template and therefore don't want to simply use $title, $body etc as their valus will conflict with each other.
Given that I know I want to access the title and body variables based on the content_name I set, how can I achieved this within smarty?

Even if this post is very old, the given answere is accpeted but not an answere for the question. Its only an other oppertunity to handle main problem.
The question is how to use dynamic variables...
for the given sample, it should be something like
PHP
$content_name = 'body';
$title = 'hello ';
$body = 'world';
$smarty->assign('content_name',$content_name);
$smarty->assign($content_name.'_title',$title);
$smarty->assign($content_name.'_body',$body);
Smarty
{$content_name} //body
{${$content_name}_title} //hello
{${$content_name}_body} //world
{${$content_name}_title}{${$content_name}_body} my {$content_name} is awesome
//hello world my body is awesome
This is the dynamic way to use it. Even if its not the best way in this case :)
If you have kind of objects or multidimensional array... and you like to iterate them, you have to care about the whole string and not just the number...
For example:
PHP
$arr = [
"attr1" => "hello ",
"attr2" => "world ",
"attr3" => "my body is awesome"
];
$smarty->assign('foobar', $arr);
Smarty
{for $i=1 to 3}
{$foobar.{"attr$i"}} //works (whole name must be string var mix)
//{$foobar.attr{"$i"}} //fails
//{$foobar.attr{$i}} //fails
{/for}
But using {$foobar{$i}} on a simple array would work.
For all who need it, enjoy.

As per my comment on using an array instead of dynamic variables, here's an example of how to add the vars to an array:
php:
$vars = array();
function whatever() {
global $vars;
$vars[] = array(
'firstname' => 'Mike',
'surname' => 'Smith'
);
}
$smarty->assign('vars', $vars);
smarty:
{section name=loop loop=$vars}
Name: {$vars[loop].firstname} {$vars[loop].surname}
{/section}

Related

Fatal error: Using $this when not in object context using array_walk

I have made a class that should replace data at the hand of an array.
I insert
$data = array(
'bike',
'car',
'pc'
);
And it should translate the array to :
$data = array(
'[#bike]',
'[#car]',
'[#pc]'
);
I have written the following piece of code.
array_walk($PlaceHolders , function(&$value, $key) { $value = $this->Seperators['plcstart'].$value.$this->Seperators['plcend']; });
Which I am using in a class context.
The two sperators have the following value:
$this->Seperators['plcstart'] = '[#';
$this->Seperators['plcend'] = ']';
The problem is. At localhost it works superb!!
Now when I upload the system to a unix environment it stops working!
I have no clue why this is the result.
Would anyone here know what I am doing wrong?
I would recommend you to use array_map() when you want to modify array elements using a callback.
You could end with something like this
class TransformerClass {
private $Seperators = array(
'plcstart' => '[#',
'plcend' => ']'
);
public function transform(array $data) {
return array_map(
function($text) {
return $this->Seperators['plcstart'].$text.$this->Seperators['plcend'];
},
$data
);
}
}
Example:
$transformer = new TransformerClass();
$items = array(
'bike',
'car',
'pc'
);
$result = $transformer->transform($items);
And $result will contain your desired resulting data.
The most bizare thing is... This morning I opened the same page again.
And it worked like the offline environment :-S....
This is quite frustrating though!!
However I would like to make a few small notes:
///######## LOADING ALL PLACEHOLDERS
$PlaceHolders = array_keys($this->TplObjects);
///######## SEPERATOR START
$SeperatorStart = $this->Seperators['plcstart'];
$SeperatorEnd = $this->Seperators['plcend'];
///######## ADDING THE START AND END TAGS TO EACH ARRAY VALUE
array_walk($PlaceHolders , function(&$value, $key) { $value =
$SeperatorStart.$value.$SeperatorEnd; });
This is what I thought to be a solution but it is NOT!!
Why?? Because the way it was worked:
///######## LOADING ALL PLACEHOLDERS
$PlaceHolders = array_keys($this->TplObjects);
///######## ADDING THE START AND END TAGS TO EACH ARRAY VALUE
array_walk($PlaceHolders , function(&$value, $key) { $value = $this->Seperators['plcstart'].$value.$this->Seperators['plcend']; });
Because it got it's data directly out of the class.
By using function I placed the variables into it's own individual scope, hence the variable $SeperatorStart and $SeperatorEnd do not exist in this scope.
I could ofcourse import these two into that function. But I do not know how to do this with array_walk. I have not used this function this often hence I know only a few basic manners to use this function.
The second option as opted for above by #Falc works great! And is the method I was looking for. Hence thanks a million!!

PHP fast way to replace content within string between characters

In creating automatic emails certain parts of the email need to be replaced with stored data.
eg. Dear %first_name% %surname%, Thanks for attending the %place_name%.
This could be done with a string replace for each of them, but there must be a faster method.
Assuming that the variable name is identical to what we want from the system eg. %first_name% should be replaced with $user['first_name'] etc....
You can utilise preg_replace_callback to replace keys between %'s with array values:
$fields = array('first_name' => 'Tim', 'place_name' => 'Canada');
$string = preg_replace_callback('/%(.+?)%/', function($arr) use($fields)
{
$key = $arr[1];
return array_key_exists($key, $fields) ? $fields[$key] : $arr[0];
}, $string);
One option:
$vars = array(
'firstname' = 'Bob',
'surname' = 'Dole',
'place' = 'Las Vegas',
// ...
);
extract($vars);
include('my_template.phtml');
And in my_template.phtml:
<?php
echo <<<EOF
Dear $firstname $surname,<br>
Thank you for attending the Viagra and Plantains Expo in $place.
EOF;
?>
If you're worried about name collisions while using extract(), you can always use the EXTR_PREFIX_ALL option, or one of the other extraction methods.
Or, better yet, don't reinvent the wheel. Just use Smarty or mustache.php.
See also this question: PHP template class with variables?

Insert a String inside an Array

How can I include an string in an array?
emailconfig.php
$globalemail 'info#site.com'=>'site'";
I want to make a new array like this:
sendemail.php
include "emailconfig.php"
$fulllist=array('info#forum.com'=>'forum', '$globalemail');
// the Array MUST must appear above, ideally it would look like this
// $fulllist=array('info#forum.com'=>'forum', 'info#site.com'=>'site');
It brings PHP error because of the =>
One way is: in your emailconfig.php, you should have 2 variables, $globalemailkey and $globalemailvalue.
$globalemailkey = 'info#site.com';
$globalemailvalue = 'site';
$fulllist = array('info#forum.com'=>'forum', $globalemailkey => $globalemailvalue);
Or, store an array in emailconfig.php, and use array_merge.
$globalemail = array('info#site.com' => 'site');
$fulllist = array('info#forum.com'=>'forum');
$fulllist = array_merge($fulllist, $globalemail);
$fulllist=array('info#forum.com'=>'forum');
$globalemail = "info#site.com'=>'site'";
$parts = explode('=>', $globalemail);
$fulllist[trim($parts[0], "'")] = trim($parts[1], "'");
http://ideone.com/mmvu9
You could But You Shouldn't use eval to do something like eval("array($yourstring)");. But you shouldn't. really. please.
You can do all sorts of things like preg-match or explode, but couldn't you easier find the source of those pieces of information, and work from there?

Passing multiple variables to a view?

so,i have two variables $posts and $comments that holds the array of posts and comments respectively,i have a separate view that accepts these variables,executes a foreach loop and prints them on the same page. The question here is,how do i pass both the variables to a view?
If its a single variable i pass it like this $this->load->view('myview',$myvar).
I tried passing it as an array like this,but still it doesnt work.
$data=array($var1,$var2);
$this->load->view('myview',$data);
Any help would be greatly appreciated! Thanks.
You need to access the variable in your view as you pass it. Using array($var1,$var2); is valid but probably not what you wanted to achieve.
Try
$data = $var1 + $var2;
or
$data = array_merge($var1, $var2);
instead. See Views for detailed documentation how to access variables passed to a view.
The problem with using array($var1,$var2); is that you will create two view variables: ${0} and ${1} (the array's keys become the variable names, you have two keys in your array: 0 and 1).
Those variable names are invalid labels so you need to enclose the name with {} on the view level.
By that you loose the ability to name the variables usefully.
The easiest thing to do in your controller:
$data['posts'] = $posts;
$data['comments'] = $comments;
$this->load->view('your_view', $data);
Then, in your view you just simply do something like:
foreach($posts as $post) {
...
}
You can hold any object in the $data variable that you pass to your view. When I need to traverse through result sets that I get from my models I do it that way.
Using associative array looks the best possible solution.
take an array
$data = array(
'posts' => $posts,
'comments' => $comments,
);
$this->load->view('myview',$data);
Probably this will help you to get a solution.
this is another and recommended way using compact:
$data1 = 'your data';
$data2 = 123;
$data3 = array();
$this->load->view('myview', compact('data1', 'data2', 'data3');
try
$data1 = 'your data';
$data2 = 123;
$data3 = array();
$this->load->view('myview', $data1 + $data2 + $data3);
$this->render($views_array,$data);

Search for [ ] and replace everything between it

I have a template file that uses the structure
[FIRSTNAME]
[LASTNAME]
etc etc.... and I will be doing a search and replace on it. One thing that I would like to do is that when the template get's sent back, IF I haven't stipulated, [FIRSTNAME].... it still shows in the template... I would like to make it NULL IF I haven't stipulated any data to that variable.
in my code i'm using the FILE_GET_CONTENTS
$q = file_get_contents($filename);
foreach ($this->dataArray as $key => $value)
{
$q = str_replace('['.$key.']', $value, $q);
}
return $q;
So once that loop is over filling in the proper data, I need to do another search and replace for any variables left using, [FIRSTNAME]
I hope this makes sense any someone can steer me in the right direction.
Cheers
It sounds like you just want to add a line like:
$q = preg_replace('/\[[^\]]*\]/', '' , $q);
After all your defined substitutions, to eliminate any remaining square-bracketed words.
If you want to be concise, you can replace the whole function with a variation of the "one line template engine" at http://www.webmasterworld.com/php/3444822.htm, with square brackets instead of curlies.
You can actually pass arrays into the str_replace function as arguments.
$keys = array(
'FIRSTNAME',
'LASTNAME'
):
$replacements = array(
'George',
'Smith'
);
str_replace($keys, $replacements, $input);
And if you want to remove first name if its blank, why don't you just add it to the key => replacement array with a value of ''?
$this->dataArray['FIRSTNAME'] = '';
or something like
if (!isset($this->dataArray['FIRSTNAME'])) {
$this->dataArray['FIRSTNAME'] = '';
}

Categories