【PHP】【实践技巧】【淘宝csv文件处理及PHP文件系统总结】

【PHP】【实践技巧】【淘宝csv文件处理及PHP文件系统总结】

一、前置说明

一般多用于后台管理系统里(图片上传可能适用于更多场景),主要对文件的一些操作,内容或有疏漏,不要介意,主要包含以下主题:

1、文件上传
2、解压文件
3、CVS文件读取与解析
4、淘宝csv文件相关字段处理
5、七牛云图片上传
6、文件夹相关操作(打开,遍历读取文件,删除文件夹内容等等)

写这篇文档的原因,是因为甩手工具箱导出的csv文件PHPexcel及PhpSpreadsheet都无法解析出正常的数据。说一下,这个csv文件编码格式是UCS-2。

补充:

用于excel和csv文件的导入与导出
composer require phpoffice/phpexcel
composer require phpoffice/phpspreadsheet

二、应用案例

将csv及相关图片资源压缩上传并解压
解压后,遍历解压文件夹里的所有csv文件
将甩手导出的csv文件解析成数组,
将数组里的图片路径改为七牛云路径,并上传图片
将处理好的数据存入数据库

三、使用

3.1、文件上传

前端:

html:

<form id="form" name="form" method="post" enctype="multipart/form-data"  >
    <input type="file" id="file" name="file" accept="application/zip"/>
    <input type="button" class="btn btn-primary " value="提交" onclick="upload()"/>
</form>

注:accept 是支持上传的文件类型,我需要的是zip,你可以不写这个字段

js:

  function upload() {
        layer.load(2,{
            shade: [0.1, '#fff']
        });
        var file = $("#file")[0].files[0];
        var form = new FormData();
        form.append('file[]', file)
        $.ajax({
            url: "/admin/Product/autoUpload",//这里是tp5的写法
            // dataType:"json",
            type: 'POST',
            data: form,
            cache: false,  //默认是true,但是一般不做缓存
            contentType: false,//设置为false,因为是构造的FormData对象,所以这里设置为false。
            processData: false,//设置为false,因为data值是FormData对象,不需要对数据做处理。
            success: function (response) {
			//---start----这里具体怎么写看你的后端代码如何返回
                if (!response.code) {
                    layer.msg(response.msg);
                    layer.closeAll('loading');
                } else {
                    layer.closeAll('loading');
                    setTimeout(function () {//刷新界面作用
                        window.location.href = response.url
                    }, response.wait * 1000);
                }
            }
			//---end----
        })
    }

php:

//简单地处理一下数据,具体使用不多赘述
if (empty($_FILES['file'])) {
            $this->error('文件未传输');
        }
        $file = [];
        foreach ($_FILES['file'] as $k => $v) {
            $file[$k] = $v[0];
        }
        if ($file['error'] == 4) {
            $this->error('请选择文件');
        }

3.2、解压文件

  补充:
        $name = $file['name'];
        //获取绝对路径
        $path = dirname(getcwd()) . DIRECTORY_SEPARATOR;//看你自己的项目路径
        //定义上传文件保存路径
       	$filepath = $path . 'upload'.DIRECTORY_SEPARATOR . $name;
        //使用PHP函数移动文件
        move_uploaded_file($file['tmp_name'], $filepath);//将上传的临时文件上传指定保存路径


	/**
     * 解压文件
     * @param string $dir 解压文件夹存放目录路径
     * @param string $filepath 压缩文件路径
     */
    private function _zip($dir,$filepath){
        $zip = new ZipArchive();
        $xif = $zip->open($filepath);
        if ($xif === true) {
            $doc_num = $zip->numFiles;
            //1.中文会出现乱码问题
            for ($i = 0; $i < $doc_num; $i++) {
                $statInfo = $zip->statIndex($i, \ZipArchive::FL_ENC_RAW);
                $filename = $this->transcoding($statInfo['name']);  //转码
                if ($statInfo['crc'] == 0) {
                    //新建目录
                    if (!file_exists($dir)) {
                        mkdir($dir, 0777);
                    }
                    if (!file_exists($dir . substr($filename, 0, -1))) {
                        mkdir($dir . substr($filename, 0, -1), 0777);
                    }
                } else {
                    //拷贝文件
                    if (!file_exists($dir . $filename)) {
                        copy('zip://' . $filepath . '#' . $zip->getNameIndex($i), $dir . $filename);
                    }
                }
            }
            //2.如果没有中文,可以直接使用下面注释的,路径修改下
            // $zip->extractTo($path.'/');//假设解压缩到在当前路径下
            $zip->close();
        }
}

     /**
     * 编码转换
     * @param string $fileName 文件名
     * @return false|string
     */
    private function transcoding($fileName)
    {
        $encoding = mb_detect_encoding($fileName, ['UTF-8', 'GBK', 'BIG5', 'CP936']);
        if (DIRECTORY_SEPARATOR == '/') {    //linux
           // $filename = iconv($encoding, 'UTF-8', $fileName);//要有iconv模块
            $filename = mb_convert_encoding($fileName,'UTF-8',$encoding);//要有mbstring模块
        } else {  //win
          $filename = mb_convert_encoding($fileName,'GBK',$encoding);
           // $filename = iconv($encoding, 'GBK', $fileName);
        }
        return $filename;
    }

