Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Atnaize's avatar

Use HTML template with PHP variable in blade

I want to store templates as html string with PHP variables in my DB. So far I'm already storing things like that

<p>Hi</p> <p>&nbsp;</p> <p>This is case n&deg; {{$surgery-&gt;id}} and the user responsible is <b>Dr. {{$surgery-&gt;surgeon-&gt;lastname}}</b></p>

In my controller I use something like this

$template = \App\Template::find(1); //Get text from DB

$output = preg_replace_callback('~\{\{(.*?)\}\}~', //Manage only var between {{ and }}
            function($key)
            {
                $surgery = \App\Surgery::find(1);

                $variable['$surgery->id'] = $surgery->id;
                $variable['$surgery->surgeon->lastname'] = $surgery->surgeon->lastname;
                //...

                return $variable[$key[1]];
            },
            htmlspecialchars_decode($template->html)); //Decode the HTML

return view('home' , compact('output'));

And in my view I use

{!! $ouput !!}

This is all working fine but I'm asking how can I improve this script to automate the translation between $variable['$surgery->id'] and $surgery->id because there are a lot of relations and I don't want to write them all.

I tried that

function($key)
{
    $surgery = \App\Surgery::find(1);

$test = substr($key[1], 10 //And I can't add the parenthesis without being blocked by Cloudflare, don't know why ...

    $variable['$surgery->' . $test] = $surgery->$test;

    return $variable[$key[1]];
    
}

It is working for direct relation like $surgery->id ou $surgery->name but not when there are many "arrows" so when this an attribute of a relation like $surgery->relation->attribute

0 likes
4 replies
Snapey's avatar
Snapey
Best Answer
Level 122

Haven't got time to go into this now, but consider this tinker session. It might give you an idea

>>> $u=User::find(1)
[!] Aliasing 'User' to 'App\User' for this Tinker session.
=> App\User {#786
     id: 1,
     member_id: 17,
     email: "[email protected]",
     loginToken: "8hTSYvBQkXNe0gHS3nuYFn1Ji",
     name: "Yvonne Reid",
     created_at: "2018-01-15 21:59:45",
     updated_at: "2018-01-15 21:59:45",
   }

>>> ${'u'}
=> App\User {#786
     id: 1,
     member_id: 17,
     email: "[email protected]",
     loginToken: "8hTSYvBQkXNe0gHS3nuYFn1Ji",
     name: "Yvonne Reid",
     created_at: "2018-01-15 21:59:45",
     updated_at: "2018-01-15 21:59:45",
   }

>>> ${'u'}->{'name'}
=> "Yvonne Reid"

>>> ${'u'}->{'member'}->{'surname'}
=> "Reid"

if your placeholders in the template were like "surgery.surgeon.lastname" then you could explode it into its parts and insert into the variable.

$parts = explode('.' , 'surgery.surgeon.lastname');

$data = ${$parts[0]}->{$parts[1]}->{$parts[2]};

I'm sure this can be refactored

anyway, it might help

1 like
Atnaize's avatar

@Snapey Thank you so much, you are a living god!

I did not find a perfect way to refactore this so I went with this


function($key)
                {
                    $surgery = \App\Surgery::find(1);

                    $parts = explode('.' , $key[1]); 

                    switch ( count($parts) ) {
                        case '2':
                            $data = ${$parts[0]}->{$parts[1]};
                            break;

                        case '3':
                            $data = ${$parts[0]}->{$parts[1]}->{$parts[2]};
                            break;

                        case '4':
                            $data = ${$parts[0]}->{$parts[1]}->{$parts[2]}->{$parts[3]};
                            break;
                        
                        default:
                            $data = 'NULL';
                            break;
                    }
                                        
                    return $data;
                }

I know this is not the best option but at least it's working well. I'll be glad if someone have time to improve this!

Snapey's avatar

One thing I would do is use ?? to protect against null objects

If you do this;

                            $data = ${$parts[0]}->{$parts[1]}->{$parts[2]} ?? 'null' ;

it will insert the word 'null' if the relation is missing rather than throwing an invalid object error (php7.x feature - null coalesce operator)

Please or to participate in this conversation.