You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PHP读取QIF文件数据生成数组并存入数据库?

用PHP解析QIF文件并生成数据库可用数组

我之前做过QIF文件导入数据库的需求,刚好能给你一些实用的指导。QIF文件是按特定标记分段的,咱们先理清它的结构,再一步步实现解析,生成你需要的数组格式。

先搞懂QIF的基本结构

QIF文件的内容由标记段组成:

  • 账户信息段以 !Account 开头,后续行是账户属性(比如N=账户名称,L=账户类型,D=描述,M=备注)
  • 交易记录段以 !Type:xxx 开头(比如!Type:Bank对应银行账户交易),每条交易的字段用特定标记开头,最后以 ^ 结束一条交易

常见的交易字段标记:

  • D:交易日期(格式通常是MM/DD/YYYY)
  • T:交易金额(正数为存入,负数为支出)
  • P:交易描述
  • N:交易序列号/支票号
  • C:交易状态/类型(比如Deposit表示存款)

实现解析代码

下面是一个实用的PHP解析函数,能把QIF文件解析成你需要的账户数组和交易数组:

function parseQIF($filePath) {
    // 读取文件内容并处理换行符
    $content = file_get_contents($filePath);
    $lines = preg_split('/\r\n|\r|\n/', trim($content));
    
    $account = [];
    $transactions = [];
    $currentTransaction = [];
    $inAccountSection = false;
    $inTransactionSection = false;

    foreach ($lines as $line) {
        $line = trim($line);
        if (empty($line)) continue;

        // 处理账户段
        if ($line === '!Account') {
            $inAccountSection = true;
            $inTransactionSection = false;
            continue;
        }

        // 处理交易类型段
        if (str_starts_with($line, '!Type:')) {
            $inAccountSection = false;
            $inTransactionSection = true;
            continue;
        }

        // 处理账户字段
        if ($inAccountSection) {
            $tag = substr($line, 0, 1);
            $value = substr($line, 1);
            switch ($tag) {
                case 'L': // 账户类型(比如ASSETS)
                    $account['type'] = $value;
                    break;
                case 'N': // 账户名称
                    $account['full_name'] = $value;
                    $account['name'] = $value; // 按你的示例统一名称字段
                    break;
                case 'D': // 账户描述
                    $account['description'] = $value;
                    break;
                case 'M': // 账户备注
                    $account['notes'] = $value;
                    break;
            }
            continue;
        }

        // 处理交易字段
        if ($inTransactionSection) {
            if ($line === '^') {
                // 一条交易结束,加入数组并重置
                if (!empty($currentTransaction)) {
                    $transactions[] = $currentTransaction;
                    $currentTransaction = [];
                }
                continue;
            }

            $tag = substr($line, 0, 1);
            $value = substr($line, 1);
            switch ($tag) {
                case 'D':
                    $currentTransaction['DATE'] = $value;
                    break;
                case 'T':
                    $currentTransaction['AMOUNT'] = (float)$value;
                    break;
                case 'N':
                    $currentTransaction['SERIAL'] = $value;
                    break;
                case 'P':
                    $currentTransaction['DESCRIPTION'] = $value;
                    break;
                case 'C':
                    $currentTransaction['TRANCODE'] = $value;
                    break;
            }
        }
    }

    // 处理最后一条未闭合的交易(如果有的话)
    if (!empty($currentTransaction)) {
        $transactions[] = $currentTransaction;
    }

    return [
        'account' => $account,
        'transactions' => $transactions
    ];
}

// 使用示例
$qifData = parseQIF('your-file.qif');

// 输出账户信息(和你给的示例格式一致)
print_r($qifData['account']);

// 输出交易记录(和你给的示例格式一致)
print_r($qifData['transactions']);

存入数据库的注意事项

  1. 日期格式转换:QIF的日期是MM/DD/YYYY,需要转成数据库支持的YYYY-MM-DD格式,比如用DateTime类处理:
    $date = DateTime::createFromFormat('m/d/Y', $transaction['DATE']);
    $dbDate = $date->format('Y-m-d');
    
  2. 金额处理:确保金额是数字类型,避免存入字符串,上面的代码已经用(float)转换了,你也可以根据数据库字段类型调整(比如用decimal类型的话直接存储即可)。
  3. 字段映射:把解析后的数组字段和你的数据库表字段对应好,比如账户表的type对应ASSETS,交易表的DATE对应transaction_date等。

测试&调整

不同软件导出的QIF文件可能略有差异(比如标记规则不同),你可以根据自己的QIF文件内容,调整代码里的标记映射逻辑,比如发现某个字段用了特殊标记,直接在switch里添加对应处理即可。

内容的提问来源于stack exchange,提问作者Yogesh Dobariya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:07:38