Зачем использовать функцию sprintf в PHP?

Я пытаюсь узнать больше о функции PHP sprintf(), но php.net не помог мне, так как я все еще смущен, почему вы хотите его использовать?

Взгляните на мой пример ниже.

Зачем использовать это:

$output = sprintf("Here is the result: %s for this date %s", $result, $date);

Если это делает то же самое и легче писать IMO:

$output = 'Here is the result: ' .$result. ' for this date ' .$date;

Я что-то пропустил?

Ответ 1

sprintf имеет все возможности форматирования исходного printf, что означает, что вы можете сделать гораздо больше, чем просто вставлять значения переменных в строки.

Например, укажите формат номера (шестнадцатеричный, десятичный, восьмеричный), количество десятичных знаков, отступы и многое другое. Google для printf, и вы найдете множество примеров. статья wikipedia на printf должна начать вас.

Ответ 2

Существует много вариантов использования sprintf, но один из способов, которыми я их использую, - это сохранить такую ​​строку: "Hello, My Name is% s" в базе данных или как константа в классе PHP. Таким образом, когда я хочу использовать эту строку, я могу просто сделать это:

$name = 'Josh';
// $stringFromDB = 'Hello, My Name is %s';
$greeting = sprintf($stringFromDB, $name);
// $greetting = 'Hello, My Name is Josh'

По сути, это позволяет некоторое разделение кода. Если я использую "Hello, My Name is% s" во многих местах моего кода, я могу изменить его на "% s - это мое имя" в одном месте и он обновляется повсеместно автоматически, без необходимости обращаться к каждому экземпляру и перемещаться конкатенации.

Ответ 3

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

Пример:

$color = 'blue';
$item = 'pen';

sprintf('I have a %s %s', $color, $item);

Но такой язык, как французский, заказывает слова по-разному:

$color = 'bleu';
$item = 'stylo';

sprintf('J\'ai un %2$s %1$s', $color, $item);

(Да, мой французский отстой: я изучил немецкий язык в школе!)

В действительности вы используете gettext для хранения локализованных строк, но вы получите эту идею.


Ответ 4

Легче перевести.

echo _('Here is the result: ') . $result . _(' for this date ') . $date;

Теперь строки перевода (gettext):

  • Вот результат:
  • для этой даты

При переводе на какой-то другой язык это может быть невозможно или это приводит к очень странным предложениям.

Теперь, если у вас есть

echo sprintf(_("Here is the result: %s for this date %s"), $result, $date);

Теперь строки перевода (gettext):

  • Вот результат:% s для этой даты% s

Это имеет гораздо больший смысл и гораздо более гибко переводит на другие языки

Ответ 5

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

Например, ваш сайт скажет "С возвращением [[Пользователь]]" в верхней части страницы. Как программист вы не знаете или не заботитесь о том, как ребята из UI собираются написать это - вы просто знаете, что имя пользователя будет показано где-то в сообщении.

Итак, вы можете вставлять сообщение в свой код, не беспокоясь о том, что это сообщение на самом деле.

Файл Lang (EN_US):

...
$lang['welcome_message'] = 'Welcome back %s';
...

Затем вы можете поддерживать любой тип сообщения на любом языке, используя это в своем фактическом php-коде.

sprintf($lang['welcome_message'], $user->name())

Ответ 6

зачем вы хотите его использовать?

Это очень полезно при использовании (внешнего) источника для языковых строк. Если вам нужно фиксированное количество переменных в данной многоязычной строке, вам нужно знать только правильное упорядочение:

EN.txt

not_found    = "%s could not be found."
bad_argument = "Bad arguments for function %s."
bad_arg_no   = "Bad argument %d for function %s."

hu.txt

not_found    = "A keresett eljárás (%s) nem található."
bad_argument = "Érvénytelen paraméterek a(z) %s eljárás hívásakor."
bad_arg_no   = "Érvénytelen %d. paraméter a(z) %s eljárás hívásakor."

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

Конечно, вы могли бы написать свою собственную функцию для выполнения этой замены, несомненно, даже при незначительном увеличении производительности, но это намного быстрее (если у вас есть класс Language для чтения языковых строк):

