개발/Dart & Flutter

[Dart/Flutter] Upload Multiple Images to Server Using PHP and JSON / 서버에 이미지 업로드

Monsh 2021. 7. 26. 22:45
반응형

import 및 여러 가지 기본적인 요소는 생략 되어 있지만,

파라미터의 사용 등 중요한 부분은 생략하지 않았습니다.


구성

class, 페이지(view), 컨트롤러, php


Class: img_key_value.dart

class ImgKeyValue {
    String fn;
    String encoded;
    
    ImgKeyValue({this.fn, this.encoded});
    
    Map<String, String> toJson() => <String, String> {
    	'fn': fn,
        'encoded': encoded,
    };
}

class IKVList {
    List<ImgKeyValue> imgKeyValues;
    
    IKVList(this.imgKeyValues);
    
    Map<String, dynamic> toJson() => <String, dynamic> {
    	'imgKeyValues': imgKeyValues,
    };
}

페이지: img_upload.dart

import 'convert';
import 'http';
import 'image_picker';
import 'io';
import 'material';
import 'path';

import 'img_key_value.dart';
import 'upload_controller';

class ImgUpload extends StatefulWidget {
  @override
  _imgUload createState() => _imgUpload();
}

class _imgUpload extends State<ImgUpload> {
  ImagePicker _picker = ImagePicker();
  List<XFile> _imageFileList;

  void _xFilesToFiles(List<XFile> imageFileList) {
    imageFileList.forEach((element) {
      fileList.add(File(element.path));
    });
  }

  List<Widget> fileListThumb;
  List<File> fileList = [];

  Future _pickFiles() async {
    List<Widget> thumbs = [];
    final pickedFileList = await _picker.pickMultiImage();
    setState(() {
      _imageFileList = pickedFileList;
    });
    _xFilesToFiles(_imageFileList);
    if (fileList != null && fileList.length > 0) {
      fileList.forEach((element) {
        thumbs.add(
            Padding(padding: EdgeInsets.all(1), child: Image.file(element)));
      });
      setState(() {
        fileListThumb = thumbs;
      });
    }
  }

  IKVList toBase64(List<File> fileList) {
    List<ImgKeyValue> imgKeyValues = [];

    if (fileList.length > 0) {
      fileList.forEach((element) {
        ImgKeyValue _imgKeyValue = ImgKeyValue(fn: basename(element.path), encoded: base64Encode(element.readAsBytesSync()));
        imgKeyValues.add(_imgKeyValue);
      });
    }

    IKVList ikvList = IKVList(imgKeyValues);

    return ikvList;
  }

  _uploadImages(IKVList ikvList) {
    UploadController().uploadImages(ikvList);
  }

  @override
  Widget build(BuildContext context) {
    if (fileListThumb == null)
      fileListThumb = [
        InkWell(
          onTap: _pickFiles,
          child: Container(child: Icon(Icons.add)),
        )
      ];
    return Scaffold(
      appBar: AppBar(
        title: Text("Uploader"),
      ),
      body: Center(
          child: Padding(
        padding: EdgeInsets.all(5),
        child: GridView.count(
          crossAxisCount: 4,
          children: fileListThumb,
        ),
      )),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          IKVList _ikvList = toBase64(fileList);
          _uploadImages(_ikvList).then((response) {
            if (response == true) {
              print("success");
            } else
              print("fail");
          });
        },
        tooltip: 'Upload File',
        child: const Icon(Icons.cloud_upload),
      ),
    );
  }
}

컨트롤러: upload_controller.dart

class UploadController {

  Future<bool> uploadImages(IKVList ikvList) async {
    String yourWebsite = "yourwebsite.yourdomain";
	String yourPhp = "/upload.php";

    final _ikvList = json.encoder.convert(ikvList);

    final response = await http.post(
        Uri.https(yourWebsite, yourPhp),
      body: <String, String> {
          'ikvList': _ikvList.toString()
      });
  
    if (response.statusCode == 200) {
      return true;
    } else {
      return false;
    }
  }
  
}

PHP: upload.php

<?php

    $ikvList = json_decode($_POST['ikvList'], true);

    try {
        foreach($ikvList as $imgKeyValues){
            foreach($imgKeyValues as $ikv){
                $fn = $ikv['fn'];
                $decoded = base64_decode($ikv['encoded']);

                file_put_contents('PathYouWant'.$fn, $decoded);
            }
        }
        echo 'OK';

    } catch(Exception $e) {
        echo $e->getMessage();
    }
    
?>

JSON을 이중으로 감쌌는데,

뇌정지가 와서 풀고 싶지가 않네요...

잘 수정해서 쓰시길 바랍니다.

반응형