Link to home
Start Free TrialLog in
Avatar of drtester
drtester

asked on

PHP conditional string processor

I'm trying to make little function in php that processes if/then type statements within a string, removing any part of the string that doesn't match the condition.  For example:

$string="ABC[if $x==2]DEF[/if]GHI";
$x=2;
print process_string($string);

should return "ABCDEFGHI".  If $x were not 2, then it should return "ABCGHI".

The "[if " is the start tag for the condition, and the condition should be valid php code (could even be a more complex evaluation).  

I essentially need to swallow the tags, as well as any data between the [if] and [/if] if it isn't true.

Next, I really need this to be able to be recursive, just like in a programming language.  For example:

$string="ABC[if $x==2]DEF[if $y>7]GHI[/if]JKL[/if]MNO";
$x=2; $y=0;
print process_string($string);

Should print out "ABCDEFJKLMNO", because the first test is true, while the second is false.
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Is this an academic question or part of an application?  If it's the latter, tell us a little more about what you're trying to accomplish.  I've never seen a data construct like $string="ABC[if $x==2]DEF[/if]GHI"; in real-world programming and I'd like to learn more about how you are using it.  Thanks, ~Ray
Avatar of drtester
drtester

ASKER

This is part of a web app that will render html.  The input string will be more on the order of:

<html><head><title>[if $x=="e"]Editing Page[/if][if $x=="n"]Creating New Page[/if]</head><body>
<center><h1>[if $x=="e"]Editing Page[/if][if $x=="n"]Creating New Page[/if]</h1>

...etc...   There are already a number of other functions I have in this, such as the ability to print variables.  Now need to add conditionals so that I can only display certain things based on the variables.
Wow, sounds like a complicated CMS or something... I'll monitor this, but I may not be able to help.  Consider putting this into the REGEX zone if you don't get a good answer here.

Best of luck, ~Ray
where is this HTML coming from, a file, a database? If a file, you should be able to write raw PHP and it execute when it's included.
Yeah, sorta like a CMS thing.  I was thinking of using a regex to find the [if xxx] tag, but the code could span multiple lines.  My example above could also be written:

<html><head><title>[if $x=="e"]Editing Page</head><body>
<center><h1>Editing Page[/if]
[if $x=="n"]Creating New Page</head><body>
<center><h1>Creating New Page[/if]
</h1>

I'm guessing there would be some sort of function you would call from within the function (perhaps itself?), so that when you find the if tag, you then call this to look for the un-if... and if there are further ifs in there, you either process them or skip them, depending on the original condition's evaluation.
MMDeveloper: that's an idea, but a little messy.  The data may be coming from a file or a database.  I'd really like to not have to deal with writing new files inside the webserver root, dealing with permissions, etc.  Besides, this will be a multiuser thing, and different people will be using the same processor with different input and conditions.
ASKER CERTIFIED SOLUTION
Avatar of ddrudik
ddrudik
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
drtester, you can remove the
  $pass=1;
and
  $pass++;
lines, they were just there for testing and are not needed in production.
Ddrudik: MOST EXCELLENT!!!  That is exactly what I was looking for!  I'm not sure I quite follow the regex yet, but I kinda see basically what's going on.  

Yes, I can be sure the string to be evaluated will be sanitized - it will be generated by other code, so no worries there.  (Can definitely see how that would be a huge hole, since we're causing php to evaluate raw code).

Thanks again!

drtester
drtester, glad to help, thanks for the question and the points.
as for the regex patterns, this one matches non-nested [if ...] ... [/if] blocks, which is to process the inner-most nested if blocks first, continuing while there are still non-nested if blocks found in the string:
'~\[(if[^\]]*)\]((?:(?!\[/?if).)*)\[/if\]~is'

and this regex pattern is for varnames:
'/\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/'
from:
http://us3.php.net/language.variables
which is used to set the variables outside of the function to global before eval so they are available in the function.