/**
 * throws exception with message($name = "ExampleMethod"):
 *  - using en.txt: ExampleMethod could not be found.
 *  - using hu.txt: A keresett eljárás (ExampleMethod) nem található.
 */
throw new Exception(sprintf(Language::Get('not_found'), $name));

/**
 * throws exception with message ($param_index = 3, $name = "ExampleMethod"):
 *  - using en.txt: Bad argument 3 for function ExampleMethod.
 *  - using hu.txt: Érvénytelen 3. paraméter a(z) ExampleMethod eljárás hívásakor.
 */
throw new Exception(sprintf(Language::Get('bad_arg_no'), $param_index, $name));

Он также имеет полные возможности printf, поэтому также является однострочным для форматирования множества типов переменных, например:

Ответ 7

Как уже упоминалось, он позволяет форматировать входные данные. Например, форсирование 2dp, 4-значных чисел и т.д. Это весьма полезно для построения строк запросов MySQL.

Другим преимуществом является то, что он позволяет отделять макет строки от данных, подаваемых в нее, почти как питание в параметрах. Например, в случае запроса MySQL:

// For security, you MUST sanitise ALL user input first, eg:
$username = mysql_real_escape_string($_POST['username']); // etc.
// Now creating the query:
$query = sprintf("INSERT INTO `Users` SET `user`='%s',`password`='%s',`realname`='%s';", $username, $passwd_hash, $realname);

Этот метод, конечно же, имеет другие применения, например, при печати вывода в формате HTML и т.д.

Изменить: По соображениям безопасности, при использовании техники, описанной выше , перед использованием этого метода необходимо очистить все входные переменные с помощью mysql_real_escape_string(), чтобы предотвратить атаки вставки MySQL. Если вы разобрали неанитированный ввод, ваш сайт и сервер будут взломаны. (За исключением, конечно, переменных, которые были полностью построены вашим кодом и гарантированно будут в безопасности.)

Ответ 8

Использование sprintf() намного чище и безопаснее форматировать вашу строку.

Например, когда вы имеете дело с входными переменными, это предотвращает неожиданные сюрпризы, заранее задавая ожидаемый формат (например, вы ожидаете строку [ %s] или номер [%d]). Это может потенциально помочь с возможным риском SQL injection, но это не помешает, если строка состоит из кавычек.

Это также помогает справляться с поплавками, вы можете явно указать точность цифр (например, %.2f), которая избавляет вас от использования функций преобразования.

Другими преимуществами являются то, что большинство основных языков программирования имеют собственную реализацию sprintf(), поэтому, познакомившись с ней, она становится еще проще в использовании, а не изучает новый язык (например, как конкатенировать строки или преобразование поплавков).

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

Например, см. приведенный ниже реальный пример:

$insert .= "('".$tr[0]."','".$tr[0]."','".$tr[0]."','".$tr[0]."'),";

Или какой-нибудь простой пример, который печатает, например. '1','2','3','4':

print "foo: '" . $a . "','" . $b . "'; bar: '" . $c . "','" . $d . "'" . "\n";

и печать с форматированной строкой:

printf("foo: '%d','%d'; bar: '%d','%d'\n", $a, $b, $c, $d);

где printf() эквивалентно sprintf(), но он выводит форматированную строку вместо того, чтобы возвращать ее (переменной).

Что более читаемо?

Ответ 9

Даже я, хотя то же самое, если только не использовал его в последнее время. Когда вы создаете документы на основе пользовательских входов, это будет удобно.

"<p>Some big paragraph ".$a["name"]." again have tot ake care of space and stuff .". $a["age"]. "also would be hard to keep track of punctuations and stuff in a really ".$a["token"]. paragarapoh.";

Что легко записать в виде

sprintf("Some big paragraph %s. Again have to take care of space and stuff.%s also wouldnt be hard to keep track of punctuations and stuff in a really %s paragraph",$a,$b,$c);

Ответ 10

Это:

"<p>Some big paragraph ".$a["name"]." again have to take care of space and stuff .". $a["age"]. "also would be hard to keep track of punctuations and stuff in a really ".$a["token"]. paragraph.";

Также можно написать:

"<p>Some big paragraph {$a['name']} again have to take care of space and stuff .{$a['age']} also would be hard to keep track of punctuations and stuff in a really {$a['token']} paragraph.";

