1. 程式人生 > 實用技巧 >ecstore匯入檔案開發問題解決 死迴圈+不相容mac換行解決

ecstore匯入檔案開發問題解決 死迴圈+不相容mac換行解決

1、死迴圈

/**
* 如果是最後一條記錄和倒數第二天記錄屬於同一個商品則繼續下去
* @return bool true 繼續獲取下一行 false 不需要在獲取,已經完整的獲取到一條商品資料
*/
public function check_continue(&$contents,&$line){

if ( count($contents) == 1 )
{
return true;
}
else
{
array_pop($contents);
return false;
}
}

2、不相容mac換行:
主要是這個
ini_set("auto_detect_line_endings", true);//https://www.cnblogs.com/jwentest/p/12852724.html
<?php
/*
 * 提供匯出匯出資料處理
 * */
ini_set("auto_detect_line_endings", true);//https://www.cnblogs.com/jwentest/p/12852724.html
class importexport_data_object{

    /**
     * 例項對應的model
     *
     * @params string $class_model  例如:b2c_mdl_members
     */
    public function __construct($class_model){
        //例項化要匯出或匯入的model
        $model = substr(stristr($class_model,'mdl_'),4);
        $app_id = substr($class_model,0,strpos($class_model,'_mdl'));
        $this->model = app::get($app_id)->model($model);

        //匯出匯入資料組織擴充套件
        $object =  kernel::service('importexport.'.$class_model);
        if( is_object($object) ){
            $this->extends = $object;
        }

        $this->set_group();
    }

    /**
     * 設定每次getList分頁條數
     */
    public function set_limit($limit=100){
        return $this->limit = 100;
    }

    public function get_limit(){
        return $this->limit ? $this->limit : 100;
    }

    /**
     * @brief 將匯出條件統一轉換為主鍵ID的條件,返回查詢條件
     *
     * @param array $filter
     *
     * @return array
     */
    public function getIdFilter($filter)
    {
        if( $this->extends && method_exists($this->extends, 'getIdFilter') )
        {
            return $this->extends->getIdFilter($filter);
        }

        $id = $this->model->schema['idColumn'];
        if( is_array($id) )
        {
            $idColumn = implode(',',$id);
        }
        else
        {
            $idColumn = $id;
        }

        if( isset($filter['_DTIME_']) && $filter['_DTIME_'] ){
            $this->model->filter_use_like = true;
        }

        $tmpfilter = $this->model->getList($idColumn,$filter);
        foreach( $tmpfilter as $row )
        {
            if( is_array($id) )
            {
                foreach( $id as $col )
                {
                    $newfilter[$col][] = $row[$col];
                }
            }
            else
            {
                $newfilter[$id][] = $row[$idColumn];
            }
        }
        return $newfilter;
    }

    /**
     * 匯出資料設定分組
     *
     * @params $col string 匯出資料分組欄位
     */
    public function set_group($col=null){

        if( $this->extends && method_exists($this->extends, 'set_group') )
        {
            $col = $this->extends->set_group($col);
        }

        $this->group_col = $col;
    }

    public function get_template($group_val=0){
        $title = $this->get_title();
        if( $group_val ){
            return $title[$group_val];
        }else{
            return $title;
        }
    }

    /*
     * 獲取匯出資料
     * */
    public function fgetlist( &$outputData,$filter,$offset){
        $limit = $this->get_limit();
        if(!$this->title){
            $this->title = $this->get_title();
        }

        $contents = $this->get_content($filter,$offset,$limit);
        if(!$contents) return false;

        $outputData = array();
        foreach($contents as $group_val=>$content){
            if( $this->group_col ){
                $outputGroupData = array_merge(array($this->title[$group_val]),$contents[$group_val]);
                $outputData = array_merge($outputGroupData,$outputData);
            }else{
                if($offset === 0){//第一次需要頭部資料
                    $outputData = array_merge(array($this->title),$content);
                }else{
                    $outputData = $content;
                }
            }
        }
        return true;
    }//end function

    /*
     * 獲取匯出欄位
     */
    public function get_title()
    {
        $title = $this->_title();

        if( $this->extends && method_exists($this->extends, 'get_title') )
        {
            $title = $this->extends->get_title($title);
        }
        return $title;
    }

    private function _title()
    {
        $cols = $this->model->_columns();
        $title = array();
        foreach( $cols as $col => $val )
        {
            if( !$val['deny_export'] ){//不進行匯出匯入欄位
                $title[$col] = $val['label'].'('.$col.')';
            }
        }
        return $title;
    }