3.3、处理csv文件

php:

    /**
     * csv文件处理 转化为数组
     * @param string $file 文件绝对路径 例如 D:\1.csv
     * @return array|void
     */
    private function fileDeal($file)
    {
        $data   = [];
        $key    = [];
        $handle = self::fopenUtf8($file);
        if ($handle === FALSE) return;
        $row = 0;
        while (($cols = self::_fgetcsv($handle, 0, "\t")) !== FALSE) {
            if ($row == 0 || $row == 2) {
                $row++;
                continue;
            }
            if ($row == 1) {
                $key = $cols;
                $row++;
                continue;
            }

            $temp = [];
            foreach ($cols as $k => $v) {
                if ($v == "") {
                    $v = null;
                }
                $temp[$key[$k]] = $v;
            }
            $data[] = $temp;
            $row++;
        }
        fclose($handle);
        return $data;
    }

    /**
     * 获取编码格式,并去除bom头
     * @param string $filename 文件路径
     * @return false|resource
     */
    private function fopenUtf8($filename)
    {
        $size   = filesize($filename) + 1;
        $handle = fopen($filename, 'r');
        $bom    = fread($handle, 2);
//    fclose($handle);
        rewind($handle);

        if ($bom === chr(0xff) . chr(0xfe) || $bom === chr(0xfe) . chr(0xff)) {
            // UTF16 Byte Order Mark present
            $encoding = 'UTF-16';
        } else {
            $file_sample = fread($handle, $size) + 'e';
            // + e is a workaround for mb_string bug
            rewind($handle);

            $encoding = mb_detect_encoding($file_sample, 'UTF-8, UTF-7, ASCII, EUC-JP,SJIS, eucJP-win, SJIS-win, JIS, ISO-2022-JP');
        }
        if ($encoding) {
            stream_filter_append($handle, 'convert.iconv.' . $encoding . '/UTF-8');
        }
        return ($handle);
    }

    /**
     * fgetcsv重写
     * @param $handle   示例 $handle = fopen($filename, 'r');
     * @param null $length
     * @param string $d
     * @param string $e
     * @return bool|mixed
     */
    private function _fgetcsv(&$handle, $length = null, $d = ',', $e = '"')
    {
        $d     = preg_quote($d);
        $e     = preg_quote($e);
        $_line = "";
        $eof   = false;
        while ($eof != true) {
            $_line   .= (empty ($length) ? fgets($handle) : fgets($handle, $length));
            $itemcnt = preg_match_all('/' . $e . '/', $_line, $dummy);
            if ($itemcnt % 2 == 0)
                $eof = true;
        }
        $_csv_line    = preg_replace('/(?: |[ ])?$/', $d, trim($_line));
        $_csv_pattern = '/(' . $e . '[^' . $e . ']*(?:' . $e . $e . '[^' . $e . ']*)*' . $e . '|[^' . $d . ']*)' . $d . '/';
        preg_match_all($_csv_pattern, $_csv_line, $_csv_matches);
        $_csv_data = $_csv_matches[1];
        for ($_csv_i = 0; $_csv_i < count($_csv_data); $_csv_i++) {
            $_csv_data[$_csv_i] = preg_replace('/^' . $e . '(.*)' . $e . '$/s', '$1', $_csv_data[$_csv_i]);
            $_csv_data[$_csv_i] = str_replace($e . $e, $e, $_csv_data[$_csv_i]);
        }
        return empty ($_line) ? false : $_csv_data;
    }

