How to force string interpolation when one comes from the database?

Asked

Viewed 247 times

3

Assuming I have the variable:

$nome = "John Due";

When I do:

$mensagem = "Seja bem-vindo, {$nome}";

I will have the result "Welcome, John Due", because I defined my string with interpolation directly in the code. However, what I need to do is store this string template in the database and continue getting the same result. If today I store the string above in a column of the bank and display it, the result I have is "Welcome, {$name}", as if the interpolation did not occur.

There is a way to force string interpolation when the content comes from the database?

An equivalent way, reading the user input string template instead of reading it from the database can be seen in the ideone, showing that the string interpolation does not occur, even using {$name} in its contents.

2 answers

6


Interpolation works when the string is handled directly by the PHP interpreter. Since it is static in the code, it can analyze it and generate the necessary structure for the interpolation of information.

When a string is stored in the database, it ceases to be evaluated directly by the interpreter for security reasons. Since the content comes from external sources, it is understood that the developer will not have full control over the content and therefore it was decided not to evaluate it to avoid possible security loopholes.

A very sensitive way to resolve yourself is to indicate to the interpreter that he should evaluate the string that way and this is done through the function eval. With the eval you assume that the data source is secure and that evaluate the interpolation of the string will not expose any sensitive application data.

Considering

// Texto vindo do banco de dados:
$smsQuery->message = "Você Possui Fatura em Aberto. Fatura: {$destinatario->identificador}";
$destinatario->identificador = "687918";

In performing eval($smsQuery->message) to string would be evaluated by interpolation of values.

Another way is to do the translation of your characters string. Instead of defining, for example:

"Você Possui Fatura em Aberto. Fatura: {$destinatario->identificador}"

You can do

"Você Possui Fatura em Aberto. Fatura: {{identificador}}"

And in PHP do the proper translation of the characters:

$dados = ['{{identificador}}' => $destinatario->identificador];

echo strtr($smsQuery->message, $dados);

Thus, you, as a developer, will have full control over the data exposed through the array $dados. Values not specified therein array shall not be altered and shall remain in string final.

See working on Ideone.

  • Other option: sprintf.

  • @bfavaretto I don’t know if sprintf will fit in this case, because as the number of variables in the template may vary, you will not know which values to replace. The template would look like "Olá %s" and we wouldn’t know which variable to replace.

  • Yeah, with sprintf It can’t be as automatic, but it’s a kind of consolidated option for storing templates. But I agree it’s bad to lose the semantics of variables.

  • Using strtr worked perfectly, but now I will have to develop something to recover all the names of the query fields, to add in the $data matrix, as they will be the variables available to use within $smsQuery->message

0

I would like to thank you very much for the help, I ended up using str_replace, I thought it was better, follow how it was my method, I’m using Laravel.

public function EnviarSMSInadimplentes()
    {

        try
        {
            $smsQuerys = DB::select(DB::raw("SELECT * FROM  SMS"));

            foreach($smsQuerys as $smsQuery):

                $destinatarios = DB::select(DB::raw($smsQuery->query));

                foreach($destinatarios as $destinatario):

                    $variaveis = array();
                    $valores   = array();

                    $camposQuery =  DB::getSchemaBuilder()->getColumnListing('V_SGI_SMSINADIMPLENTES');

                    foreach($camposQuery as $campo):
                        $campo = strtolower($campo);
                        $variaveis[] = "#$campo#";
                        $valores[] = $destinatario->$campo;
                    endforeach;

                    $message = str_replace($variaveis, $valores, $smsQuery->message);
                    //die($message);

                    EnviarSmsJob::dispatch($smsQuery->proccess,$destinatario->identificador,'550000000000',$message,$smsQuery->identifiertype)
                                    ->delay(now()->addMinutes(0))
                                    ->onQueue('SMS');
                endforeach;

            endforeach;
        }
         catch(Exception $e)
         {
            echo 'Ocorreu algum erro no processo';
         }

    }

Below the string stored in the message field of the SMS table, recovered through the property: $smsQuery->message

Invoice #identifier##maturity#

Browser other questions tagged

You are not signed in. Login or sign up in order to post.