I have an XML file that contains FAQs, but some of the contents of the answers need to use PHP functions to output appropriate content.
How can I find the placeholders within the answers, and replace them with PHP functions? Ideally, I would like to be able to have the functions set as variables to be changeable across multiple websites this code would be used on.
XML File (placeholders in last block, %LOCAL_NO% and %PREM_NO%)
<?xml version="1.0" encoding="UTF-8"?>
<faqs>
<faq>
<category>General</category>
<q>How old do I have to be to use your service?</q>
<a>You must be at least 18 years of age.</a>
</faq>
<faq>
<category>General</category>
<q>How long is a psychic reading?</q>
<a>The length of a psychic reading is completely up to you. It depends on the number and complexity of the questions you ask. The average length of a reading is 15 to 20 minutes.</a>
</faq>
<faq>
<category>General</category>
<q>Can I choose the psychic I speak with?</q>
<a>Of course! You can choose who you would like to speak to by selecting your desired psychic's profile and following the online prompts via the online booking page, or call us on %PREM_NO% and enter their PIN, or call %LOCAL_NO% and our live receptionists will connect you to a psychic that matches your requirements!</a>
</faq>
</faqs>
PHP output
<?php // General FAQs
$faqGeneral = $xml->xpath("/faqs/faq[category='General']");
echo "<h2>General</h2>";
foreach ($faqGeneral as $faq) { ?>
<h3><?php echo $faq->q; ?></h3>
<p><?php echo $faq->a; ?></p>
<?php } ?>
If you know the strings to match and the values before (i.e., not dynamic) then you can just do a str_replace
inline.
If they are dynamic then you can grab the values from your database (or wherever you are storing them) and then loop through and str_replace
them.
Or, you could use regex, something like /(\%[a-z_]+\%)/i
. For that you can look into preg_match_all
.
Update: You can use arrays as parametera for str_replace
. E.g.,
$find = array('%PREM_NO%', '%LOCAL_NO%');
$replace = array('012345', '67890');
$answer = str_replace($find, $replace, $faq->a);
That looks like a case for preg_replace_callback
, of course called before evaluating the XML. Which also ensures that the "PHP-echoed" values do not break XML syntax.
$data = array(
'tags' => array(
'PREM_NO' => '1-800-CSICOP',
)
);
$filledXML = preg_replace_callback(
'#%(\\w+)%#', // A-Z and underscore between %%'s
function ($matches) use ($data) {
switch($matches[1]) {
case 'PREM_NO':
case 'WHATEVER':
return $data['tags'][$matches[1]];
case 'YYYYMMDD':
return date('Y-m-d');
default:
return '';
}
},
$xmlString);
// $xml = loadXML($xmlString);
$xml = loadXML($filledXML);
This allows for special tags such as YYYYMMDD to return runtime-calculated values, as well as externals. You can even include a PDO handle in $data and be able to run SQL queries inside the function.
$tags = array(
'%PREM_NO%' => '12345',
'%YYYYMMDD%' => date('Y-m-d'),
// ... et cetera
);
$filledXML = str_replace(array_keys($tags), array_values($tags), $xmlString);