3.4、淘宝csv文件相关字段处理

//正则替换 图片路径
//--遍历转换好的数组时使用
$reg = '/[\'"]file:\/\/\/(.*?)[\'"]/i';
$v['description'] = preg_replace_callback(
                $reg,
                function ($matches) use ($qny_domain,$tempPath) {
                    //将本地路径改为服务器文件解压路径
                    $str =$tempPath. substr($matches[1],strpos(mb_convert_encoding($matches[1], 'utf-8'), mb_convert_encoding('淘宝助理', 'utf-8')));
                    $url = self::upload($matches[1]);//上传图片
                    return '"' . $qny_domain . $url . '"';//图片链接拼装
                },
                $v['description']
            );

//数据库[{},{}]格式形成
$r = [[],[]];
$res = json_encode($r)
//可以重置索引(数值)
$data = array_merge($data)

3.5、七牛云上传

    注:tbi后缀文件改成jpg就可以变成图片
	/**
     * 七牛云上传(用于csv里的图片上传,如果用于其他的需要些许修改,看里面注释)
     * @param $file 文件绝对路径
     * @return mixed
     * @throws \Exception
     */
    private function upload($file)
    {
        $qiniu     = config('admin.qiniu2');//tp里获取七牛云配置,主要下面三个要填写
        $accessKey = $qiniu['app_key'];
        $secretKey = $qiniu['app_secret'];
        $bucket    = $qiniu['bucket'];

        $auth = new Auth($accessKey, $secretKey);

        // 生成上传Token
        $token = $auth->uploadToken($bucket);
        $str   = explode('.', $file);
        $ext   = $str[count($str) - 1]; // 获取后缀名
        //--------start--------如果你要上传其他类型文件,就删掉这一段
        if ($ext == 'tbi') {
            $ext = 'jpg';
        }
        //--------end--------
        // 上传到七牛存储后保存的文件名
        $key = date('Y') . '/' . date('m') . '/' . substr(md5($file), 0, 5) . date('YmdHis') . mt_rand(0, 9999) . '.' . $ext;
        // 构建 UploadManager 对象
        $uploadMgr = new UploadManager();

        // 调用 UploadManager 的 putFile 方法进行文件的上传,该方法会判断文件大小,进而决定使用表单上传还是分片上传,无需手动配置。
        list($ret, $err) = $uploadMgr->putFile($token, $key, $file);
        if ($err !== null) {
            return false;
            //写个日志
        } else {
            return $ret['key'];//里面里有新的文件名字
        }
    }

3.6、文件夹相关操作

    /**
     * 删除指定目录下的文件
     * @param string $path 需要删除的文件夹路径
     * @param bool $delDir
     * @return bool
     */
    private function delDirAndFile($path, $delDir = FALSE)
    {
        $handle = opendir($path);
        if ($handle) {
            while (false !== ($item = readdir($handle))) {
                if ($item != "." && $item != "..")
                    is_dir("$path/$item") ? $this->delDirAndFile("$path/$item", $delDir) : unlink("$path/$item");
            }
            closedir($handle);
            if ($delDir)
                return rmdir($path);
        } else {
            if (file_exists($path)) {
                return unlink($path);
            } else {
                return FALSE;
            }
        }
    }

//遍历文件夹
        $temp = scandir($path);
        foreach ($temp as $v) {
            $file = $path . $v;
            if (!is_dir($file) && substr($file, strpos($file, '.') + 1) == 'csv') {//不处理csv可删除
                //处理csv文件
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值