    /**
     * 獲取匯出的資料
     */
    public function get_content($filter,$offset,$limit)
    {
        $title = $this->_title();//需要匯出欄位

        if($this->group_col){
            if( !$list = $this->model->getList(implode(',',array_keys($title)),$filter,$offset*$limit,$limit,$this->group_col) ) return false;
        }else{
            if( !$list = $this->model->getList(implode(',',array_keys($title)),$filter,$offset*$limit,$limit) ) return false;
        }

        $contents = array();
        foreach( (array)$list as $line => $row )
        {
            $tmpRow = array();
            $row = $this->_pre_content($row);
            if( $this->extends && method_exists($this->extends, 'get_content_row') )
            {
                $tmpRow = $this->extends->get_content_row($row);
            }else{
                $tmpRow[$line] = $row;
            }

            $group_val = isset($row[$this->group_col]) ? $row[$this->group_col] : 0;
            foreach($tmpRow as $key=>$tmpRowVal ){
                $contents[$group_val][] = $tmpRowVal;
            }
        }
        return $contents;
    }

    /**
     * 匯出資料庫中的資料格式進行轉換
     */
    private function _pre_content($row){
        $cols = $this->model->_columns();
        $rowVal = array();
        foreach( (array)$row as $col => $val ){
            //如果改欄位的型別為time 則轉換
            if( in_array( $cols[$col]['type'],array('time','last_modify') ) && $val )
            {
                $val = date('Y-m-d H:i',$val);
            }

            //如果是longtext,則將匯出的資料去掉換行符
            if ($cols[$col]['type'] == 'longtext')
            {
                if (strpos($val, "\n") !== false){
                    $val = str_replace("\n", " ", $val);
                }
            }

            //關聯表字段顯示對應的is_title欄位
            if( strpos( (string)$cols[$col]['type'], 'table:')===0 && $col != $this->group_col)
            {
                #type=>table@b2c:member_lv  $subobj = array(0=>b2c,1=>member_lv)
                $subobj = explode( '@',substr($cols[$col]['type'],6) );
                if( !$subobj[1] ){//為指定app則表示關聯表和當前表屬相同app
                    $subobj[1] = $this->model->app->app_id;
                }
                $hasModel = app::get($subobj[1])->model( $subobj[0] );
                $textColumn = $hasModel->getList( $hasModel->schema['textColumn'], array( $hasModel->schema['idColumn'] => $val ) );
                $val = $textColumn[0][$hasModel->schema['textColumn']] ? $textColumn[0][$hasModel->schema['textColumn']] : $val;
            }

            #'type' => array(
            #     'pc' =>app::get('b2c')->_('標準平臺'),
            #     'wap' => app::get('b2c')->_('手機觸屏')
            # )
            # 如果type為陣列則 $val='pc' 轉換為$val = '標準平臺' 否則 直接匯出資料庫儲存的值
            $rowVal[$col] = is_array($cols[$col]['type']) ? $cols[$col]['type'][$val] : $val;
        }
        return $rowVal;
    }

    /*-----------------------以下為匯入函式-----------------------*/

    //處理讀取出的資料,格式化資料,將資料中的值對應到欄位中
    public function pre_import_data($contents,$line) {
      /*  foreach($contents as $k=>$v){
            foreach($v as $kk=> $vv){
                $contents[$k][$kk]=iconv('GBK','UTF-8',$vv);
            }
        }*/
        $oneline = current($contents);


        $title = $this->get_title();



        foreach( $title as $group_val=>$title_row )
        {
            //如果第一條記錄為標題
            if( current($title_row) == current($oneline) )
            {

                //將匯入的標題對應到定義的欄位中
                $title_row_flip = array_flip($title_row);
                $this->current_title = array();
                foreach( $oneline as $key=>$label )
                {
                    $col = $title_row_flip[$label];
                    $this->current_title[] = $col;
                }
                //end


                array_shift($contents);
            }
        }

        if( !$this->current_title ){
            return false;
        }

        foreach((array)$contents[$line] as $key=>$value){
            $col = $this->current_title[$key];
            if( $col )
            {
                $contents[$line][$col] =$value;
            }
            unset($contents[$line][$key]);
        }
        return $contents;
    }//end function


    /**
     * 檢查是否需要繼續讀取檔案
     * 一般情況下每次讀取一行則進行處理一行資料
     * 但是多規格商品的時候,需要一次讀取多個行,才是一個完整的商品資料
     * 因此需要判斷如果一個商品資料未完成則時候則需要繼續讀取資料
     */
    public function check_continue(&$contents,&$line) {

        file_put_contents(DATA_DIR.'/importTichengNew.txt',date("Y-m-d H:i:s")."\r\n".var_export($contents,true)."\r\n".$line."\r\n",FILE_APPEND);

        if( empty($contents) ) return true;

        if($line == 0 ){
            $line++;
            return true; //如果是第一行則繼續
        }

        $result = false; //預設不需要繼續

        if( $this->extends && method_exists($this->extends, 'check_continue') )
        {
            //check_continue 需要將$contents 傳引用出來
            $result = $this->extends->check_continue($contents,$line);
        }

        if( $result ) $line++;

        return $result;
    }

    /**
     * 將匯入資料由陣列轉換為sdf格式
     * @param array $contents 匯入的資料
     * @param string 如果錯誤返回錯誤資訊
     */
    public function dataToSdf($contents,&$msg) {

        if( $this->extends && method_exists($this->extends, 'dataToSdf') )
        {
            $rs = $this->extends->dataToSdf($contents,$msg);
        }

        return $rs;
    }
}