如何允许带有esc_html__()的单引号,而不使用Sprintf()

时间:2020-01-19 作者:Rens Tillmann

出于安全原因,我们当然需要使用esc_html__() 用于WP开发。这很烦人,因为如果要在字符串中传递一个引号,就必须使用sprintf() 让它发挥作用。否则你就会' 打印出来,而不是\'.

不使用sprintf():

esc_html__( \'Wasn\\\'t your favorite color red?\', \'domain\' );
// Output: Wasn't your favorite color red?
esc_html__( \'Provided reason isn\\\'t selected\', \'domain\' );
// Output: Provided reason isn't selected
使用sprintf() 我可以使用单引号(当然)。

sprintf( esc_html__( \'Wasn%st your favorite color red?\', \'domain\' ), \'\\\'\' );
// Output: Wasn\'t your favorite color red?
sprintf( esc_html__( \'Provided reason isn%st selected\', \'domain\' ), \'\\\'\' );
// Output: Provided reason isn\'t selected
我想知道是否有不同的方法来实现相同的输出。恐怕没有,但我想为什么不试一试,谁知道呢。

1 个回复
最合适的回答,由SO网友:Tim Elsass 整理而成

嗯,你说的是另一种输出方式吗?

<?php if ( \'en_US\' === get_locale() ) : ?>
    Wasn\'t your favorite color red?
<?php endif; ?>
:大笑:

但说真的,我的意思是,如果你想做什么,什么都可以做。如果你看esc_html__ - 你会发现它只是在打电话esc_html, 在确定安全文本后可过滤_wp_specialchars. 正在查看_wp_specialchars 您可以看到,它只是在编码实体的单引号上进行字符串替换。如果要撤消它所做的操作,只需执行反向逻辑,将实体替换为单个引号。这样做可以实现您的目标:

add_filter( \'esc_html\', function( $safe_text ) {
    return str_replace( \'&#039;\', "\'", $safe_text );
}, PHP_INT_MAX );
真正的问题是should you do it? 有些人经常提到\'" 作为愚蠢的引语。理想情况下,这些应该在代码中使用,而 有时被称为智能引号、花式引号或排版引号。这些通常被认为是可显示的引号,或属于您的内容的引号。它们是为了看起来更漂亮,更准确地显示您要向用户/访问者显示的引用文本的开头和结尾。一般来说,如果你要显示文本供他人阅读,通常最好使用智能引号,这就是为什么_wp_special_chars 进行转换。这也是在wptexturize 在WordPress中过滤显示的内容,如内容、评论、导航菜单标题、链接名称、术语描述、博客信息值和widget\\u标题,只需说出几个地方。

显然,在HTML输出中使用哑引号并不会带来巨大的风险,但在某些情况下,如果某些内容写得不好/被忽视,可能会导致问题。通过过滤该值,您需要比我提供的代码片段更负责任,并采取措施确保只过滤通过插件/主题代码添加的值,以确保不会导致其他人的代码出现开放向量。理想情况下,在篡改之前,您应该检查被过滤的文本是否属于您的textdomain。这也是为什么在这里更改过滤值不是一个好主意的另一个原因,因为使用此过滤器是非常罕见的,插件和主题有代码通过它运行也是非常常见的。

那么你应该这样做吗?No, 但是,如果你对这种行为有绝对必要的需求,那么一定有办法做到这一点,即使你的例子也展示了一种令人烦恼的解决方法。我甚至看到人们在加载页面时通过JS将其转换回来,这似乎有点过激。然而,在现代,它并没有在安全方面做得那么多,而是在为人们阅读内容提供的显示价值方面做得更多。只是别傻了,想想在用户输入表单中允许它,或者使用相同的技术esc_attr 不过这是个好主意。