티스토리 뷰
웹프로그램을 개발하는 과정에서 사진(이미지)파일을 선택해서 다중으로 입력하는 구문이 많이 어려웠습니다.
단일 파일은 만들어서 사용을 많이 했는데,
다중파일을 선택해서 이미지를 누르면 업로드 되고 화면에 나오는 것...
너무 많이 쓰는 방식인데, php와 javascript를 사용해서 실제 구현한 내용을 정리해 봤습니다.
제품사진등록... 다중으로 선택가능하도록 만드는 구간.
<button type="button" id="delBtn" class="btn btn-secondary"> DATA 삭제 </button>
<button type="button" id="regpicBtn" class="btn btn-secondary" > 제품사진등록 </button>
<button type="button" class="btn btn-secondary" id="EcountsendBtn"> Ecount 자료 전송화면 </button>
기본적으로 부트스트랩의 버튼을 사용해서 만들었지요.
제품사진등록 버튼을 구현하는 내용을 정리한 것입니다.
제이쿼리를 이용해서 창을 하나 띄웠습니다.
$("#regpicBtn").click(function(){ // 사진등록
const num = $("#num").val();
window.open('reg_pic.php?num=' + num ,"사진등록","width=1200, height=700, top=0,left=0,scrollbars=no");
});
이렇게 창을 하나 띄우게 만든 후 php에 javascript 구문을 함께 넣어서,
이미지파일의 압축부분의 로직이 들어있습니다.
원본그대로 올리면? 파일 크기가 엄청 큰거 다 아시죠? 그래서 압축하는 과정이 로직에 들어있습니다.
<meta charset="utf-8">
<?php
session_start();
$num=$_REQUEST["num"];
$parent=$num;
if(isset($_REQUEST["check"]))
$check=$_REQUEST["check"];
else
$check=$_POST["check"];
require_once("../lib/mydb.php");
$pdo = db_connect();
try{
$sql = "select * from mirae8440.(DB테이블명) where num=?";
$stmh = $pdo->prepare($sql);
$stmh->bindValue(1, $num, PDO::PARAM_STR);
$stmh->execute();
$row = $stmh->fetch(PDO::FETCH_ASSOC);
$PROD_DES = $row["PROD_DES"];
}catch (PDOException $Exception) {
print "오류: ".$Exception->getMessage();
}
if(isset($_POST['submit'])){
$countfiles = count($_FILES['file']['name']);
for($i=0;$i<$countfiles;$i++){
$filename = $_FILES['file']['name'][$i];
$sql = "INSERT INTO fileup(id,name) VALUES ('$filename','$filename')";
$db->query($sql);
move_uploaded_file($_FILES['file']['tmp_name'][$i],'imgwork/'.$filename);
}
}
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<link rel="stylesheet" href="../css/partner.css" type="text/css" />
<style>
.progress {
margin: 10px;
width: 700px;
}
.blink {
-webkit-animation: blink 1.05s linear infinite;
-moz-animation: blink 1.05s linear infinite;
-ms-animation: blink 1.05s linear infinite;
-o-animation: blink 1.05s linear infinite;
animation: blink 1.05s linear infinite;
}
@-webkit-keyframes blink {
0% { opacity: 1; }
50% { opacity: 1; }
50.01% { opacity: 0; }
100% { opacity: 0; }
}
@-moz-keyframes blink {
0% { opacity: 1; }
50% { opacity: 1; }
50.01% { opacity: 0; }
100% { opacity: 0; }
}
@-ms-keyframes blink {
0% { opacity: 1; }
50% { opacity: 1; }
50.01% { opacity: 0; }
100% { opacity: 0; }
}
@-o-keyframes blink {
0% { opacity: 1; }
50% { opacity: 1; }
50.01% { opacity: 0; }
100% { opacity: 0; }
}
@keyframes blink {
0% { opacity: 1; }
50% { opacity: 1; }
50.01% { opacity: 0; }
100% { opacity: 0; }
}
</style>
<title> 사진등록/수정 </title>
</head>
<body>
<div id="top-menu">
</div>
</div>
<br>
<div class="row">
<h1 class="display-1 text-left">
<input type="button" class="btn btn-secondary btn-lg " value="닫기" onclick="self.close();"> </h1>
</div>
<br>
<br>
<form id="board_form" name="board_form" method="post" action="pic_insert.php" enctype="multipart/form-data">
<input type="hidden" id=childnum name=childnum value="<?=$childnum?>" >
<input type="hidden" id=check name=check value="<?=$check?>" >
<input type="hidden" id=parent name=parent value="<?=$parent?>" >
<input type="hidden" id=num name=num value="<?=$num?>" >
<input type="hidden" id=mode name=mode value="<?=$mode?>" >
<input type="hidden" id=PROD_DES name=PROD_DES value="<?=$PROD_DES?>" >
<div class="container">
<div class="row">
<H1 class="display-5 font-center text-center" > 사진 등록/수정 </H1>
</div>
<div class="row">
<div id=progressbar class="blink" style="display:none;">
<!-- <div id=progressbar style="display:none;" class=blinking > -->
<div class="row"> </div> <br>
<h1 class="display-1 text-left"> 사진등록을 서버에 저장중입니다. <br> (잠시만 기다려주세요.) </h1>
<div class="progress">
<div id="dynamic" class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
<span id="current-progress"></span>
</div>
</div>
<div class="row"> </div> <br>
</div>
</div>
<br>
<div class="row">
<h1 class="display-5 font-center text-left">
품명(규격) : <?=$PROD_DES?>
<br>
<br>
<?php
if($filename1!=null) {
print "기존 업로드 파일 있음 " . $filename1 ;
echo "<img src='". $imgurl1 . "'";
print " </div> <br> <br>";
}
?>
<div class="row">
<input id="upfile" name="upfile[]" class="input" type="file" onchange="this.value" multiple >
</div>
<div class="row">
<div id=progressbar1 class="blink" style="display:none;">
<!-- <div id=progressbar style="display:none;" class=blinking > -->
<div class="row"> </div> <br>
<h1 class="display-1 text-left"> 사진등록을 서버에 저장중입니다. <br> (잠시만 기다려주세요.) </h1>
<div class="progress">
<div id="dynamic" class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
<span id="current-progress"></span>
</div>
</div>
<div class="row"> </div> <br>
</div>
</div>
<div class="row">
<h1 class="display-5 font-center text-left">
<br>
<div class="row">
<h1 class="display-1 text-left">
<input type="button" class="btn btn-primary btn-lg " value="서버에 저장하기" onclick="javascript:pro_submit()" > </h1>
</div>
</div>
</div>
</form>
</body>
</html>
<script>
/* function new(){
window.open("viewimg.php","첨부이미지 보기", "width=300, height=200, left=30, top=30, scrollbars=no,titlebar=no,status=no,resizable=no,fullscreen=no");
} */
var imgObj = new Image();
function showImgWin(imgName) {
imgObj.src = imgName;
setTimeout("createImgWin(imgObj)", 100);
}
function createImgWin(imgObj) {
if (! imgObj.complete) {
setTimeout("createImgWin(imgObj)", 100);
return;
}
imageWin = window.open("", "imageWin",
"width=" + imgObj.width + ",height=" + imgObj.height);
}
function inputNumberFormat(obj) {
obj.value = comma(uncomma(obj.value));
}
function comma(str) {
str = String(str);
return str.replace(/(\d)(?=(?:\d{3})+(?!\d))/g, '$1,');
}
function uncomma(str) {
str = String(str);
return str.replace(/[^\d]+/g, '');
}
function input_Text(){
document.getElementById("test").value = comma(Math.floor(uncomma(document.getElementById("test").value)*1.1)); // 콤마를 계산해 주고 다시 붙여주고
}
function copy_below(){
}
function pro_submit()
{
$('#progressbar').show();
$('#progressbar1').show();
$('#progressbar2').show();
$('#board_form').submit();
}
</script>
서버저장하기 버튼을 누르면 동작하는 것은 pic_insert.php 내용입니다. 서버에 저장하는 내용의 구현입니다.
<?php session_start();
if(isset($_REQUEST["num"]))
$num=$_REQUEST["num"];
else
$num="";
if(isset($_REQUEST["check"]))
$check=$_REQUEST["check"];
else
$check=$_POST["check"];
$countfiles = count($_FILES['upfile']['name']);
for($i=0;$i<$countfiles;$i++){
$filename = $_FILES['upfile']['name'][$i];
// $target_file = 'imgwork/'.$filename;
// move_uploaded_file($_FILES['file']['tmp_name'][$i],$target_file);
// $statement->execute(array($filename,$target_file));
print $filename;
if($filename !='') {
//Auth key
define('UPLOAD_ERR_INI_SIZE',"100000000");
$uploads_dir = './imgwork'; //업로드 폴더 -현재 처리하는 폴더 하부로 imgtest 폴더
$allowed_ext = array('jpg','jpeg','png','gif','JPG','JPEG','PNG','GIF'); //이미지 파일만 허용
//첨부파일이 있다면
$uploadSize = 100000000;
@mkdir("$upload_dir", 0707);
@chmod("$upload_dir", 0707);
// 올라간 파일의 퍼미션을 변경합니다.
chmod("$uploads_dir", 0755);
// 변수 정리
$error = $_FILES['upfile']['name'][$i];
$name = $_FILES['upfile']['name'][$i];
$tmpNm = explode( '.', $name );
$ext = strtolower(end($tmpNm));
echo "$ext <br>";
// 확장자 확인
if( !in_array($ext, $allowed_ext) ) {
echo "허용되지 않는 확장자입니다.";
exit;
}
// $newfile=$tmpNm[0].".".$ext ;
$new_file_name = date("Y_m_d_H_i_s");
$newfilename1 = $new_file_name."_" . $i . "." . $ext;
$url1 = $uploads_dir.'/'.$newfilename1; //올린 파일 명 그대로 복사해라. 시간초 등으로 파일이름 만들기
// 사진회전시키기
$tmpimage = imagecreatefromjpeg($url1);
$exif = exif_read_data($url1);
print '사진 정보' . $exif['Orientation'] . "<br>";
if(!empty($exif['Orientation']))
{
switch($exif['Orientation'])
{
case 8:
$url1 = imagerotate($url1,90,0);
break;
case 3:
$url1 = imagerotate($url1,180,0);
break;
case 6:
$url1 = imagerotate($url1,-90,0);
break;
}
}
//요기부분 수정했습니다.
$filename1 = compress_image($_FILES['upfile']["tmp_name"][$i], $url1, 70); //실제 파일용량 줄이는 부분
list($width, $height, $type, $attr) = getImagesize($_FILES['upfile']["tmp_name"][$i]);
echo $width."<br>";
echo $height."<br>";
echo $type."<br>";
echo $attr."<br>";
if($width > 700){
$switch_s=80;
}else{
$switch_s=100;
}
$buffer = file_get_contents($url1);
// 파일 정보 출력
echo "<h2>파일 정보</h2> <h1>
<ul>
<li>자료번호: $num</li>
<li>파일명: $name</li>
<li>확장자: $ext</li>
<li>url: {$url1}</li>
<li>filename: {$filename1}</li>
</ul> </h1>";
$re_image = new Image($filename1);
$rate=$width/$height;
if($width>$height) {
$re_image -> width(800);
$re_image -> height(800/$rate);
}
else
{
$re_image -> width(800*$rate);
$re_image -> height(800);
}
$re_image -> save();
require_once("../lib/mydb.php");
$pdo = db_connect();
// insert
try{
$pdo->beginTransaction();
$sql = "insert into mirae8440.espicfile ";
$sql .=" (parentnum, picname) " ;
$sql .=" values(?, ?) " ;
$stmh = $pdo->prepare($sql);
$stmh->bindValue(1, $num, PDO::PARAM_STR);
$stmh->bindValue(2, $newfilename1, PDO::PARAM_STR);
$stmh->execute();
$pdo->commit();
} catch (PDOException $Exception) {
$pdo->rollBack();
print "오류: ".$Exception->getMessage();
}
// // update
// try{
// $pdo->beginTransaction();
// $sql = "update mirae8440.espicfile set ";
// $sql .=" parentnum=?, picname=?, copiedfile where num=? LIMIT 1" ;
// $stmh = $pdo->prepare($sql);
// $stmh->bindValue(1, $newfilename1, PDO::PARAM_STR);
// $stmh->bindValue(2, $num, PDO::PARAM_STR);
// $stmh->execute();
// $pdo->commit();
// } catch (PDOException $Exception) {
// $pdo->rollBack();
// print "오류: ".$Exception->getMessage();
// }
}
} // end of for statement
class Image {
var $file;
var $image_width;
var $image_height;
var $width;
var $height;
var $ext;
var $types = array('','gif','jpeg','png','swf');
var $quality = 70;
var $top = 0;
var $left = 0;
var $crop = false;
var $type;
function __construct($name='') {
$this->file = $name;
$info = getimagesize($name);
$this->image_width = $info[0];
$this->image_height = $info[1];
$this->type = $this->types[$info[2]];
$info = pathinfo($name);
$this->dir = $info['dirname'];
$this->name = str_replace('.'.$info['extension'], '', $info['basename']);
$this->ext = $info['extension'];
}
function dir($dir='') {
if(!$dir) return $this->dir;
$this->dir = $dir;
}
function name($name='') {
if(!$name) return $this->name;
$this->name = $name;
}
function width($width='') {
$this->width = $width;
}
function height($height='') {
$this->height = $height;
}
function resize($percentage=50) {
if($this->crop) {
$this->crop = false;
$this->width = round($this->width*($percentage/100));
$this->height = round($this->height*($percentage/100));
$this->image_width = round($this->width/($percentage/100));
$this->image_height = round($this->height/($percentage/100));
} else {
$this->width = round($this->image_width*($percentage/100));
$this->height = round($this->image_height*($percentage/100));
}
}
function crop($top=0, $left=0) {
$this->crop = true;
$this->top = $top;
$this->left = $left;
}
function quality($quality=70) {
$this->quality = $quality;
}
function show() {
$this->save(true);
}
function save($show=false) {
if($show) @header('Content-Type: image/'.$this->type);
if(!$this->width && !$this->height) {
$this->width = $this->image_width;
$this->height = $this->image_height;
} elseif (is_numeric($this->width) && empty($this->height)) {
$this->height = round($this->width/($this->image_width/$this->image_height));
} elseif (is_numeric($this->height) && empty($this->width)) {
$this->width = round($this->height/($this->image_height/$this->image_width));
} else {
if($this->width<=$this->height) {
$height = round($this->width/($this->image_width/$this->image_height));
if($height!=$this->height) {
$percentage = ($this->image_height*100)/$height;
$this->image_height = round($this->height*($percentage/100));
}
} else {
$width = round($this->height/($this->image_height/$this->image_width));
if($width!=$this->width) {
$percentage = ($this->image_width*100)/$width;
$this->image_width = round($this->width*($percentage/100));
}
}
}
if($this->crop) {
$this->image_width = $this->width;
$this->image_height = $this->height;
}
if($this->type=='jpeg') $image = imagecreatefromjpeg($this->file);
if($this->type=='png') $image = imagecreatefrompng($this->file);
if($this->type=='gif') $image = imagecreatefromgif($this->file);
$new_image = imagecreatetruecolor($this->width, $this->height);
imagecopyresampled($new_image, $image, 0, 0, $this->top, $this->left, $this->width, $this->height, $this->image_width, $this->image_height);
$name = $show ? null: $this->dir.DIRECTORY_SEPARATOR.$this->name.'.'.$this->ext;
if($this->type=='jpeg') imagejpeg($new_image, $name, $this->quality);
if($this->type=='png') imagepng($new_image, $name);
if($this->type=='gif') imagegif($new_image, $name);
imagedestroy($image);
imagedestroy($new_image);
}
}
// 파일 압축 메소드
function compress_image($source, $destination, $quality) {
$info = getimagesize($source);
if ($info['mime'] == 'image/jpeg')
$image = imagecreatefromjpeg($source);
elseif ($info['mime'] == 'image/gif')
$image = imagecreatefromgif($source);
elseif ($info['mime'] == 'image/png')
$image = imagecreatefrompng($source);
elseif ($info['mime'] == 'image/x-ms-bmp')
$image = imagecreatefrombmp($source);
imagejpeg($image, $destination, $quality);
return $destination;
}
echo "<script> opener.document.getElementById('pInput').value='100'; </script>"; // 부모창에 100 기록해보기
echo "<script> self.close(); </script>"; // 창닫기
// header("Location:http://8440.co.kr/es/reg_pic.php?num=$num&check=$check");
?>
정리하면... 사진파일을 멀티로 올리는 것은 간단한 소스가 아닙니다. 처리하는 것이 복잡해서 나름 연구했는데도...
구현을 성공해서 사용하고 있지만, 할때마다 구현이 쉽지 않다는 것을 많이 느끼고 있습니다.
좀더 소스를 가다듬으면 업데이트되고 좀더 요약된 내용으로 만들고 싶네요.
좀더 코드를 줄이고 간명하게 코드를 정리하고 있으니, 완성되면 또 올려보고 싶습니다.
파일업로드... 너무 많이 사용하고 너무 중요한 것이니...
여러번 반복해서 습득해야 할 것 같아요~
코딩하는 모든 분들..
파일 업로드 구현에 성공하시길 기원합니다.
'IT tech Coding > php' 카테고리의 다른 글
[php + JS] 웹사이트에 첨부파일(pdf 등) 올리는 실제 프로그램 구현과정 (0) | 2023.01.08 |
---|---|
[php] 오늘 날짜 또는 특정일 기준 5일전 날짜가 설정한 일자의 범위에 있는지 확인하는 소스코드 (0) | 2022.12.21 |
[php] namespace와 use 사용에 헷갈릴때 봐야 할 자료 (1) | 2022.10.08 |
[php+html] select option value 배열에 넣고 만들어 보기 (0) | 2022.10.03 |
[php] 전화번호의 - 또는 . 문자열에서 없애는 방법 (0) | 2022.09.26 |
- Total
- Today
- Yesterday
- 엑셀보호
- 오블완
- 도면자동생성
- json파일편하게보는법
- 프로그래머생활
- 구글드라이브API
- coalesce는 한국어로 "코얼레스크" 또는 "코얼리스"
- json파일형태보기
- General error: 2031
- 테크에능한여성
- 1. #웹개발 2. #로트번호 3. #성적서보기 4. #ajax 5. #jquery 6. #php 7. #프론트엔드 8. #백엔드 9. #부트스트랩 10. #웹기능구현
- #InstallForge
- isset을 적용해야 하는 이유
- 티스토리챌린지
- 엑셀셀보호
- 엑셀입력보호
- Bootstrap 5
- 스크립트작성기초
- #프로그램설치
- 코딩효율성
- sql문장 날짜계산
- 오토핫키가이드
- 뫄프로그래밍
- 캐드자동작도
- 파이썬코드줄바꿈방법
- #파이썬패키징
- 효율적코딩방법
- 코딩튜토리얼
- ajax오류메시지
- chatGPT3.5파이썬버전
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |