douhongxie5436 2019-03-14 21:16 采纳率: 100%
浏览 192
已采纳

PHP - 遍历文件并为JSON分解文本块

I have a file on a server that I need to parse and build a JSON object to return. I am using PHP.

The file contents look something like this:

########################################
#             NOTES FILE
#
# THIS FILE IS AUTOMATICALLY GENERATED
#        DO NOT MODIFY THIS FILE!
########################################

info {
    created=1552596653
    version=4.4.3
    last_update_check=1552554585
    update_available=0
    last_version=4.4.3
    new_version=4.4.3
    }

programstatus {
    modified_host_attributes=0
    modified_service_attributes=0
    pid=11523
    daemon_mode=1
    program_start=1552593834
    last_log_rotation=0
    ...

Ideally, I would like to grab EACH segment (eg: "info", "programstatus", etc...) and add them to the JSON obj/array as I parse through it. With each attribute = value being assigned accordingly.

So something like:

$data = array();

// Loop here for each segment
$data['info'] = array(
    "created" => "1552596653",
    "version" => "4.4.3",
    etc...
)

// Then wrap it up with something like
return json_encode($data);

I just can't "think" to loop through the file while breaking it out into chunks.

I have the file contents via:

$statusFile = '/location/to/my/data/file';

ob_start();
include( $statusFile );
$statusFileContent = ob_get_contents();
ob_end_clean();
  • 写回答

3条回答 默认 最新

  • dougan1205 2019-03-14 22:11
    关注

    You need to accomplish 3 things:

    1. Load the file contents in a way that will allow you to read very large files without storing it entirely in memory.
    2. When getting each line, you need to run it through a parsing algorithm of your own design to be able to extract the data efficiently.
    3. You finally need to write each line's data to memory (or a file if you expect the data to be too large and might run out.

    Here is a rough chunk of code I threw together that illustrates the approach you could take. I tested it on PHP Fiddle, but couldn't figure out how to share a link.

    <?php
    
        // File path to load
        // $file = "/path/to/file.txt";
        $file = "https://pastebin.com/raw/gu2AC7qy";
    
        // Flag indicating we are inside of a "block"
        $inBlock = false;
    
        // Name/Key of current "block"
        $blockName = null;
    
        // Container for our data
        $data = [];
    
        // Open for reading
        $handle = fopen($file, 'r');
    
        // If we opened it (you should add better error handling)
        if ($handle) {
    
            // Grab each line one at a time
            while(($line = fgets($handle)) !== false) {
    
                // Cleanup line
                $line = trim($line);
    
                // Throw away useless lines (comments, empty, etc.)
                if (empty($line)) {
                    // Skip blank lines
                    continue;
                }
                if (substr($line, 1) == '#') {
                    // Skip comments
                    continue;
                }
    
                // Check if start of "block"
                if (substr($line, -1) == '{') {
                    // Set the flag
                    $inBlock = true;
                    // Get the block name
                    $blockName = trim(str_replace('{', '', $line));
                    // Create new data section
                    $data[$blockName] = [];
                    // Get next line
                    continue;
                }
    
                // If currently inside block
                if ($inBlock === true && ! empty($blockName)) {
                    // Get a data attribute
                    $dataRow = trim($line);
                    // Parse as key/value
                    $dataRowParts = explode("=", $dataRow);
                    $key = isset($dataRowParts[0]) ? trim($dataRowParts[0]) : null;
                    $value = isset($dataRowParts[1]) ? trim($dataRowParts[1]) : "";
                    // Store in current block's data
                    if ($key !== null) {
                        $data[$blockName][$key] = $value;
                    }
                    // Get next line
                    continue;
                }
    
                // Check if end of "block"
                if (substr($line, -1) == '}') {
                    // Clear flag
                    $inBlock = false;
                    // Unset block name
                    $blockName = null;
                    // Get next line 
                    continue;
                }
            }
    
            // Close the file
            fclose($handle);
        }
    
        // Output data as JSON
        echo json_encode($data);
    
    ?>
    

    Ideally you would put this logic in classes and methods so it's not a giant wall of code -- and of course add appropriate error handling. Good luck!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号