为什么在 PHP 中使用 sprintf 函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1386593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why use sprintf function in PHP?
提问by JasonDavis
I am trying to learn more about the PHP function sprintf() but php.net did not help me much as I am still confused, why would you want to use it?
我正在尝试了解有关 PHP 函数 sprintf() 的更多信息,但 php.net 对我没有多大帮助,因为我仍然感到困惑,为什么要使用它?
Take a look at my example below.
看看我下面的例子。
Why use this:
为什么使用这个:
$output = sprintf("Here is the result: %s for this date %s", $result, $date);
When this does the same and is easier to write IMO:
当这样做相同并且更容易编写 IMO 时:
$output = 'Here is the result: ' .$result. ' for this date ' .$date;
Am I missing something here?
我在这里错过了什么吗?
采纳答案by Isak Savo
sprintfhas all the formatting capabilities of the original printf which means you can do much more than just inserting variable values in strings.
sprintf具有原始 printf 的所有格式化功能,这意味着您可以做的不仅仅是在字符串中插入变量值。
For instance, specify number format (hex, decimal, octal), number of decimals, padding and more. Google for printf and you'll find plenty of examples. The wikipedia article on printfshould get you started.
例如,指定数字格式(十六进制、十进制、八进制)、小数位数、填充等。谷歌搜索 printf,你会发现很多例子。关于 printf的维基百科文章应该可以帮助您入门。
回答by macinjosh
There are many use cases for sprintf but one way that I use them is by storing a string like this: 'Hello, My Name is %s' in a database or as a constant in a PHP class. That way when I want to use that string I can simply do this:
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'
Essentially it allows some separation in the code. If I use 'Hello, My Name is %s' in many places in my code I can change it to '%s is my name' in one place and it updates everywhere else automagically, without having to go to each instance and move around concatenations.
本质上,它允许在代码中进行一些分离。如果我在代码中的许多地方使用“你好,我的名字是 %s”,我可以在一个地方将其更改为“%s 是我的名字”,并且它会自动更新其他所有地方,而无需去每个实例并四处走动串联。
回答by Ken Keenan
Another use of sprintfis in localized applications as the arguments to sprintfdon't have to be in the order they appear in the format string.
的另一个用途sprintf是在本地化应用程序中,因为参数sprintf不必按照它们在格式字符串中出现的顺序排列。
Example:
例子:
$color = 'blue';
$item = 'pen';
sprintf('I have a %s %s', $color, $item);
But a language like French orders the words differently:
但是像法语这样的语言对单词的排序不同:
$color = 'bleu';
$item = 'stylo';
sprintf('J\'ai un %2$s %1$s', $color, $item);
(Yes, my French sucks: I learned German in school!)
(是的,我的法语很烂:我在学校学了德语!)
In reality, you'd use gettextto store the localized strings but you get the idea.
实际上,您会使用gettext来存储本地化的字符串,但您明白了。
回答by raspi
It's easier to translate.
翻译起来更容易。
echo _('Here is the result: ') . $result . _(' for this date ') . $date;
Translation (gettext) strings are now:
翻译 (gettext) 字符串现在是:
- Here is the result:
- for this date
- 结果如下:
- 对于这个日期
When translated to some other language it might be impossible or it results to very weird sentences.
当翻译成其他语言时,这可能是不可能的,或者会导致非常奇怪的句子。
Now if you have
现在如果你有
echo sprintf(_("Here is the result: %s for this date %s"), $result, $date);
Translation (gettext) strings is now:
翻译 (gettext) 字符串现在是:
- Here is the result: %s for this date %s
- 结果如下:该日期 %s %s
Which makes much more sense and it's far more flexible to translate to other languages
这更有意义,翻译成其他语言也更灵活
回答by Xeoncross
The best reason that I have found is that it allows you to place all the language strings in your language file were people can translate and order them as needed - yet you still know that no matter what format the string is in - you wish to show the users name.
我发现的最好的原因是它允许您将所有语言字符串放在您的语言文件中,人们可以根据需要翻译和订购它们 - 但您仍然知道无论字符串采用什么格式 - 您希望显示用户名。
For example, your site will say "Welcome back [[User]]" on the top of the page. As the programmer you don't know or carehow the UI guys are going to write that - you just know that a users name is going to be shown somewhere in a message.
例如,您的站点会在页面顶部显示“欢迎回来 [[用户]]”。作为程序员,您不知道也不关心UI 人员将如何编写它 - 您只知道用户名将显示在消息的某个地方。
So you do can embed the message into your code without worring about what that message actually is.
因此,您可以将消息嵌入到您的代码中,而不必担心该消息实际上是什么。
Lang file (EN_US):
语言文件(EN_US):
...
$lang['welcome_message'] = 'Welcome back %s';
...
Then you can support any type of message in any language by using this in your actual php code.
然后,您可以通过在实际的 php 代码中使用它来支持任何语言的任何类型的消息。
sprintf($lang['welcome_message'], $user->name())
回答by John Weisz
why would you want to use it?
你为什么要使用它?
It proves very useful when using an (external) source for language strings. If you need a fixed number of variables in a given multilingual string, you only need to know the correct ordering:
当使用语言字符串的(外部)源时,它被证明非常有用。如果在给定的多语言字符串中需要固定数量的变量,则只需要知道正确的顺序:
en.txt
.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
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."
The inserted variables don't even have to be at the beginning or the end across multiple languages, only their ordering matters.
插入的变量甚至不必在多种语言的开头或结尾,只有它们的顺序很重要。
Of course, you could write your own function to perform this replace, undoubtedly even with some minor performance increases, but it is much faster to just (given you have a class Languageto read language strings):
当然,您可以编写自己的函数来执行此替换,毫无疑问,即使性能略有提高,但仅(假设您有一个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));
It also comes with the full capabilities of printf, thus is also a one-liner for formatting numerous types of variables, for example:
它还具有 的全部功能printf,因此也是格式化多种类型变量的单行程序,例如:
- floating point number output precision, or
- filling integers with leading zeros.
回答by Samuel Jaeschke
As mentioned, it allows formatting of the input data. For example, forcing 2dp, 4-digit numbers, etc. It's quite useful for building MySQL query strings.
如前所述,它允许格式化输入数据。例如,强制2dp,4位数字等。对于构建MySQL查询字符串非常有用。
Another advantage is that it allows you to separate the layout of the string from the data being fed into it, almost like feeding in paramaters. For example, in the case of a MySQL query:
另一个优点是它允许您将字符串的布局与输入的数据分开,就像输入参数一样。例如,在 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);
This method does of course have other uses, such as when printing output as HTML, etc.
这种方法当然还有其他用途,例如将输出打印为 HTML 等。
Edit: For security reasons, when using a technique as above you must sanitise all input variables with mysql_real_escape_string()before using this method, to prevent MySQL insertion attacks. If you parse unsanitised input, your site and server will get hacked. (With exception to, of course, variables which have been completely constructed by your code and are guaranteed to be safe.)
编辑:出于安全原因,使用上述技术时,您必须mysql_real_escape_string()在使用此方法之前清理所有输入变量,以防止 MySQL 插入攻击。如果您解析未经处理的输入,您的站点和服务器将被黑。(当然,完全由您的代码构建并保证安全的变量除外。)
回答by kenorb
Using sprintf()is much cleaner and safer to format your string.
使用sprintf()格式化字符串更干净、更安全。
For example when you're dealing with input variables, it prevents unexpected surprises by specifying the expected format in advance (for instance, that you're expecting string [%s] or the number [%d]). This could potentially helps with possible risk of SQL injection, but it won't prevent if string consist quotes.
例如,当您处理输入变量时,它会通过预先指定预期格式(例如,您需要字符串 [ %s] 或数字 [ %d])来防止出现意外情况。这可能有助于解决SQL 注入的可能风险,但如果字符串包含引号,则不会阻止。
It also helps dealing with floats, you can explicitly specify the digit precision (e.g. %.2f) which saves you from using converting functions.
它还有助于处理浮点数,您可以明确指定数字精度(例如%.2f),从而避免使用转换函数。
The other advantages is that most of the major programming languages have their own implementation of sprintf(), so once you get familiar with it, it's even more easier to use, rather than learning a new language (like how to concatenate strings or converting the floats).
另一个优点是大多数主要的编程语言都有自己的 实现sprintf(),所以一旦你熟悉它,它就更容易使用,而不是学习一门新语言(比如如何连接字符串或转换浮点数)。
In summary, it's a good practise to use in order to have a cleaner and more readable code.
总而言之,为了获得更清晰、更易读的代码,使用它是一种很好的做法。
For instance, see the below real example:
例如,请参阅下面的真实示例:
$insert .= "('".$tr[0]."','".$tr[0]."','".$tr[0]."','".$tr[0]."'),";
Or some simple example which prints e.g. '1','2','3','4':
或一些打印的简单示例,例如'1','2','3','4':
print "foo: '" . $a . "','" . $b . "'; bar: '" . $c . "','" . $d . "'" . "\n";
and printing with formatted string:
并使用格式化字符串打印:
printf("foo: '%d','%d'; bar: '%d','%d'\n", $a, $b, $c, $d);
where printf()is equivalent to sprintf(), but it outputs a formatted string instead of returning it (to the variable).
whereprintf()等价于sprintf(),但它输出一个格式化的字符串而不是返回它(到变量)。
Which is more readable?
哪个更易读?
回答by swordfish
Even i though the same thing unless i used it recently. When you generate documents based on user inputs this will be in handy.
即使我也是同样的东西,除非我最近使用过它。当您根据用户输入生成文档时,这会很方便。
"<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.";
WHich can be easily written as
可以很容易地写成
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);
回答by Thomas Tremain
This:
这个:
"<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.";
Could also be written:
也可以写成:
"<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.";
In my opinion this is clearer to read, but I can see the use for localizing, or formatting.
在我看来,这更易于阅读,但我可以看到用于本地化或格式化的用途。

