CsvParser.php 3.6 KB
<?php
/**
 * Created by PhpStorm.
 * User: Cibermag
 * Date: 26.08.2015
 * Time: 17:00
 */

namespace app\components\parsers;

use Yii;
use yii\base\ErrorException;

class CsvParser implements \IteratorAggregate {

    /** @var string */
    private $filePath;

    /** @var bool */
    private $hasHeaderRow;

    /** @var string */
    private $delimiter;

    /** @var string */
    private $enclosure;

    /** @var string */
    private $escape;

    /** @var resource */
    private $handler;

    /** @var out encoding charset */
    private $out_charset = 'UTF-8';
    /** @var out encoding charset */
    public $in_charset;
    /** @var out encoding charset */
    public $first_line;


    public function __construct($filePath, $first_line = 0,$hasHeaderRow = TRUE)
    {

        $this->in_charset = 'windows-1251';
        $this->filePath = $filePath;
        $this->hasHeaderRow = $hasHeaderRow;
        $this->first_line = $first_line;

    }

//    public function encodeFile( $in_charset, $out_charset, $filePath ){
//
//        $old_content = file_get_contents( $filePath );
//        $encode_content = iconv( $in_charset, $out_charset, $old_content );
//        $file = @fopen( $filePath, "w" );
//        fwrite( $file, $encode_content );
//        @fclose( $file );
//
//    }


    /**
     * @param string $delimiter
     * @param string $enclosure
     * @param string $escape
     * @return $this
     */
    public function setup($delimiter = ';', $enclosure = '"', $escape = '\\')
    {
        $this->handler->setCsvControl($delimiter);
    }

    public function getIterator()
    {
        return new \ArrayIterator($this->read());
    }

    /**
     * @return array
     * @throws InvalidFileException
     * @deprecated Use ::read instead.
     */
    public function parseAll()
    {
        return $this->read();
    }

    /**
     * @return array
     * @throws InvalidFileException
     */
    public function read()
    {
        $return = [];

        $this->openHandler();

        $line = 0;
        $keys = NULL;

        while (($row = $this->readRow()) !== FALSE) {
            $line++;

            if ($this->hasHeaderRow) {
                if ($keys === NULL) {
                    $keys = array_values($row);
                } else {

                    if (count($keys) !== count($row)) {
//
                        Yii::warning("Invalid columns detected on line #$line .");
                        return $return;
                    }

                    $return[] = array_combine($keys, $row);
                }
            } else {
                $return[] = $row;
            }
        }

        $this->closeHandler();

        return $return;
    }

    private function openHandler()
    {
        try {
            $this->handler = new \SplFileObject( $this->filePath , 'r' );;
        } catch (ErrorException $e) {
            Yii::warning("Ошибка открытия файла {$this->filePath}");
        }
        $this->handler->setFlags(\SplFileObject::READ_CSV);// | \SplFileObject::READ_AHEAD | \SplFileObject::SKIP_EMPTY | \SplFileObject::DROP_NEW_LINE);
        $this->handler->fseek( $this->first_line );
        $this->setup();
    }
    private function closeHandler()
    {
        $this->handler = NULL;
    }

    private function readRow()
    {
        $dirt_value_arr = $this->handler->fgetcsv(  );
        return $this->encodeArray( $dirt_value_arr );

    }

    private function encodeArray( $array_to_encode )
    {
        return array_map(function($array_to_encode) {
            return iconv( $this->in_charset, $this->out_charset, $array_to_encode );
        }, $array_to_encode);

    }


}