有没有一个PHP函数只给双引号添加反斜杠而不是单引号?

38

我正在使用PHP生成JSON。

我一直在使用

$string = 'This string has "double quotes"';

echo addslashes($string);

输出:这个字符串有“双引号”

完全有效的JSON

不幸的是,addslashes也会对有效JSON造成灾难性的影响,因为它会转义单引号。

$string = "This string has 'single quotes'";

echo addslashes($string);

输出:这个字符串有 '单引号'

简而言之,有没有一种方法只转义双引号?


13
好的,以下是对http://php.net/manual/en/function.json-encode.php的翻译:json_encode 函数(PHP 5 >= 5.2.0, PHP 7, PECL json >= 1.2.0)json_encode — 对变量进行 JSON 编码说明string json_encode ( mixed $value , int $options = 0 , int $depth = 512 )json_encode() 函数返回 value 参数的 JSON 形式。参数value要编码成 JSON 字符串的值。该函数只接受 UTF-8 编码的数据。options由以下常量组成的二进制掩码:JSON_HEX_QUOT、JSON_HEX_TAG、JSON_HEX_AMP、JSON_HEX_APOS、JSON_NUMERIC_CHECK、JSON_PRETTY_PRINT、JSON_UNESCAPED_SLASHES、JSON_FORCE_OBJECT、JSON_PRESERVE_ZERO_FRACTION、JSON_UNESCAPED_UNICODE、JSON_PARTIAL_OUTPUT_ON_ERROR。默认为 0(不使用任何选项)。有关这些常量的详细信息,请参见 json_encode() 常量。depth设置递归深度。如果它大于 512,则将抛出一个异常。这是为了防止可能的递归无限循环。默认为 512。返回值返回 JSON 数据编码后的字符串,或者在失败时返回 FALSE。更新日志版本 说明 7.2.0 添加了 JSON_PARTIAL_OUTPUT_ON_ERROR 选项。 5.5.0 添加了 JSON_PRETTY_PRINT 选项。 5.3.3 添加了 JSON_UNESCAPED_UNICODE 选项。 5.3.0 添加了 options 参数。 5.2.0 添加了 json_encode()。 示例Example #1 简单的 json_encode() 示例<?php $arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5); echo json_encode($arr); ?> 以上例程会输出:{"a":1,"b":2,"c":3,"d":4,"e":5}Example #2 json_encode() 带选项参数的示例<?php $arr = array('quotes' => '"', 'willnot' => "won't", 'cant' => "can't", 'and' => '&'); echo json_encode($arr, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); ?> 以上例程会输出:{"quotes":"\u0022","willnot":"won\u0027t","cant":"can\u0027t","and":"\u0026"}Example #3 使用 JSON_PRETTY_PRINT 选项的示例<?php $arr = array('item1' => 'value1', 'item2' => 'value2', 'item3' => array('subitem1' => 'subvalue1', 'subitem2' => 'subvalue2', 'subitem3' => array('subsubitem1' => 'subsubvalue1', 'subsubitem2' => 'subsubvalue2'))); echo json_encode($arr, JSON_PRETTY_PRINT); ?> 以上例程会输出:{ "item1": "value1", "item2": "value2", "item3": { "subitem1": "subvalue1", "subitem2": "subvalue2", "subitem3": { "subsubitem1": "subsubvalue1", "subsubitem2": "subsubvalue2" } } } - igorw
4个回答

62

虽然如果您可以使用json_encode,应该优先使用它,但您也可以使用addcslashes仅将\添加到某些字符中,例如:

addcslashes($str, '"\\/')

你还可以使用基于正则表达式的替换方法:
function json_string_encode($str) {
    $callback = function($match) {
        if ($match[0] === '\\') {
            return $match[0];
        } else {
            $printable = array('"' => '"', '\\' => '\\', "\b" => 'b', "\f" => 'f', "\n" => 'n', "\r" => 'r', "\t" => 't');
            return isset($printable[$match[0]])
                   ? '\\'.$printable[$match[0]]
                   : '\\u'.strtoupper(current(unpack('H*', mb_convert_encoding($match[0], 'UCS-2BE', 'UTF-8'))));
        }
    };
    return '"' . preg_replace_callback('/\\.|[^\x{20}-\x{21}\x{23}-\x{5B}\x{5D}-\x{10FFFF}/u', $callback, $str) . '"';
}

21

有没有仅向双引号添加反斜杠而非单引号的PHP函数?

并没有像addslashes()这样仅向双引号添加反斜杠的函数。

但是,您可以使用addcslashes()来仅向特定字符(例如只有双引号)添加反斜杠:

addcslashes($string, '"');

这段代码完全按照描述的功能运行。如果你想要与stripcslashes()兼容,则需要将斜杠本身添加到字符列表中:

addcslashes($string, '"\\');

那应该能完成你一直在寻找的工作。我不知道它是否与json编码兼容。


5
如果您要生成JSON,为什么不直接使用json_encode()函数呢?

7
如果这个人不知道这个功能,但它解决了他的问题,那么这个问题就在讨论范围内。 - koen
@koen 没错。此外,他还问道:“简而言之,有没有一种方法只转义双引号?” - rzetterberg
谢谢。是的,不幸的是json_encode在这种情况下不适用。 - Tim
json_encode() 对某些字符组合,比如 "'" 会失败,导致解析错误。你可以在之前使用 addcslashes 来转义这样的序列。 - Robse

2
function json_string_encode( $str ) {
   $from = array('"');    // Array of values to replace
   $to = array('\\"');    // Array of values to replace with

   // Replace the string passed
   return str_replace( $from, $to, $str );
}

要使用此功能,您只需使用:
$text = json_string_encode($text);

感谢您发布答案!虽然代码片段可以回答问题,但添加一些额外的信息,如解释等,仍然很棒。 - j0k

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接