I do not know if this is at all possible.
I am fully aware that if $stringname = 'Rating'
, then $stringname()
will be the same as the function call Rating()
. I also know that if $stringname = 'size'
, then ${$stringname}
will be the same as $size
. My thoughts hinge on these facts.
What I'm trying to do is put in an XML function call for the PHP, to insert the results of a function into some text.
Two examples of this XML function call are:
<Function name="ListCensors">
<Arg name="pginf" />
<Arg value="/Lib:MainPage/child::*[self::Lib:Page or self::Lib:Series]/@rating" />
<Arg value="//Gen:Ratings/Gen:Rating[contains(|InsertList|,@code)]" />
</Function>
and
<Function name="RatingImage">
<Arg value="Web_G" />
<Arg value="m" />
</Function>
You'll notice that these have a different number of arguments (RatingImage()
has two, while ListCensors()
has three), and that the first argument for the ListCensors()
function call has the attribute name (pginf) instead of a value. This is because while the attribute value passes a string, the attribute name refers to a variable name already defined in the PHP.
So, here is the PHP, which currently does not work.
$func = $maintxt_child->getAttribute('name');
$func_arg_els = $maintxt_child->getElementsByTagName('Arg');
$func(for($func_arg_el_num = 0; $func_arg_el_num < $func_arg_els->length; $func_arg_el_num++){
if($fun_arg_els->item($func_arg_el_num)->hasAttribute('value')){
$func_arg_els->item($func_arg_el_num)->getAttribute('value')
} else {
${$func_arg_els->item($func_arg_el_num)->getAttribute('name')}
}
});
What I'm trying--and failing--to pull off is to set up something where the <Function>
element can refer to ANY PHP function I've defined and loop through the Arg elements to send the proper information to these PHP functions. How would be the right way of doing this? If it is impossible, let me know, so I can figure out different ways of doing things. Thanks.
I think this gives you what you are after, there are some potential issues which I will cover at the end.
In this example, I'm just calling the Test()
function with a value and a variable. As I only have the one function defined, the idea would be to find the appropriate function and then extract the parameters to an array with all of the values. Then once they have all been extracted, just call the function with this $parameters
array and use the array unpacking operator (...
) to expand them into the separate values...
$def = '
<ListFn>
<Function name="Test">
<Arg value="Web_G" />
<Arg name="m" />
</Function>
</ListFn>';
$dom = new \DOMDocument();
$dom->loadXML($def);
// Test function to call
function Test(string $a, string $b) {
echo "{$a}->{$b}".PHP_EOL;
}
// Set up a variable for the call
$m = "1234";
// Just use the first Function definition
$fn = $dom->getElementsByTagName("Function")[0];
// Function name
$func = $fn->getAttribute('name');
// Extract parameters
$parameters = [];
foreach ( $fn->getElementsByTagName("Arg") as $arg ) {
if ( $arg->hasAttribute("value") ) {
$parameters[] = $arg->getAttribute("value");
}
else {
$parameters[] = ${$arg->getAttribute("name")};
}
}
// Call the function
$func(...$parameters); // Displays Web_G->1234
This has limitations in that you cannot use things like arrays(name="m[1]"
), objects(name="m->var1"
), pass by reference and there are other limitations.