Python与PHP高效传递JSON数组:从多字符串到结构化解析实践


Python与PHP高效传递JSON数组:从多字符串到结构化解析实践

本教程旨在解决python脚本向php返回多个json对象时,php端解析困难的问题。核心方案在于python脚本将所有独立的json数据聚合为一个列表,并统一序列化为单个json字符串输出。php接收该字符串后,通过两次`json_decode`操作,首先解析外部的json数组结构,然后遍历数组对每个内部的json字符串进行二次解析,最终实现数据的结构化访问。

在现代Web应用开发中,不同编程语言间的协作是常态,Python和PHP之间的交互尤为常见。当Python脚本需要处理复杂数据并以JSON格式传递给PHP时,如果处理不当,可能会遇到PHP无法正确解析数据的问题,特别是当Python尝试输出多个独立的JSON对象时。本教程将深入探讨这一问题,并提供一套健壮的解决方案。

理解问题根源

最初的问题在于Python脚本在循环中多次调用print(json.dumps(data))。这种做法会导致Python将每个JSON对象独立地打印到标准输出,最终PHP通过shell_exec接收到的将是一个由多个JSON字符串简单拼接而成的长字符串,例如:{"key": "SWAT-107", ...}{"key": "SWAT-98", ...}。

PHP的json_decode()函数设计用于解析一个完整的、格式正确的JSON字符串(可以是对象或数组)。当它遇到上述拼接字符串时,会认为这不是一个合法的JSON结构,从而无法正确解析。即使Python尝试将单个JSON字符串放入一个Python列表中,然后打印这个列表的字符串表示,PHP接收到的也只是一个包含单引号、方括号等字符的普通字符串,而不是一个可直接解析的JSON数组。

Python端解决方案:统一聚合与序列化

解决此问题的关键在于Python脚本需要将所有待传输的JSON数据聚合到一个标准Python数据结构中(例如列表),然后将整个数据结构一次性序列化为单个、合法的JSON字符串。

以下是优化后的Python脚本示例:

import json
# 假设 Jira 类和相关方法已定义并可正常工作
# from PyJira.Jira import Jira 

if __name__ == "__main__":
    # jira = Jira() # 实例化Jira类
    output_data_list = [] # 创建一个空列表,用于存储所有JSON对象

    # 模拟数据获取过程
    # fields = jira.get_fields()
    # jql_issues = jira.get_jql_search_issues(jql_search="project = SWAT AND resolution = Unresolved ORDER BY priority DESC, updated DESC")

    # 模拟Jira issue数据
    jql_issues = [
        type('obj', (object,), {'key': 'SWAT-107', 'fields': type('obj', (object,), {'assignee': type('obj', (object,), {'display_name': 'Unassigned'})})})(),
        type('obj', (object,), {'key': 'SWAT-98', 'fields': type('obj', (object,), {'assignee': type('obj', (object,), {'display_name': 'Unassigned'})})})(),
        type('obj', (object,), {'key': 'SWAT-100', 'fields': type('obj', (object,), {'assignee': type('obj', (object,), {'display_name': 'Unassigned'})})})(),
    ]

    for issue in jql_issues:
        data_item = {} # 为每个issue创建一个新的字典
        data_item['key'] = issue.key
        # 假设 assignee 字段存在且有 display_name 属性
        data_item['assignee'] = issue.fields.assignee.display_name if hasattr(issue.fields.assignee, 'display_name') else 'N/A'
        output_data_list.append(data_item) # 将字典添加到列表中

    # 将整个列表序列化为一个JSON字符串并打印
    print(json.dumps(output_data_list))
    # exit() # 在脚本末尾通常不需要显式调用 exit()

关键改进点:

CodeGeeX CodeGeeX

智谱AI发布的AI编程辅助工具插件,可以实现自动代码生成、代码翻译、自动编写注释以及智能问答等功能

CodeGeeX 191 查看详情 CodeGeeX
  1. 数据聚合: 创建一个名为 output_data_list 的空列表。在循环中,不再直接打印每个JSON对象,而是将每个处理好的字典 (data_item) 添加到这个列表中。
  2. 一次性序列化: 循环结束后,使用 print(json.dumps(output_data_list)) 将整个列表序列化为一个单一的JSON字符串。这个字符串将是一个合法的JSON数组,其结构类似于 [{"key": "SWAT-107", ...}, {"key": "SWAT-98", ...}]。

