티스토리 뷰

이전 포스팅을 참고하시면 더욱 좋습니다.

1. PHP MySQL Hash 함수를 사용한 파일관리 - 파일 업로드



※ 본 포스팅은 개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있음을 밝힙니다.



이제 업로드된 파일을 조회하기 위해 index.php 를 수정 해보겠습니다.



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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<html>
    <meta charset="utf-8"/>
    <title>File Manager</title>
</html>
<body>
    <?php
        @ $db = new mysqli('localhost''DB계정''DB비밀번호''DB명');
        if(mysqli_connect_errno())
        {
            echo "DB connect error";
        }
        
        $query = "select * from ftp";
        $result = $db->query($query);
        $num_result = $result->num_rows;
    ?>
    
    <table border='1' align="center">
        <thead>
            <tr>
                <th width="50">NUM</th>
                <th width="250">FILE</th>
                <th width="200">TIME</th>
                <th width="70">DOWN</th>
                <th width="50">DEL</th>
            </tr>
        </thead>
        <tbody>
            <?php
                for($i=0; $i<$num_result$i++)
                {
                    $row = $result->fetch_assoc();
                    echo "<tr>";
                    echo "<td align='center'>".$row['num']."</td>";
                    echo "<td align='left'>
                <a href='./download.php?num=".$row['num']."'>".$row['name']."</a></td>";
                    echo "<td align='center'>".$row['time']."</td>";
                    echo "<td align='center'>".$row['down']."</td>";
                    echo "<td align='center'>
                <a href='./delete.php?num=".$row['num']."'>DEL</a></td>";
                    echo "</tr>";
                }
                $db->close();
            ?>
        </tbody>
    </table>
 
    <div align="center">
        <form action="./upload.php" method="POST" enctype="multipart/form-data" />
            <input type="file" id="file" name="file" required />
            <input type="submit" value="UPLOAD" />
        </form>
    </div>
</body>
</html>


처음작성한 index.php에 table 태그와 PHP 구문을 추가한 모습입니다.


$query = "select * from ftp"; : 업로드된 파일의 정보가 있는 ftp 테이블의 모든 정보를 가져옵니다.


$result = $db->query($query); : 해당쿼리를 DB로 날립니다.


$num_result = $result->num_rows; : num_result에는 DB의 결과가 몇 개인지의 정보가 들어갑니다.


for($i=0; $i<$num_result; $i++) : 반복문을 사용해서 총 num_result 만큼 테이블이 동적으로 생성되게 합니다.


$row = $result->fetch_assoc(); : 각 반복문이 돌아갈 떄 마다 row 변수에 select로 뽑아온 데이터가 배열로 저장됩니다.


echo "<td align='center'><a href='./delete.php?num=".$row['num']."'>DEL</a></td>"; : 테이블을 동적으로 생성되는데 테이블의 내용에는 하이퍼링크 태그가 걸려있습니다.





수정된 index.php를 띄워보면 



이렇게 아까 업로드한 파일의 정보가 나타납니다.




이제 실제로 다운로드 페이지의 php 구문을 작성해 보겠습니다.





download.php



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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
 
    header("Content-type: text/html; charset=utf-8");
 
    if(!$_GET['num'])
    {
        echo "<script>alert('이상하게 접근하셨습니다;;');";
        echo "history.back();</script>";
    }
    
    @ $db = new mysqli('DB호스트''DB계정명''DB계정비밀번호''사용할DB');
    if(mysqli_connect_errno())
    {
        echo "DB connect error";
        exit;
    }
    
    $query = "select name, hash from ftp where num=".$_GET['num'];
    $result = $db->query($query);
    if(!$result)
    {
        echo "query error";
        exit;
    }
    $result = $result->fetch_assoc();
    
    $dir = "./files/";
    $filename = $result['name'];
    $filehash = $result['hash'];
    
    if(file_exists($dir.$filehash))
    {
            header("Content-Type: Application/octet-stream");
            header("Content-Disposition: attachment; filename=".$filename);
            header("Content-Transfer-Encoding: binary");
            header("Content-Length: ".filesize($dir.$filehash));
 
            $fp = fopen($dir.$filehash"rb");
            while(!feof($fp))
            {
                echo fread($fp, 1024);
            }
            fclose($fp);
            
            $query = "update ftp set down=(down+1) where num=".$_GET['num'];
            $result = $db->query($query);
            if(!$result)
            {    
                echo "down counter update error";
                exit;
            }
    }
    else
    {
            echo "<script>alert('파일이 없습니다.);";
            echo "history.back();</script>";
            exit;
    }
    $db->close();
    
?>


$query = "select name, hash from ftp where num=".$_GET['num']; : ftp 테이블에서 GET으로 넘어온 num과 일치하는 name, hash의 값을 받아오는 쿼리 입니다.


$dir = "./files/"; : 파일이 저장되었는 디렉토리명


$filename = $result['name']; : 실제 파일 이름


$filehash = $result['hash']; : 실제로 서버에 저장된 파일 이름(해시 값)


if(file_exists($dir.$filehash)) : 파일의 존재유무 검사. 없으면 else문 실행


header("Content-Disposition: attachment; filename=".$filename); : 파일이 저장할 때 이름을 지정 filename 변수의 값을 쓴다.


header("Content-Transfer-Encoding: binary"); : 바이너리 형태임을 명시해준다.


header("Content-Length: ".filesize($dir.$filehash)); : 파일의 사이즈를 명시해준다. 이렇게 하면 브라우져가 파일 다운로드시 남은 시간을 계산할 수 있다.


$fp = fopen($dir.$filehash, "rb"); : 실제로 다운할 파일을 fopen으로 연다. 바이너리 파일이므로 read binary(rb) 형태로 지정한다.


while(!feof($fp)) : 파일의 끝을 만날때까지

echo fread($fp, 1024); : 1024 바이트씩 파일을 읽어들인다.


$query = "update ftp set down=(down+1) where num=".$_GET['num']; : 파일 다운로드의 조회수를 +1 하는 쿼리문이다.


주의사항이 하나있는데 파일 다운로드가 이루어지는 download.php에 echo 와 같은 

출력함수가 사용되면  다운로드되는 파일의 바이너리에 echo의 내용이 추가됩니다. 

그러므로 download.php에는 출력함수를 사용하지 않는 편이 좋습니다.




러고 나서 다시 index.php 로 돌아와 파일명을 클릭하면


다운로드 창이 열리게 되고


다운받은 파일을 열어보면



다행이 다운로드가 잘 되었다.



그리고 다운로드 횟수도 잘 올라간다.




다음은 마지막으로 파일 삭제에 대해 포스팅 하겠습니다.






다음 포스팅 링크 입니다.

3. PHP MySQL Hash 함수를 사용한 파일관리 - 파일 삭







저작자 표시 비영리 변경 금지
신고
공유하기 링크
태그 클라우드
, ,
프로필사진

Yowu (Yu Yongwoo)

My MBTI type is ENTP. (Of course I do not believe it 100%, but I want to do that) I use Node.js to develop the backend. I use Ubuntu Linux as my development environment, and I love Vim. I am interested in open source and are keen to contribute. I have a bachelor's degree in computer science from Catholic University and now a software engineer at Plating Inc., I spent about 5 years developing and learning, and I am still interested in software development and culture. Recently, I am interested in React, Serverless structure, Domain Design Driven. Sometimes I play drums in the band.