【问题标题】:How to convert Perl generated string(Object) into JSON using PHP?如何使用 PHP 将 Perl 生成的字符串(对象)转换为 JSON?
【发布时间】:2017-11-30 15:08:35
【问题描述】:

我使用 Laravel (Lumen) 创建了一个 REST API。基本上我从数据库中获取一些值并且需要做一些功能。这就是问题所在。 我的结果集中有一个名为 web_data 的字段。这是 Perl 代码。这就是我使用普通 SQL 编辑器(如 phpmyadmin 和 workbench)查询数据库时的样子。

{"caption" => "Genes (Comprehensive set from GENCODE 26)","colour_key" => "[biotype]","default" => {"MultiBottom" => "collapsed_label","MultiTop" => "gene_label","alignsliceviewbottom" => "as_collapsed_label","contigviewbottom" => "transcript_label","contigviewtop" => "gene_label","cytoview" => "gene_label"},"key" => "ensembl","label_key" => "[biotype]","multi_name" => "GENCODE 26 Comprehensive gene set","name" => "Comprehensive Gene Annotations from GENCODE 26"}

非常清楚,没有错。但是当我通过我的 REST API 得到相同的结果时,我得到了以下输出。它有许多“\”符号。这是输出。

{\"caption\" => \"Genes (Comprehensive set from GENCODE 26)\",\"colour_key\" => \"[biotype]\",\"default\" => {\"MultiBottom\" => \"collapsed_label\",\"MultiTop\" => \"gene_label\",\"alignsliceviewbottom\" => \"as_collapsed_label\",\"contigviewbottom\" => \"transcript_label\",\"contigviewtop\" => \"gene_label\",\"cytoview\" => \"gene_label\"},\"key\" => \"ensembl\",\"label_key\" => \"[biotype]\",\"multi_name\" => \"GENCODE 26 Comprehensive gene set\",\"name\" => \"Comprehensive Gene Annotations from GENCODE 26\"}

你能告诉我这是什么原因吗?这是 PHP 的问题还是类似的问题?

我还有另一个问题。这是包含“=>”符号来分隔值的 Perl 代码。我需要使用 PHP 将其转换为 JSON 对象。那可能吗 ? 需要像下面的对象一样转换。

{ "caption" : "Genes (Comprehensive set from GENCODE 26)", "colour_key" : "[biotype]", "default" : { "MultiBottom" : "collapsed_label" ...

这是我用来使用 SQL 数据创建 REST 输出的 php 代码。

public function testDualDatabaseConnection()
{
    $testGene = DB::connection('mysql2')->select('select a.analysis_id, logic_name, ad.description, ad.display_label, ad.web_data FROM ( select distinct(analysis_id) as analysis_id from gene ) as a join analysis on (a.analysis_id = analysis.analysis_id) join analysis_description as ad on (analysis.analysis_id = ad.analysis_id) where ad.displayable =  :wow1', ['wow1' => "1"]);
    return response()->json($testGene);
}

这也是我通过 REST API 获得的完整 JSON 输出。 https://gist.github.com/chanakaDe/0d1e5916d8bc788bb101afa9b92dc9cd

在此响应中,您可以看到“web_data”,这也是我需要再次转换为 JSON 的部分。

【问题讨论】:

  • 我们需要更多信息。我们需要查看生成 JSON 的代码。我们需要知道您是如何查看 REST API 结果的。
  • @ChanakaDeSilva — 编辑您的问题并使用提供的格式化功能。将大量代码发布到评论中会留下难以阅读的混乱。
  • @DaveCross 请检查。我编辑了问题。
  • 您要求将 Perl code 转换为 JSON!

标签: php mysql json perl


【解决方案1】:

如果你真的有机会

{\"caption\" => \"Genes ...\", ...}

然后你有一个 JSON 片段,你需要做的第一件事就是把它变成一个完整的 JSON 文档,以便它可以被解码。

$json_fragment_from_api = '{\"caption\" => \"Genes ...\", ...}';
$json_from_api = '{"result":"' . $json_fragment_from_api . '"}';
$response = json_decode($json_from_api, true);
$perl_code = $response["result"];

也就是说,我认为您更有可能只展示了实际输入的一部分。你更有可能收到看起来更像的东西

{ "result": "{\"caption\" => \"Genes ...\", ...}" }

既然您已经有了一个完整的 JSON 文档,只需从解码它开始。

$json_from_api = '{ "result": "{\"caption\" => \"Genes ...\", ...}" }';
$response = json_decode($json_from_api, true);
$perl_code = $response["result"];

此时,您已获得数据库中的值。

{"caption" => "Genes ...", ...}

该值是 Perl 代码。更具体地说,它肯定是由 Data::Dumper 生成的 Perl 代码。这将很难转换为 JSON。

您可以使用以下内容,但它不会处理所有问题:

$desired_json = str_replace(' =>', ':', $perl_code);

以下是它无法处理的一些事情:

  • 未定义的值
  • 包含=> 的字符串
  • 包含$ 的字符串
  • 包含@ 的字符串
  • 包含非 ASCII 或某些不可打印字符的字符串。

如下图:

$ perl -e'
   use feature qw( say );
   use Data::Dumper qw( Dumper );
   local $Data::Dumper::Useqq = 1;
   local $Data::Dumper::Terse = 1;
   local $Data::Dumper::Indent = 0;
   say(Dumper({ x => undef }));
   say(Dumper({ x => " => " }));
   say(Dumper({ x => q{$} }));
   say(Dumper({ x => q{@} }));
   say(Dumper({ x => "\x7F" }));
'
{"x" => undef}      # Gives {"x": undef}  instead of {"x": null}
{"x" => " => "}     # Gives {"x": ": "}   instead of {"x": " => "}
{"x" => "\$"}       # Gives {"x": "\$"}   instead of {"x": "$"}
{"x" => "\@"}       # Gives {"x": "\@"}   instead of {"x": "@"}
{"x" => "\177"}     # Gives {"x": "\177"} instead of {"x": "\u007f"}

【讨论】:

  • 您可能希望将 str_replace 放在 json_decode 之前。如果其中有“=>”,它将无法解码该字符串。更准确地说,json_last_error_msg() 将返回“语法错误”。哪一点让你留下我写的东西......
  • @Alex Tartan,不,那是错误的。 OP 以 JSON 字符串开头。字符串包含=> 的事实无关紧要。 "{\"caption\" => \"Genes ...\", ...}" 将正确解码。
  • 请看3v4l.org/WiDli 这是一个执行php代码的在线平台。我制作了一个 sn-p 来证明这一点。不要误会我的意思,我的代码不是通用转换器。它只是应该与提供的数据类型一起工作。要制作一个合适的转换器,是的,需要考虑更多的情况。
  • Re "Re "notice i didn't change $db_string!", 实际上,你做到了。如果你这样做echo $db_string,你会发现它和之前的不一样已发布 OP。这是proper test。如您所见,两种解决方案都为所提供的输入提供了正确的输出。但是,对于许多其他有效输入,您的解决方案将失败!
【解决方案2】:

不确定转义发生在哪里(如果可以,请提供更多详细信息)

但是,尝试将=> 替换为:,将\" 替换为",您将拥有一个有效的json。

$string = '{\"caption\" => \"Genes (Comprehensive set from GENCODE 26)\",\"colour_key\" => \"[biotype]\",\"default\" => {\"MultiBottom\" => \"collapsed_label\",\"MultiTop\" => \"gene_label\",\"alignsliceviewbottom\" => \"as_collapsed_label\",\"contigviewbottom\" => \"transcript_label\",\"contigviewtop\" => \"gene_label\",\"cytoview\" => \"gene_label\"},\"key\" => \"ensembl\",\"label_key\" => \"[biotype]\",\"multi_name\" => \"GENCODE 26 Comprehensive gene set\",\"name\" => \"Comprehensive Gene Annotations from GENCODE 26\"}';

$string = str_replace('\"','"', $string);
$string = str_replace('=>',':', $string);
$json = json_decode($string, true);
print_r($json);

您可以在这里查看:https://3v4l.org/UBmGA


显然,这个答案比我预期的更讨厌。尽管如此,它确实对 OP 有所帮助,我坚持下去。最后,这就是 SO 的含义。

我想知道...为什么这么多反对票?我确实能很好地接受建设性的批评,并且想知道如何改进未来的答案。

【讨论】:

  • 您还需要删除列表末尾的逗号。在 Perl 中是允许的,在 json 中是不允许的。
  • @simbabque,提供的数据结构 OP 没有列表。但如果是这样,一个简单的$string = str_replace(',]',']', $string); 就可以完成这项工作。不,我不会正则表达式一个 json 字符串;)。我通常不会把问题复杂化
  • @simbabque,Perl 代码肯定是由 Data::Dumper 生成的,它不会创建这些逗号。然而,还有大量其他问题。
  • @AlexTartan 这不是一个列表,它是一个数组引用。 Perl 中用逗号分隔的任何内容都是一个列表。其中一些恰好是数组或哈希引用。您可以在任何地方放置尾随逗号。他们创建空元素,而那些只是被删除。 Ikegami 是对的,它可能是 Data::Dumper 输出。我认为有一个标志可以打开它们。
猜你喜欢
  • 2012-07-29
  • 2012-08-28
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多