Объединение строк и переменных в PHP

В PHP есть несколько вариантов указания строк, но большинство из нас знакомо только с их определением в кавычках. Иногда эти строки простые, и мы можем использовать их как есть, но чаще всего мы хотим, чтобы они были динамическими, связанными с различными переменными.

Важно иметь хорошее представление о том, как строки могут быть объединены с любой переменной.

Наиболее распространенные подходы к адаптации строк заключаются в использовании:

  1. Одинарные кавычки с конкатенацией
  2. Двойные кавычки с переменной в строке
  3. функции sprintf (vsprintf)
  4. синтаксис heredoc (newdoc)

Остановимся на каждом варианте — его сильных и слабых сторонах.

Сначала немного теории.

Теория

#1 Одинарные кавычки с конкатенацией

Строка в одинарных кавычках не содержит интерпретируемых переменных. В отличие от других параметров, переменные в строке с одинарными кавычками не будут расширены при появлении. Это означает, что необходимо использовать конкатенацию.

'Variable is' . $var; 

#2 Двойные кавычки с переменной в строке

В случае двойных кавычек компилятор PHP будет расширять каждую переменную внутри строки следующим образом.

"Variable is {$var}"; 

#3 Функция sprintf (vsprintf)

Sprintf — самая мощная и продвинутая функция форматирования строк в PHP fi1a/format, предлагающая множество опций для управления конечным результатом. Он позволяет форматировать строки в соответствии со специальным языком шаблонов и кажется гораздо более мощным способом вставки в них переменных, но с наибольшими затратами времени на обработку.

Функция sprintf принимает строковый шаблон в качестве первого аргумента. За ним может следовать бесконечное количество аргументов —  sprintf заменит заполнители в строке в соответствии с аргументами, которые вы передаете функции.

sprintf('Variable is %s', $var); 

# 4 здесь документ (и сейчас документ)

Здесь документ определяется как раздел файла исходного кода, который обрабатывается так, как если бы он был отдельным файлом.

Улучшенный синтаксис (начиная с PHP 7.3) позволяет использовать heredoc более читаемым, понятным и менее подверженным ошибкам способом. Heredoc позволяет вам делать то, что сложнее сделать в кавычках. Позволяет определить блок текста как литерал.

По умолчанию PHP обрабатывает heredoc, как если бы это была строка в двойных кавычках, а nowdoc, как если бы это была строка в одинарных кавычках. Чтобы использовать nowdoc, просто поместите идентификатор открытия в одинарные кавычки.

синтаксис heredoc:

$str = <<<STR
Variable is $var
STR;

синтаксис нового документа:

$str = <<<'STR'
Variable is $var
STR;

Упражняться

Давайте проверим каждый подход на нескольких примерах.

Посмотрите на следующий текст:

Knock knock, "LANG" has you. Wake up NAME, ACTION

конкатенация №1

$str = 'Knock knock, "' . $lang . '" has you. Wake up ' . $name . ', ' . $action;

Здесь много кавычек, конкатенаций и лишних пробелов.

#2 Переменная в строке 

$str = "Knock knock, \"{$lang}\" has you. Wake up {$name}, {$action}";

Это выглядит намного лучше. Только не забывайте предварять переменные и специальные символы символами (в данном случае — «).

#3 Спринтф

$str = sprintf('Knock knock, "%s" has you. Wake up %s, %s', $lang, $name, $action);

Это также выглядит вполне читабельно, без использования escape-символов. 

При желании мы можем передать переменные в виде массива.

$vars = [
 'PHP',
 'Developer',
 'time to code'
];
$str = sprintf('Knock knock, "%s" has you. Wake up %s, %s', ...$vars);

То же самое и с функцией vsprintf.

$str = vsprintf('Knock knock, "%s" has you. Wake up %s, %s', $vars);

#4 Вот документ

$str = <<<STR
Knock knock, "$lang" has you. Wake up $name, $action
STR;

Никаких побегов, конкатенаций или дополнительных кавычек, никаких вызовов функций, всего 3 строки простой строки.

Допустим, мы хотим добавить разметку с динамическими переменными:

