Forum Moderators: coopster

Message Too Old, No Replies

parsing variable in variable

         

Borek

3:19 pm on Mar 25, 2010 (gmt 0)

10+ Year Member



I have some kind of mental block. I am more C/C++ type and I need to dive into PHP only about once a year, so I don't have much experience.

If I use double quotes string is treated as a template and variables are replaces by their value, so

$name='John';
print("name is $name");


outputs 'name is John'. Simple.

However, I am thinking about going a step further and using variable as a template. Something like

$template = 'You need $flower';
$flower = 'rose';
more_fancy_print($template);


outputting 'You need rose'.

I can probably achieve similar effect using some combination of str_replace, or sprintf, or whatever, many ways to skin that cat. But if I could just parse the $template it would be simple and fast. Unfortunately nothing I see in PHP documentation seems to be related. Any ideas? Am I missing something obvious?

Matthew1980

3:41 pm on Mar 25, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there Borek,

As you said, many ways to skin a cat, though my first thought is this:- (Theres bound to be loads of suggestions thought!)

The var need's to be declared before you use it though..

$flower = "rose";
$template = "You need ".$flower;

echo $template;

or:-

print($template);

In this instance I just use the . to append the $var to the existing string then terminate the entire string with ; as normal.

Is that what you were referring to?

Cheers,
MRb

Borek

4:18 pm on Mar 25, 2010 (gmt 0)

10+ Year Member



No, trick is to have $template containing _names_ of variables that will be used.

$flower='rose';
$name='Greg';

// fetch '$name holds a $flower' into $template
print($template);
// fetch '$flower lies on the table' into $template
print($template);


I want my code to output

Greg holds a rose
rose lies on the table


This is very similar to what

print("$name holds a $flower");


does, but unfortunately I can't do it this way, as template is not part of the code - it is part of the data. What you suggest means writing separate code for every possible case, instead of using templates.

Readie

4:24 pm on Mar 25, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I think this may be what you're after:

$template = array(
'{NAME} holds a {FLOWER}',
'{FLOWER} lies on the table'
);

$name = 'Greg';
$flower = 'rose';

$output = '';

foreach($template as $temp) {
$temp = preg_replace('/{NAME}/m', $name, $temp);
$temp = preg_replace('/{FLOWER}/m', $flower, $temp);
$output = ucfirst($temp);
echo '<p>' . $output . '</p>';
}

Matthew1980

4:30 pm on Mar 25, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there Borek,

Ok, I think I have understood you this time.

str_replace(); will be the way to go I think, as long as the string your feeding into the function has 'place holder' ie; text or data that you know will be there in every instance given to you (I'm assuming as this is a user submitted thing)

NOTE: $name is a reserved var!

$replace_flower = "rose";
$replace_greg = "Greg";

$template = str_replace("known_pattern1",$Replace_name, $template);
$template = str_replace("known_pattern2",$replace_flower, $template);

You see the pattern there, then:-

print($template);

Hopefully I have understood you correctly this time ;-p

Cheers,
MRb

Borek

5:07 pm on Mar 25, 2010 (gmt 0)

10+ Year Member



Thank you both.

So from what I understand there is no easy way of doing it - I mean, it has to be hardcoded, no miracle function that does the trick (even if obviously similar function does exist somewhere in PHP parser/interpreter).

That's a good and a bad news. I wasn't missing anything obvious - that's the good part, I have to either rethink the idea or implement hardcode replacing - that's the bad part.

Not that coding it is difficult, it just makes things more complicated then intended. Sigh.

Readie

5:37 pm on Mar 25, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, you could build your own function, and simply have the pattern and the replacement in a MySQL database - and just loop through the values from the database inside the function.

Anyango

6:50 pm on Mar 25, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If i havent understood it wrong, whats tough about it. As matthew suggested, str_replace does the job just fine, without making things complex.

$template="you have a #flower#, and you have a #candy# and you have another #flower#";
$candy="Mars";
$flower="Rose";

$template = str_replace("#flower#",$flower,$template);
$template = str_replace("#candy#",$candy,$template);
echo $template;

Matthew1980

7:44 pm on Mar 25, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



HI there all,

Just noticed a typo from my post, just to clarify this:-

$replace_flower = "rose";
$replace_greg = "Greg";

was meant to be:-


$replace_flower = "rose";
$replace_name = "Greg";

Also..

Could you elaborate on the context to which this code/custom function would be in, from that we could help a little further. Ie: is it a user submitted string (from form) that will have to be sifted or data from a database that has to have certain values replaced on the way out?

Cheers,
MRb

Borek

8:29 pm on Mar 25, 2010 (gmt 0)

10+ Year Member



Template is from the database, it is not user submitted. These will be quizz questions built out of template and data. They have to vary between users, so method of generating individual questions must be flexible and able of generating similar yet different questions with different answers. So more like "Is George holding a rose?" than "George holds a rose." ;)

Matthew1980

9:08 pm on Mar 25, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



HI there Borek,

Aah, I see. I used to do pub quizzes too!

Right then, there is a way of achieving what you want, just means a little bit of mix and match ;-p

So the database holds the data, fixed text in other words, and you just want to alter set parts like names and objects almost on the fly, so that for every 'template' you 'generate' those preset words will change, seemingly in a random order so that every time you get a template printed off, there are differences that way. This is how I see your dilemma. Well if that's the case I wouldn't be that difficult.

1)SELECT data from your database
2)process the data
3)use str_replace to change words to make changes to the template and keep context of phrase or sentace?
4)Hey presto a quiz form.

$QuizzWordsFruits = array();

$QuizzWordsFruits[] = "apple";
$QuizzWordsFruits[] = "orange";
$QuizzWordsFruits[] = "kiwi";

$QuizzWordsNames = array();

$QuizzWordsNames[] = "James";
$QuizzWordsNames[] = "Daniel";
$QuizzWordsNames[] = "Susan";

Add to these as you see fit, then use these in conjunction with str_replce(); Just make sure that the template has place holders like {NAME} {FRUIT} and then you can replace the text like this:-

Shuffle the data to create almost random entries, but make sure there are lots of names there, but I am sure as you get the gist now ;-p

shuffle($QuizzWordsNames);
shuffle($QuizzWordsFruits);

$template = str_replace("{FRUIT}", $QuizzWordsFruits[2], $template);
$template = str_replace("{NAMES}", $QuizzWordsNames[2], $template);

//This should then return a different $template string each time you use the script

From this you should be able to work the rest out, there are other methods of doing a randomiser, but for now I can only think of this being the simplest solution. Coming from a C/C++ background this should be easy in comparision :) Kinda comical really as I am trying to do something in C at the moment, which I am struggling to do, writing an embedded web server on a Cyclone II FPGA, and failing upto yet :( Oh well, all good fun...

I hope you can see what I am trying to convey ;-p

Cheers,

MRb

Borek

10:02 pm on Mar 25, 2010 (gmt 0)

10+ Year Member



So it all boils down to str_replace. Bearable, but not exactly what I hoped for ;)

Borek

11:13 am on Mar 26, 2010 (gmt 0)

10+ Year Member



After some searching and thinking - printf with argument swapping will be probably better.

It is different approach then I thought about at first, but seems like it will be flexible enough for the purpose.