По-моему, это яснее читать, но я вижу использование для локализации или форматирования.

Ответ 11

Некоторые из типичных случаев - это то, где вам нужен более точный контроль над выходным форматом. Это может быть сложно, например, удостовериться, что определенное значение имеет определенное количество пробелов, проложенных спереди, в зависимости от его длины или число, выводимое в определенном точном формате.

В руководстве PHP есть много примеров

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

Другой причиной использования sprintf или printf может быть то, что вы хотите, чтобы пользователь определял выходной формат некоторого значения - вы можете смело разрешить им определять формат вывода, совместимый с sprintf.

О, и ваш пример на самом деле ошибочен для одной части. sprintf возвращает строку, но echo не делает - echo немедленно выводит ее и ничего не возвращает, а sprintf просто возвращает ее.

Ответ 12

  • Если вы использовали C/С++, вы бы использовали функцию sprintf.

  • Существует хорошая вероятность того, что вторая строка менее эффективна. Echo сконструирован как команда вывода, тогда как sprintf предназначен для замещения токенов. Я не человек PHP, но я подозреваю, что с эхом есть больше объектов. Если он действует как Java, он создает новую строку каждый раз, когда что-то добавляется в список, поэтому вы должны создать 4 строки.

Ответ 13

Иногда у меня есть что-то вроде этого, что я считаю немного более легким для чтения:

$fileName = sprintf('thumb_%s.%s', 
                    $fileId,
                    $fileInfo['extension']);

Ответ 14

Обычно я использую sprintf для обеспечения того, что идентификатор, который поступает с пользовательского ввода, является целым числом, например:

// is better use prepared statements, but this is practical sometimes
$query = sprintf("SELECT * from articles where id = %d;",$_GET['article_id']);

Также используется для создания элементарных шаблонов (для html-писем или других вещей), поэтому вы можете повторно использовать шаблон во многих местах:

$mail_body = "Hello %s, ...";
$oneMail = sprintf($mail_body, "Victor");
$anotherMail = sprintf($mail_body, "Juan");

Очень полезно также форматировать числа в разных представлениях (восьмеричные, управлять десятичной точкой и т.д.).

Ответ 15

define('TEXT_MESSAGE', 'The variable "%s" is in the middle!');

sprintf(TEXT_MESSAGE, "Var1");
sprintf(TEXT_MESSAGE, "Var2");
sprintf(TEXT_MESSAGE, "Var3");

Ответ 16

sprintf особенно полезен при форматировании строк, которые используют числа. Например,

$oranges = -2.34;
echo sprintf("There are %d oranges in the basket", $oranges);

Output: There are -2 oranges in the basket

Апельсины отформатированы как целое число (-2), но будут округлены до положительных чисел, если вы используете% u для значений без знака. Чтобы избежать такого поведения, я использую абсолютную функцию abs() для округления числа до нуля следующим образом:

$oranges = -5.67;
echo sprintf("There are %d oranges in the basket", abs($oranges));

Output: There are 5 oranges in the basket

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

$oranges = -3.14;
$apples = 1.5;
echo sprintf("There are %d oranges and %d apples", abs($oranges), abs($apples));

Output: There are 3 oranges and 4 apples

Левая часть оператора sprintf четко выражает строку и типы ожидаемых значений, в то время как правая сторона четко выражает используемые переменные и как их манипулируют.

Ответ 17

Ну, sprintf имеет много возможностей, как мы знаем пример, как показано ниже:

Несколько месяцев назад мне понадобилось конвертировать секунды в час: минута: секунды Как $t = 494050 //seconds я хотел напечатать как 137 h 14 m 10 s, поэтому я придумал функцию php springf(), я просто удерживаю секунды в $t, а echo sprintf("%02d h %s%02d m %s%02d s", floor($t/3600), $f, ($t/60)%60, $f, $t%60); дает мне 137 h 14 m 10 s

Функция sprintf() очень полезна, если мы знаем, как ее использовать.

Ответ 18

Аргумент тот же, что и для использования шаблонов. Вы захотите отделить свой Textsleev от фактических значений переменных. Помимо дополнительных возможностей sprintf, о которых мы упоминали об этом, просто стиль.

