dow5001 2014-08-27 05:11
浏览 102
已采纳

CakePHP中的多维数组=> CSV导出

I'm trying to export data from my model and two related models into a CSV file in my CakePHP 2.4 app, and need some help doing it in a computationally non-expensive manner.

In my app, each Post hasMany Field and each Field belongsTo Fieldtype. Fields stores values, and Fieldtype stores the value types (IE "Oxygen concentration"). On each Post, there can be multiple Fields with the same Fieldtype.

The problem with CSV generation here is that each Post's Fields require a different number of columns, so when I'm doing my fputcsv I'm going to need to add empty cells for when any Post has less than the maximum number of fields for, say, Helium so the headers line up.

Is there a SQL solution that will somehow let me do a join on my Posts find and return an array of Fieldtypes with the maximum number of Fields needed for each Fieldtype?

My DB structure:

Posts
id

Fields
id    post_id    fieldtype_id    value

Fieldtypes
id    name
  • 写回答

1条回答 默认 最新

  • dqgg25493 2014-08-30 23:29
    关注

    I wasn't able to find an easy way to get the field count in SQL, and as it turns out doing it in PHP isn't too slow because it's not like I'm accessing the database each time.

    If anyone else has to deal with this problem, here's what I did:

    //Where $posts is my array of Posts and $fieldtypes is an id => name array of my column types
    public function makeCSV($posts = array(), $fieldtypes = array()){
        $fields = array();
        $fieldlist = array();
        foreach($posts as $post){
            foreach($post['Field'] as $field){
                if($field['value'] != ''){
                    $fields[] = $field['fieldtype_id'];
                    $fieldlist[$field['fieldtype_id']] = null;
                }
            } //Get a list of all the fields for that post
    
            $postcount = array_count_values($fields);
            $fields = array();
    
            // get a per-post count of fields
    
            foreach($postcount as $id => $count){
                if ($count > $fieldlist[$id] || !isset($fieldlist[$id])){
                    $fieldlist[$id] = $count;
                }
            }
        }
    
            $output = null;     
            $output .= "Latitude" . ",";
            $output .= "Longitude" . ",";
            $output .= "Sighted (UTC)" . ",";
            $output .= "Posted (UTC)" . ",";
            $output .= "User" . ",";
            $output .= "Location" . ",";
            $output .= "Tags" . ",";
            $output .= "Category" . ",";
            $output .= "Species status" . ",";
    //      $output .= "Comments" . ",";
    
        foreach ($fieldlist as $fieldtype => $count){
            $total = $count;
            while($count != 0){
                $output .= $fieldtypes[$fieldtype] . " " . ($total + 1 - $count)  . ",";
                --$count;
            }
        }
            $output = $output . "
    ";
    
        foreach ($posts as $post) {
            $output = $output . addslashes($post['Post']['lat']) . "," . addslashes($post['Post']['lng']) . ",";
            $output = $output . "\"" . addslashes($post['Post']['sighted']) . "\"" . ",";
            $output = $output . "\"" . addslashes($post['Post']['created']) . "\"" . ",";
            $output = $output . "\"" . addslashes($post['User']['username']) . "\"" . ",";
            $output = $output . "\"" . addslashes($post['Post']['location']) . "\"" . ",";
            $output = $output . "\"" . addslashes($post['Post']['tags']) . "\"" . ",";
            $output = $output . addslashes($post['Post']['category']) . ",";
            if ($post['Post']['status'] == 1) {
                $output .= "Present,";
            } elseif($post['Post']['status'] == 2) {
                $output .= "Recently Appeared,";
            } elseif ($post['Post']['status'] == 3) {
                $output .= "Disappeared,";
            }
            else {
                $output .= ",";
            }
    //      $output = $output . "\"" . addslashes(str_replace(array("
    ", "\t", ""), '', $post['Post']['body'])) . "\"" . ",";
    
            foreach ($fieldlist as $fieldtype => $count){
                foreach($post['Field'] as $field){
                    if($field['fieldtype_id'] == $fieldtype){
                        $output .= $field['value'] . ",";
                        --$count;
                    }
                }
                while ($count > 0){
                    $output .= ",";
                    --$count;
                }
            }
            $output = $output . "
    ";   
        }
        return $output; 
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 想问问富文本拿到的html怎么转成docx的
  • ¥15 我看了您的文章,遇到了个问题。
  • ¥15 GitHubssh虚拟机连接不上
  • ¥15 装完kali之后下载Google输入法 重启电脑后出现以下状况 且退不出去 桌面消失 反复重启没用
  • ¥15 ESP-IDP-BLE配网连接wifi
  • ¥15 ue2.6.12版本用的若以,安装gojs,引入import * as go from 'gojs';报错
  • ¥15 服务器上的网站安装php5.6版本
  • ¥15 ModuleNotFoundError: No module named 'torch.utils._import_utils' 是缺少什么
  • ¥15 请大咖一起探索iptv 直播源的hls通过反向代理解密
  • ¥100 寻找技术员 云闪付tn转h5输入卡号付款的链接 重酬!