Page 1 of 1

Working with 2 multidimensional arrays in a loop

Posted: Fri Dec 24, 2010 2:23 pm
by ff8raider
Ok, I'm fairly new to PHP, but I've been able to figure most everything out so far. I ran into a problem that I could really use some help with.

First of all, I'm dealing with a proprietary cms, that my boss payed $10,000 for.

This CMS uses Tinymce, to edit html code which it stores in our database. Then the content is simply retrieved, and echoed to the main content division.

2 Problems with this: I can not have dynamic database content, directly in any of my pages, and I end up with a new php template for every new thing I want to do, like displaying a database search. So when I want to make a change to any sidebar or anything, I have to make that change in *15 different php templates.

So here is what I'm trying to do: I added support for a custom html tag in Tiny_MCE, let's say my tag is just <bens>. So, I write my php code between the <bens> tag, tinymce doesn't strip it out, and it gets stored in the database. Now the tricky part:

In the main php template, the page content is retrieved and is stored to the $content variable. After this happens, I run a preg_match_all for code between the <ben> tags. I capture the code, and the offset, and at creates a multidimensional array with the php code, and where it was in the $content. Then I run a preg_split on the <bens> tag, and all code between it, and capture the output, which gives me chunks of normal code that was around the <bens> tag. So after this I end up with 2 multidimensional arrays.

How I want these to work is: If there is a <bens> tag first, evaluate it, and then display the normal content, UP to the next <bens> tag. Then evaluate that, display the next chunk of normal content, and so on, until it reaches the end. This should give me dynamic access to php, from within my pages, and eliminate the need for 15 different php templates.

How I would like to be able to do it in a perfect world, is to load up both arrays in a single for each loop. then have variables passed from both arrays like: $htmlkey $htmlvalue, and $phpkey $phpvalue. Then I could just do echo $htmlvalue , eval $phpvalue.

I can not figure out how to set up a foreach loop to iterate through 2 different multidimensional arrays at the same time, passing their variables to the loop. The fact that they are multidimensional makes it more difficult.

Am I going about this completely wrong? Do I need to combine the arrays somehow? Does anybody have any suggestions? I would appreciate any help at all, Thank you very much.

Re: Working with 2 multidimensional arrays in a loop

Posted: Sat Dec 25, 2010 4:46 am
by Darhazer
Isn't it much easier to replace <bens> with <?php, and </bens> with ?> and then just eval the whole page :)

If this is not an option, can you please show examples of the 2 arrays. You need to map the keys of the first array to the keys of the second in order to loop both of them in a single loop.

Re: Working with 2 multidimensional arrays in a loop

Posted: Sat Dec 25, 2010 2:12 pm
by ff8raider
I honestly wasn't aware the eval function worked like that! Eval will Just echo anything that isn't between <? ?> Tags, and evaluate what is, in order? And to think I worked on those regexs forever. I will surely give this a try on monday, when I go back to work. I had a feeling I was doing about 30 steps too many, but I couldn't think of any other way, because I was assuming that eval only took php code. Thanks a lot for the simple answer, and I'll let you know how it works.

Happy Holidays!

Re: Working with 2 multidimensional arrays in a loop

Posted: Sun Dec 26, 2010 3:25 am
by Darhazer
ff8raider wrote:I honestly wasn't aware the eval function worked like that! Eval will Just echo anything that isn't between <? ?> Tags, and evaluate what is, in order? And to think I worked on those regexs forever. I will surely give this a try on monday, when I go back to work. I had a feeling I was doing about 30 steps too many, but I couldn't think of any other way, because I was assuming that eval only took php code. Thanks a lot for the simple answer, and I'll let you know how it works.

Happy Holidays!
Well, actually eval() really works only on PHP but here are 2 ways to go around this:
write the output to a file and include it via include() - it will work on mixed PHP/HTML
replace <bens> with "; and </bens> with;echo" - add echo " in the beginning and "; and escape all " in thens text, so the output of

Code: Select all

<p>this is some "text", <bens>echo $var;</bens></p>
become:

Code: Select all

echo "<p>this is some \"text\", "; echo $var;echo"</p>";
and then you can eval it

Edit: third solution:
You can use preg_replace_callback instead of decomposing, evalueting and composing the content again. It accepts a callback function and each mach will be passed to the callback function, and will be replaced with its return value. And your callback should just eval the code and return the output :)

Re: Working with 2 multidimensional arrays in a loop

Posted: Mon Dec 27, 2010 4:52 pm
by ff8raider
Hmm... Well preg_replace_callback seemed like the easiest way to go, but I seem to be having some trouble with it.

Here is the editor html code that gets passed to the $content variable.:

Code: Select all

<p>This one is anchorage to Denali</p>
<p><textarea> echo "This is price 1"; </textarea></p>
<p>Heres a bunch of whatever</p>
<p><textarea> echo "This is price 2"; </textarea></p>
<p>Heres a bunch of whatever2</p>
<p><textarea> echo "This is price 3"; </textarea></p>
I'm just using textarea to hold my code currently.

Here is my preg replace line in my main php file:

Code: Select all

$content = preg_replace_callback('%<textarea>.*?<\/textarea>%is', evalphpcode_fn, $content);
And here is my evalphpcode function:

Code: Select all

function evalphpcode_fn($matches) {

$matches = preg_replace('%<textarea> | <\/textarea>%',"", $matches);
foreach( $matches as $key => $value ) {
$matches = $value;
}

$matches = eval($matches);
return $matches;

}
I know that's a sloppy way of converting an array to a string, but I can't seem to get implode to work.

Anyways, all that together outputs this:

This is price 1This is price 2This is price 3

This one is anchorage to Denali

Heres a bunch of whatever

Heres a bunch of whatever2

It's just sticking all the evaluated code at the top, instead of where each replaced line was, and I'm not sure why. Am I doing something blatantly wrong here?

EDIT: I figured it out, the eval function can't be used like that, you have to capture the output.

Edit Again: The new problem I'm having is this: I need to evaluate multiple statements, like

Code: Select all

echo "something";
echo "something else";
As far as I can tell this is not possible with the eval function, it dies on the first ;

So what do I need to do? Split the array using ; as a delimiter and evaluate each one separately?