PHP端解决方案:分步解析JSON数据

PHP接收到Python脚本输出的单一JSON字符串后,需要进行两步解析操作:

  1. 第一次解析: 使用 json_decode() 解析外部的JSON数组字符串,将其转换为PHP数组。
  2. 第二次解析: 遍历这个PHP数组,对每个元素(这些元素本身是JSON字符串)再次使用 json_decode() 进行解析,并指定 true 参数以确保将JSON对象转换为PHP关联数组,而非标准对象。

以下是优化后的PHP脚本示例:

<?php

// 执行Python脚本并捕获其标准输出
// 注意:实际路径和命令可能需要根据您的环境进行调整
$python_script_command = "cd .. && cd python/pyjira && pipenv run python PyJira/Jira.py";
$output_json_string = shell_exec($python_script_command);

// 调试输出,查看原始JSON字符串
// var_dump($output_json_string);

// 第一次解码:将外部的JSON数组字符串解码为PHP数组
// 此时 $decoded_output 会是一个包含多个字符串的PHP数组,每个字符串都是一个JSON对象
$decoded_output = json_decode($output_json_string);

// 检查解码是否成功
if (json_last_error() !== JSON_ERROR_NONE) {
    echo "Error decoding main JSON string: " . json_last_error_msg() . "<br>";
    exit;
}

// 遍历PHP数组,对每个内部的JSON字符串进行二次解码
if (is_array($decoded_output)) {
    foreach ($decoded_output as $json_item_string) {
        // 第二次解码:将内部的JSON对象字符串解码为PHP关联数组
        // 传入 true 参数,确保转换为关联数组而非对象
        $jira_data = json_decode($json_item_string, true);

        // 检查二次解码是否成功
        if (json_last_error() !== JSON_ERROR_NONE) {
            echo "Error decoding inner JSON item: " . json_last_error_msg() . " - String: " . htmlspecialchars($json_item_string) . "<br>";
            continue; // 跳过当前错误项,继续处理下一个
        }

        // 成功解析后,即可通过键名访问数据
        if (is_array($jira_data) && isset($jira_data['key']) && isset($jira_data['assignee'])) {
            echo "Key: " . $jira_data['key'] . " - Assignee: " . $jira_data['assignee'] . "<br>";
        } else {
            echo "Invalid data structure for item: " . htmlspecialchars($json_item_string) . "<br>";
        }
    }
} else {
    echo "Expected an array from Python script, but received: " . htmlspecialchars($output_json_string) . "<br>";
}

?>

关键改进点:

  1. 第一次解码: json_decode($output_json_string) 将Python输出的 [{"key": "...", ...}, {"key": "...", ...}] 这样的字符串解析为一个PHP数组。这个PHP数组的每个元素仍然是一个JSON字符串,例如 {"key": "SWAT-107", "assignee": "Unassigned"}。
  2. 循环与第二次解码: 使用 foreach 循环遍历 $decoded_output 数组。在循环内部,对每个元素(即单个JSON字符串)再次调用 json_decode($json_item_string, true)。这里的 true 参数至关重要,它指示PHP将JSON对象解码为关联数组,而不是PHP标准对象,这样就可以通过 $jira_data['key'] 这样的方式方便地访问数据。

注意事项与最佳实践

  • 错误处理: 在PHP端,务必使用 json_last_error() 和 json_last_error_msg() 来检查 json_decode() 是否成功,这对于调试和生产环境中的健壮性至关重要。
  • 安全性: shell_exec() 函数允许执行系统命令,存在安全风险。如果Python脚本的输入来源于用户,请务必对输入进行严格的过滤和验证,以防止命令注入攻击。对于更复杂的交互或敏感操作,考虑使用更安全的IPC(进程间通信)机制,如消息队列、HTTP API或gRPC。
  • 性能: 对于大量数据,频繁的 json_decode() 操作可能会有性能开销。如果数据量非常大,可以考虑Python直接输出一个更紧凑的格式,或者在Python端进行更多的预处理。
  • 环境一致性: 确保PHP执行Python脚本的环境(如Python版本、pipenv环境)与开发环境一致,避免因路径、依赖问题导致脚本执行失败。
  • 编码: 确保Python和PHP在处理JSON时都使用UTF-8编码,以避免字符乱码问题。

总结