<div class="container">
 <p style="font-size:SIZEpx;line-height:SIZEpx;">
   <span class="first-item" style="color:red">TEXT1</span>
   <span class="last-item" style="color:black">TEXT2/span>
 </p>
</div>

В этом случае мы рекомендуем использовать heredoc :

<<<TEXT
<div class="container">
 <p style="font-size:{$size}px;line-height:{$size}px;">
   <span class="first-item" style="color:red">$text1</span>
   <span class="last-item" style="color:black">$text2</span>
 </p>
</div>
TEXT;

Внутри строка выглядит аналогично, но нам нужно немного больше escape-символов — «\» и {}

"<div class=\"container\">
 <p style=\"font-size:{$size}px;line-height:{$size}px;\">
   <span class=\"first-item\" style=\"color:red\">{$text1}</span>
   <span class=\"last-item\"  style=\"color:black\">{$text2}</span>
 </p>
</div>";

Конкатенация выглядит менее читабельно, но благодаря форматированию не раздражает. Однако главная проблема здесь не в этом:

'<div class="container">
<p style="font-size:' . $size . 'px;line-height:' . $size . 'px;">
<span class="first-item" style="color:red">' . $text1 . '</span>
<span class="last-item"  style="color:black">' . $text2 . '</span>
</p></div>';

Представьте, что вы хотите добавить новую динамическую переменную в тег <p>  в синтаксисе heredoc.

display: $display;

или в двойных кавычках

display: {$display};

В то время как с одинарными кавычками нам нужно найти правильное место, прежде чем добавлять больше конкатенаций и кавычек, здесь очень легко сделать ошибку.

display:' . $display . ';">' . '

И для спринта :

sprintf('<div class="container">
<p style="font-size:%spx;line-height:%spx;">
  <span class="first-item" style="color:red">%s</span>
  <span class="last-item" style="color:black">%s</span>
</p>
</div>', $size, $size, $text1, $text2);

Передача многострочной строки выглядит не очень хорошо, если только вы не хотите сначала присвоить ее какой-либо переменной.

Также помните, что количество переменных заполнителей должно быть небольшим. В противном случае вам будет трудно найти путь через 10+ параметров, пытаясь добавить новый %s, найти элемент в списке параметров и добавить его в вызов sprintf.

В приведенном выше примере, если мы хотим добавить новую переменную

display: %s;

сразу после высоты строки нам нужно определить, что это третий параметр, и передать его в качестве аргумента между $size и $text1 . Разве это не звучит хорошо?

В этом случае вы можете попробовать поиграть с упорядоченными заполнителями, такими как %1$s , %2$s . Кроме того, эти заполнители можно повторять без добавления дополнительных аргументов в код.

sprintf('<div class="container">
<p style="font-size:%1$spx;line-height:%1$spx;display:%4$s">
  <span class="first-item" style="color:red">%2$s</span>
  <span class="last-item" style="color:black">%3$s</span>
</p>
</div>', $size, $text1, $text2, $display);

Сравнение производительности

Начальная конфигурация нашего теста:

  • PHP 7.3
  • Количество итераций — 5 000 000
  • Простой случай — Тук-тук, у $lang есть ты
  • Сложный — это Knock Knock, у вас есть «$ lang». Проснись $name, $action

Полученные результаты:

 ОДИНАРНАЯ КАВЫЧКАДВОЙНЫЕ КАВЫЧКИСПРИНТСПРИНТФ (ALT)HEREDOC
простой случай, мс275259533572260
сложный случай, мс685479935888487
Полученные результаты

МИФ: Использование « быстрее, чем ». PHP не будет использовать дополнительную обработку для интерпретации содержимого одинарных кавычек, тогда как с двойными кавычками PHP должен анализировать и проверять, есть ли какие-либо переменные.

В настоящее время аргумент о том, что один из этих вариантов лучше другого, трудно защитить, если вы не начнете объединять строки с переменными, и в этом случае метод двойных кавычек определенно выигрывает.

Резюме

Мы считаем вариант с переменной внутри строки наиболее удобным способом объединения строк и переменных. Однако обычно рекомендуется использовать каждый из этих методов для различных сценариев.

КатегорииБез рубрики

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *