Home » Php » php – Is it possible to reuse a double quoted string with variables?

php – Is it possible to reuse a double quoted string with variables?

Posted by: admin February 25, 2020 Leave a comment

Questions:

The application I’m writing generates some HTML server side though it could be applied to just any string.

$badges = [
    "<span class='badge badge--brand badge--inline'>$target</span>",
    "<span class='badge badge--dark badge--inline'>$target</span>",
    "<span class='badge badge--primary badge--inline'>$target</span>",
    "<span class='badge badge--success badge--inline'>$target</span>",
    "<span class='badge badge--info badge--inline'>$target</span>",
    "<span class='badge badge--warning badge--inline'>$target</span>",
    "<span class='badge badge--danger badge--inline'>$target</span>",
];

$TargetStr = 'one,two,three';

$Targets = explode(',', $TargetStr);
$Badges = '';
foreach ($Targets as $index => $target) {
    $Badges .= $badges[$index % count($badges)];
}
echo $Badges;

The desired output would be:

<span class='badge badge--brand badge--inline'>one</span><span class='badge badge--dark badge--inline'>two</span><span class='badge badge--primary badge--inline'>three</span>

I realize the $target variables are being evaluated inside the array, before it reaches the loop. With error reporting, this fails and without it, there is nothing in place of $target.

I can certainly just leverage str_replace and achieve desired results but this seemed like an interesting solution if I could get it to work.

Is it possible to achieve this? I haven’t tried using eval and I would prefer not to as the $TargetStr is user supplied.

How to&Answers:

You can set these spans as format strings instead.

$badges = [
    "<span class='badge badge--brand badge--inline'>%s</span>",
    "<span class='badge badge--dark badge--inline'>%s</span>",
    "<span class='badge badge--primary badge--inline'>%s</span>",
    "<span class='badge badge--success badge--inline'>%s</span>",
    "<span class='badge badge--info badge--inline'>%s</span>",
    "<span class='badge badge--warning badge--inline'>%s</span>",
    "<span class='badge badge--danger badge--inline'>%s</span>",
];

Then use sprintf to print the spans with your variables.

$TargetStr = 'one,two,three';

$Targets = explode(',', $TargetStr);
$Badges = '';
foreach ($Targets as $index => $target) {
    $Badges .= sprintf($badges[$index % count($badges)], $target);
}
echo $Badges;

If you like, you could also use sprintf() to insert the different badge types to eliminate the repeated markup.

$badges = ['brand', 'dark', 'primary', 'success', 'info', 'warning', 'danger'];
$span = "<span class='badge badge--%s badge--inline'>%s</span>";

$TargetStr = 'one,two,three';

$Targets = explode(',', $TargetStr);
$Badges = '';
foreach ($Targets as $index => $target) {
    $Badges .= sprintf($span, $badges[$index % count($badges)], $target);
}
echo $Badges;

Answer:

I would prefer this:

$badges = [
    "<span class='badge badge--brand badge--inline'>{{target}}</span>",
    "<span class='badge badge--dark badge--inline'>{{target}}</span>",
    "<span class='badge badge--primary badge--inline'>{{target}}</span>",
    "<span class='badge badge--success badge--inline'>{{target}}</span>",
    "<span class='badge badge--info badge--inline'>{{target}}</span>",
    "<span class='badge badge--warning badge--inline'>{{target}}</span>",
    "<span class='badge badge--danger badge--inline'>{{target}}</span>",
];

$TargetStr = 'one,two,three';

$Targets = explode(',', $TargetStr);
$Badges = '';
foreach ($Targets as $index => $target) {
    $Badges .= str_replace('{{target}}', $target, $badges[$index % count($badges)]);
}
echo $Badges;

eval solution (tested / Working):

<?php
        //Enter your code here, enjoy!
$badges = [
    '<span class="badge badge--brand badge--inline">$target</span>',
    '<span class="badge badge--dark badge--inline">$target</span>',
    '<span class="badge badge--primary badge--inline">$target</span>',
    '<span class="badge badge--success badge--inline">$target</span>',
    '<span class="badge badge--info badge--inline">$target</span>',
    '<span class="badge badge--warning badge--inline">$target</span>',
    '<span class="badge badge--danger badge--inline">$target</span>',
];

$TargetStr = 'one,two,three';

$Targets = explode(',', $TargetStr);
$Badges = '';
foreach ($Targets as $index => $target) {
    $Badges .= eval(" ?>".preg_replace('/>([^<]+)</', '><?php echo $1; ?><', $badges[$index % count($badges)]). "<?php ");
}
echo $Badges;

Answer:

this works better, I think:

<?php
        //Enter your code here, enjoy!
$badges = [
    '<span class="badge badge--brand badge--inline">$target</span>',
    '<span class="badge badge--dark badge--inline">$target</span>',
    '<span class="badge badge--primary badge--inline">$target</span>',
    '<span class="badge badge--success badge--inline">$target</span>',
    '<span class="badge badge--info badge--inline">$target</span>',
    '<span class="badge badge--warning badge--inline">$target</span>',
    '<span class="badge badge--danger badge--inline">$target</span>',
];

$TargetStr = 'one,two,three';

$Targets = explode(',', $TargetStr);
$Badges = '';
foreach ($Targets as $index => $target) {
    $Badges .= eval(" ?>".preg_replace('/($[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/', '<?php echo $1; ?>', $badges[$index % count($badges)]). "<?php ");
}
echo $Badges;