Ответ 19

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

Ответ 20

Использование функции sprintf() над обычной конкатенацией имеет то преимущество, что вы можете применять различные типы форматирования для конкатенированных переменных.

В вашем случае у вас есть

$output = sprintf("Here is the result: %s for this date %s", $result, $date);

и

$output = 'Here is the result: ' .$result. ' for this date ' .$date;

Возьмем $result = 'passed'; date = '23rd';

Используя обычную конкатенацию, вы можете получить только результат:

Here is the result: passed for this date 23rd

Однако, если вы используете sprintf(), вы можете получить модифицированный результат, например:

$output = sprintf('Here is the result: %.4s for this date %.2s',$result,$date);
echo $output;

Вывод:

Here is the result: pass for this date 23

Ответ 21

sprintf() в достаточной степени похож на printf(). Если вы знаете printf() в деталях, тогда sprintf() и даже vsprintf() понять не сложно.

одно из sprintf() от printf() состоит в том, что вам нужно объявить переменную, чтобы перехватить выходные данные функции, поскольку она ничего не печатает и не выводит напрямую. Давайте посмотрим следующие фрагменты кода:

printf("Hello %s", "world"); // "Hello world"

sprintf("Hello %s", "world"); // does not display anything

echo sprintf("Hello %s", "world"); // "Hello world"

$a = sprintf("Hello %s", "world"); // does not display anything

echo $a;// "Hello world"

Надеюсь, это поможет.

Ответ 22

Один "выводит", другой "возвращает", вот одно из главных отличий.

Выходные данные printf()

sprintf() Возвращает

Ответ 23

Вы должны быть осторожны при использовании sprintf в циклах:

$a = 'Anton';
$b = 'Bert';
$c = 'Corni';
$d = 'Dora';
$e = 'Emiel';
$f = 'Falk';
$loops = 10000000;

$time = microtime(true);

for ($i = 0; $i < $loops; $i++)
{
    $test = $a . $b . $c . $d . $e . $f;
}

$concatTime = microtime(true) - $time;

$time = microtime(true);

for ($i = 0; $i < $loops; $i++)
{
    $test = "$a $b $c $d $e $f";
}

$concat2Time = microtime(true) - $time;

$time = microtime(true);

for ($i = 0; $i < $loops; $i++)
{
    $test = sprintf('%s %s %s %s %s %s', $a, $b, $c, $d, $e, $f);
}

$sprintfTime = microtime(true) - $time;

echo 'Loops: ' . $loops . '<br>';
echo '\'$a . $b . $c . $d . $e . $f\'' . ' needs ' . $concatTime  . 's<br>';
echo '"$a $b $c $d $e $f"' . ' needs ' . $concat2Time  . 's<br>';
echo 'sprintf(\'%s %s %s %s %s %s\', $a, $b, $c, $d, $e, $f)' . ' needs ' . $sprintfTime  . 's<br>';

Что приводит к следующему времени (на моей локальной машине с PHP 7.2):

Петли: 10000000

$ a. $ б. $ c. $ d. $ е. $ f 'нужно 1.4507689476013s

"$ a $ b $ c $ d $ e $ f" требует 1.9958319664001s

sprintf ('% s% s% s% s% s% s', $ a, $ b, $ c, $ d, $ e, $ f) необходимо 9.1771278381348s

Ответ 24

Я использую это для сообщений пользователям или других "симпатичных" типов функциональности. Например, если я знаю, что я собираюсь использовать имя пользователя.

$name = 'Some dynamic name';

И иметь несколько сообщений для использования в этой ситуации. (Т.е. блокирование или отслеживание другого пользователя)

$messageBlock = 'You have blocked %s from accessing you.';
$messageFollow = 'Following %s is a great idea!';

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

Подумайте об этом, что выглядит лучше?

return $messageOne === true ? $name.'. Please use the next example' : 'Hi '.$name.', how are you?'

или

$message = $messageOne === true ? 'Option one %s' 
: ($messageTwo === true ? 'Option Two %s maybe?' : '%s you can choose from tons of grammatical instances and not have to edit variable placement and strings');

return sprintf($message, $name);

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