我正在尝试更多地了解PHP函数sprintf()但是php.net对我没有多大帮助,因为我仍然感到困惑,为什么要使用它?
看看我下面的例子.
为什么用这个:
$output = sprintf("Here is the result: %s for this date %s", $result, $date);
Run Code Online (Sandbox Code Playgroud)
如果这样做并且更容易编写IMO:
$output = 'Here is the result: ' .$result. ' for this date ' .$date;
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么吗?
Isa*_*avo 127
sprintf 具有原始printf的所有格式化功能,这意味着您可以做的不仅仅是在字符串中插入变量值.
例如,指定数字格式(十六进制,十进制,八进制),小数位数,填充等.谷歌的printf,你会发现很多例子.关于printf的维基百科文章应该可以帮助您入门.
mac*_*osh 76
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'
Run Code Online (Sandbox Code Playgroud)
基本上它允许在代码中进行一些分离.如果我在我的代码中的许多地方使用'Hello,My Name is%s',我可以在一个地方将其更改为'%s是我的名字',并且它可以自动更新到其他地方,而无需转到每个实例并四处移动级联.
Ken*_*nan 46
另一个用途sprintf是在本地化应用程序中作为参数,sprintf不必按照它们在格式字符串中出现的顺序.
例:
$color = 'blue';
$item = 'pen';
sprintf('I have a %s %s', $color, $item);
Run Code Online (Sandbox Code Playgroud)
但像法语这样的语言对单词的命令不同:
$color = 'bleu';
$item = 'stylo';
sprintf('J\'ai un %2$s %1$s', $color, $item);
Run Code Online (Sandbox Code Playgroud)
(是的,我的法语很糟糕:我在学校学过德语!)
实际上,您可以使用gettext来存储本地化的字符串,但您会明白这一点.
ras*_*spi 36
翻译更容易.
echo _('Here is the result: ') . $result . _(' for this date ') . $date;
Run Code Online (Sandbox Code Playgroud)
翻译(gettext)字符串现在是:
当翻译成其他语言时,它可能是不可能的,或者导致非常奇怪的句子.
现在,如果你有
echo sprintf(_("Here is the result: %s for this date %s"), $result, $date);
Run Code Online (Sandbox Code Playgroud)
翻译(gettext)字符串现在是:
这更有意义,而且翻译成其他语言要灵活得多
Xeo*_*oss 16
我找到的最好的理由是,它允许您将所有语言字符串放在您的语言文件中,如果人们可以翻译并根据需要进行排序 - 但您仍然知道无论字符串处于何种格式 - 您希望显示用户名.
例如,您的网站会在页面顶部显示"欢迎回[[用户]]".作为程序员,你不知道或不关心 UI人员将如何编写 - 你只知道用户名将在消息中的某处显示.
因此,您可以将消息嵌入到代码中,而不必担心该消息实际上是什么.
Lang文件(EN_US):
...
$lang['welcome_message'] = 'Welcome back %s';
...
Run Code Online (Sandbox Code Playgroud)
然后,您可以在实际的PHP代码中使用它来支持任何语言的任何类型的消息.
sprintf($lang['welcome_message'], $user->name())
Run Code Online (Sandbox Code Playgroud)
你为什么要用呢?
当使用(外部)源语言字符串时,它证明非常有用.如果在给定的多语言字符串中需要固定数量的变量,则只需要知道正确的顺序:
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."
Run Code Online (Sandbox Code Playgroud)
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."
Run Code Online (Sandbox Code Playgroud)
插入的变量甚至不必在多种语言的开头或结尾,只有它们的顺序很重要.
当然,您可以编写自己的函数来执行此替换,毫无疑问,即使性能稍有提高,但它只是快得多(假设您有一个类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));
Run Code Online (Sandbox Code Playgroud)
它还具有全部功能printf,因此也是用于格式化多种类型变量的单行程序,例如:
如上所述,它允许格式化输入数据.例如,强制使用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);
Run Code Online (Sandbox Code Playgroud)
这种方法当然有其他用途,例如将输出打印为HTML等.
编辑:出于安全原因,使用上述技术时,必须mysql_real_escape_string()先使用此方法清理所有输入变量,以防止MySQL插入攻击.如果您解析未经过处理的输入,您的站点和服务器将被黑客入侵.(当然,除了代码完全构造并保证安全的变量之外.)
使用sprintf()可以更加清晰,更安全地格式化字符串.
例如,当您处理输入变量时,它会通过提前指定预期格式(例如,您期望字符串[ %s]或数字[ %d])来防止意外惊喜.这可能有助于SQL注入的可能风险,但如果字符串包含引号则不会阻止.
它还有助于处理浮点数,您可以明确指定数字精度(例如%.2f),这使您无需使用转换函数.
其他优点是大多数主要的编程语言都有自己的实现sprintf(),所以一旦你熟悉它,它就会更容易使用,而不是学习一门新语言(比如如何连接字符串或转换浮点数).
总之,使用它是一种更好的做法,以便拥有更清晰,更易读的代码.
例如,请参阅以下真实示例:
$insert .= "('".$tr[0]."','".$tr[0]."','".$tr[0]."','".$tr[0]."'),";
Run Code Online (Sandbox Code Playgroud)
或者打印一些简单的例子'1','2','3','4':
print "foo: '" . $a . "','" . $b . "'; bar: '" . $c . "','" . $d . "'" . "\n";
Run Code Online (Sandbox Code Playgroud)
并使用格式化字符串打印:
printf("foo: '%d','%d'; bar: '%d','%d'\n", $a, $b, $c, $d);
Run Code Online (Sandbox Code Playgroud)
where printf()等于sprintf(),但它输出一个格式化的字符串而不是返回它(到变量).
哪个更具可读性?
| 归档时间: |
|
| 查看次数: |
71908 次 |
| 最近记录: |