通过在Python端将所有数据聚合到一个列表中并进行一次性JSON序列化,以及在PHP端进行两次分步的 json_decode 操作,我们可以有效地解决Python向PHP传递多个JSON对象时的解析难题。这种方法确保了数据传输的结构化和可解析性,是跨语言数据交互的常用且推荐的实践。遵循本教程的指导,开发者可以构建更健壮、更易维护的Python-PHP集成应用。

以上就是Python与PHP高效传递JSON数组:从多字符串到结构化解析实践的详细内容,更多请关注php中文网其它相关文章!


# python  # 创建一个  # 结构化  # 数据结构  # 遍历  # 转换为  # 多字  # 是一个  # 多个  # j  # 字符串解析  # 应用开发  # nas  # ai  # 编程语言  # app  # 编码  # json  # js  # html  # php  # 开发环境  # 怀柔短视频seo  # 酒店网站建设开发费用  # 苏州昆山seo公司  # 旅游营销无需求产品推广  # 承德京东网站推广介绍  # 烟台电脑网站优化招聘  # 如何系统地做seo  # 龙泉网站建设开发  # 大兴网站建设和推广  # 电销团队网站推广方案设计  # 列表中 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 学习通网页版个人登录_学习通网页版个人账户登录入口  如何使用 composer 和 aop-php 实现 AOP 编程?  j*a中ArrayBlockingQueue的使用  《一起考教师》账号注销方法  4399造梦西游3无敌版_4399游戏入口  mysql如何配置从库只读_mysql从库只读设置方法  Flexbox布局中Stencil组件宽度不显示问题解析与:host尺寸控制  如何使用CSS Grid实现“大方块左侧,小方块右侧垂直堆叠”的水平布局  Win10运行窗口在哪里打开 Win10调出运行命令框快捷键【技巧】  使用Google服务账号实现Google Drive API无缝集成与文件访问  J*a实现任务清单管理_集合框架综合入门练手  MacBook Pro词典使用指南  菜鸟驿站的取件码忘了怎么办 手机快速查询指南  vivo手机视频通话美颜怎么设置_vivo视频通话美颜开启方法  C++怎么解决数值计算中的精度问题_C++浮点数误差与数值稳定性分析  解决J*aScript动态图片上传中ID重复问题:在同一页面显示多张独立图片  如何在Python中安全地将环境变量转换为整数并满足Mypy类型检查  mysql怎么查询数据_mysql基础查询语句使用教程  word文档中的分隔符有哪些不同类型和用途_Word分隔符类型与用途方法  C++如何使用CMake构建项目_C++ CMakeLists.txt编写入门教程  花生壳内网映射新方案  CSS绝对定位与溢出控制:实现背景元素局部显示不触发滚动条  C++ priority_queue怎么用_C++优先队列底层实现与自定义比较器  荣耀盒子应用管理技巧  tiktok国际版入口_tiktok官网网页版链接  4399正版网页版入口高清直达链接  外卖小程序对接第三方配送  智慧团建活动报名入口 智慧团建活动报名入口手机端官网​  极兔快递官网查询入口手机版 手机极兔快递登录查询入口官方  优化CSS动画与J*aScript定时器协同:构建稳定Toast提示  React应用中Commerce.js数据加载与状态管理最佳实践  抖音视频如何添加标题?添加标题有哪些好处?  QQ邮箱官方登录页_腾讯出品安全稳定的邮箱服务  在Django单元测试中优雅处理信号:基于环境的条件执行策略  微信如何设置字体大小_微信字体设置的阅读舒适  composer licenses 命令:如何检查项目依赖的许可证?  TikTok网页版实时观看入口 TikTok网页版短视频在线浏览  圆通快递官网入口查询单号 手机版官方查询入口  Lar*el 中高效执行多列更新:单次查询实现  《糖豆》添加舞曲方法  《知到》打卡课程方法  京东快递物流信息不更新怎么办_物流停滞原因与处理方法  《万兴喵影》导出视频方法  sublime text 4如何安装_最新版sublime下载与汉化教程  汽水音乐官方网站登录入口_汽水音乐网页版进入链接  苹果手机如何清理系统缓存数据 iPhone非越狱清理垃圾文件的技巧【系统优化】  Yandex浏览器官方入口_Yandex搜索引擎中文版  如何配置VS Code作为您Git操作的默认编辑器  windows10怎么关闭自动安装应用_windows10禁止推广应用下载  mysql如何限制远程访问_mysql远程访问限制方法 

 2025-12-12

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.