[PHP] JSON 데이터 화면에 출력하기[PHP] JSON 데이터 화면에 출력하기

Posted at 2020. 1. 16. 13:53 | Posted in PHP




참고 : https://kdevkr.github.io/archives/2018/understanding-http-content-types/




■ JSON 데이터 JSON 타입으로 변환해서 처리하기




PHP 상에서 API를 제공하는 경우 그 형식이 JSON 타입일때


단순히 TEXT 형태로 JSON 데이터를 나열하는것이 아니라.


Content-Type의 헤더를 :application/json으로 페이로드와 함께 HTTP 요청을 하게 되면


서버가 JSON 타입으로 변환해서 처리한다.




  Content-Type:application/json; 을 설정한 경우


# 소스코드

<?php

header( "Content-Type:application/json;charset=UTF-8" );


$json = '{

    "SlayerS_BoxeR" : {

          "name" : "임요환"

        , "species" : "테란"

        , "birthday" : "1980-09-04"

        , "team" : "SK텔레콤 T1"

    }

    , "YellOw" : {

        "name" : "홍진호"

      , "species" : "저그"

      , "birthday" : "1982-10-31"

      , "team" : "KTF 매직엔스"

    }

    , "Nal_rA" : {

        "name" : "강민"

      , "species" : "프로토스"

      , "birthday" : "1982-03-15"

      , "team" : "KTF 매직엔스"

    }

}';

echo $json;

?>




# 출력결과





 Content-Type:text/html인경우



# 소스코드

<?php

// @breif Content-Type 주석처리

// header( "Content-Type:application/json;charset=UTF-8" );


$json = '{

    "SlayerS_BoxeR" : {

          "name" : "임요환"

        , "species" : "테란"

        , "birthday" : "1980-09-04"

        , "team" : "SK텔레콤 T1"

    }

    , "YellOw" : {

        "name" : "홍진호"

      , "species" : "저그"

      , "birthday" : "1982-10-31"

      , "team" : "KTF 매직엔스"

    }

    , "Nal_rA" : {

        "name" : "강민"

      , "species" : "프로토스"

      , "birthday" : "1982-03-15"

      , "team" : "KTF 매직엔스"

    }

}';

echo $json;

?>




# 출력결과



위 두개의 결과처럼 똑같이 JSON 데이터를 화면에 뿌려주지만


어떻게 인식하고 처리하는지 여부를 한눈에 확인할 수 있다.









Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[Flow.Txt] 윈도우7 종료 우분투로 이전[Flow.Txt] 윈도우7 종료 우분투로 이전

Posted at 2020. 1. 16. 10:28 | Posted in Flow.Txt





Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[Flow.Txt] 개발자 이지만 네이버 웨일을 사용중입니다.(2020.01.08)[Flow.Txt] 개발자 이지만 네이버 웨일을 사용중입니다.(2020.01.08)

Posted at 2020. 1. 8. 11:16 | Posted in Flow.Txt



업무특성상 아무래도 여러 브라우저를 열고 테스트를 하는데.


네이버 디자인이 변경되었네 라고 넘어갔다가.


어라 왜 다른지 하고 보던중에 알게 되었다.





네이버 웨일만 달랐던 거였다...


이런....


앞으로 네이버 메인페이지 디자인 변경 반응에 대한 테스트는 웨일에서 진행하는 걸려나?







기본적으로 요즘 개발자라면...


요즘 개발자들이 가장 많이 사용하는 구글 크롬


나처럼 고인물들이나 좋아하는 모질라 파이어 폭스가 기본 브라우저일 것이다.

(거기에 최종적으로 확인을 위한 마이크로 소프트의 인터넷 익스플러 까지)



그래서 네이버에서 브라우저가 나왔다고 했을때.


그닥 새로운 엔진을 사용한것도 아니라 구글 크로미움 기반이었으니


관심도 없었지만, 최근 업데이트로 인해 조금 관심을 가지고 사용해 보기 시작했다.






위와 같이 번역을 위한 파파고...


그리고 업무중 가벼운 눈팅을위한 옴니 테스킹 기능


이것때문에 라도 한번 설치를 해보았던건데...


이것들이 크게 쓸만해서 서포트 브라우저를 구글 크롬에서 네이버 웨일로 갈아타게 되었다.








특히나 컴퓨터에서 보는 화면과 모바일에서 보는 화면이 다르고...


파폭으로 개발하고, 크롬으로 확인하는 나같은 놈한테...


서포트 해주는 기능이 많은건 확실히 좀 편하달까?




※ 개인 사용율


1위. 파이어 폭스 - 이유 : 개발자 도구, 웹 표준에 가장 가깐운 브라우저


2위. 웨일 - 이유 : 옴니 테스킹, 모바일창, 크로미움 기반 브라우저 테스트용


3위. 크롬 - 이유 : 세상에서 제일 많이 쓰는 브라우저




이런것 같다.


그치만 네이버 웨일은 결국 내 사용율 1위는 불가능 할거다...


일단 기본검색이 구글이 아니라 네이버라는 가장 큰 단점...


그리고 너무도 익숙하고 편한 파이어 폭스의 개발자 도구...

(아 나도 고일때로 고였어... 넷스케이프 만세...)




2019년은 네이버가 국내 전자상거래 기업 1위, 웹툰 1위


그리고 라인과 야후 재팬의 합병...


손정의님의 투자등...


YouTube의 등장으로 검색시장도 많이 빼앗기고 있다지만.


요즘 네이버는 여전히 변화에 잘 적응하는 기업이라는 생각이 든다.







Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[Utility] Doxygen을 이용한 프로젝트 및 개발 코드 관리[Utility] Doxygen을 이용한 프로젝트 및 개발 코드 관리

Posted at 2020. 1. 3. 17:07 | Posted in Developer Tool



참고 : https://www.slideshare.net/arload/doxygen-33932243




■ 독시젠(Doxygen)이란?





· 독시젠은 소프트웨어 레퍼런스 문서 생성기 이다.


· 독시젠 주석 문법을 사용함으로서 설명서 자체가 코드로 되어 있기에 문서와 코드를 상호 참조 할 수 있다.




처음 코딩을 시작할 때붜 독시젠을 사용함으로서 나중을 위한 주석 작성을 하게 되며,


이후 간단한 작업을 거쳐 손쉽게 레퍼런스 문서를 획득할 수 있다.








■ 윈도우즈(Windows)에서 독시젠 설치 하기




제일먼저 http://www.doxygen.nl/download.html 접속하여 윈도우용 독시젠을 다운로드 받는다.





Downloads 페이지에서 doxygen-버전NO-seup.exe 파일을 다운로드 받는다.








■ 독시젠 주석 작성법




#01. 메인 페이지 주석 예시


    /**

     * @mainpage       메인페이지 제목

     * @brief              간략한 설명

     * @details           자세한 설명

    */





#02. 파일 페이지 주석 예시


    /**

     * @file                파일 클래스 이름

     * @brief              간략한 설명

     * @details           자세한 설명

     */





#03. 패키지 주석 예시


    /**

     * @namespace       org.nhnnext

     * @brief                패키지 간략 설명

     * @details             패지키 자세히 설명

     */

    package org.nhnnext;





#04. 클래스 주석 예시


    /**

     * @brief           클래스 간략 설명

     * @details         클래스 자세히 설명

     * @author         이름, 이메일

     * @date            YYYY-MM-DD

     * @version        0.0.1

     */

     class 클래스_이름 extends 자식_클래스_이름 {

         /* do nothing */

     }





#05. 메서드 주석 예시


    /**

     * @brief            메서드 간략 설명

     * @details          메서드 자세히 설명

     * @param          args 콘솔 파라미터

     * @returnCnt      프로그램 상태

     *

     * @bug              메모리 누수 있음

     * @todo             버그 해결 해야함

     * @Exception      StringIndexOutOfRangeException

     *

     * @see               NewClass

     * @see               http://magic.wickedmiso.com/

     */

    public static int main(String[] args)

    {

        ...

        retrun( status );

    }





#06. 메타 데이터 주석 예시


    /**

     * @mainpage    프로그램의 전체 개요 등을 설명한다.

     * @section        프로그램의 개요 별로 설명한다.

     * @versions      프로그램 버전을 설명한다.

     * @breif           간략한 설명을 쓸 때 사용한다.

     * @details        자세한 설명을 쓸 때 사용한다.

     * @files           파일 이름을 구별할 때 사용한다.

     * @author        작성자 이름을 나타낼 때 사용한다.

     * @date           작성날짜를 나타낼 때 사용한다.

     * @param        함수 파라미터를 설명한다.

     * @return         함수 리턴값을 설명한다.

     * @exeception  예외 처리를 설명한다.

     * @throws        throw하는 객체나 변수 등을 설명한다.

     * @see            참고할 함수나 페이지를 지정한다.

     * @todo          해야할 일에 대해서 따로 리스트를 생성한다.

     * @bug           버그에 대해서 따 리스트를 생성한다.

     * @code          중요코드를 설명할때 시작 지점을 가리킨다.

     * @endcode     중요코드를 설명할때 종료 지점을 가리킨다.

     */











■ 독시젠 설정 및 사용방법




#01. Wizard > Project


 ① 프로젝트 루트 폴더를 지정한다.

 ② 프로젝트 이름과 버전을 지정한다.

 ③ 소스 파일이 있는 폴더를 지정한다.

 ④ 모든 하위 폴더를 재귀적으로 스캔한다.

 ⑤ 독시젠 문서를 생성할 폴더를 지정한다.




#02. Wizard > Mode


 ① 각 함수마다 사용한 함수로의 링크를 생성한다.

 ② 진행한 프로젝트의 개발 언어를 선택한다.




#03. Wizard > Output


 ① 문서 왼쪽에 탐색 트리를 보여준다.




#04. Wizard > Diagrams


 ① 소스간의 관계를 Graphviz로 표현해 준다.




#05. Expert > Project


 ① 출력 결과에 쓰여질 언어를 한국어-영어 같이 사용으로 선택한다.

 ② 항상 상세 정보를 보여준다.

 ③ 소멸자와 상속자를 제외한 상속된 모든 멤버를 보여준다.




#06. Expert > Build


 ① 소스코드의 모든 요소가 문서화 대상이 된다.

 ② 클래스 내의 모든 private 멤버가 문서화 대상이 된다.

 ③ 클래스 내의 모든 static 멤버가 문서화 대상이 된다.




#07. Expert > Source Browser


 ① 함수 설명시 함수 코드를 보여준다.




#08. Expert > Dot


 ① 클래스 상속구조 다이어그램을 그린다.

 ② 다이어 그램을 UML 형식으로 그린다.




#09. Expert > Dot


 ① dot_path의 지정 경로에 Graphviz 이미지가 생성된다.




#10. Run


 ① 독시젠을 가동시켜 문서를 생성한다.

 ② Show Html output 버튼이 활성화되면 독시젠 문서 생성이 완료되었다.





#11. Show Html Output



모든 작업이 완료되면 위와같이.


HTML 형태로 진행한 프로젝트의 문서화가 이루어 진다.





Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[Flow.Txt] 첫 은행 적금 만기(2019.12.27)[Flow.Txt] 첫 은행 적금 만기(2019.12.27)

Posted at 2020. 1. 2. 18:53 | Posted in Flow.Txt





2년간 100만원씩...


적금을 부었던 통장이 만기가 되었다.







30살 넘은 직장인이 만기가 된 통장이 하나뿐이라는게...


어찌보면 참 부끄럽지만...


사회 생활 시작할 때부터 빚부터 지고 시작한걸 다 마무리 하고...


2000만원이 조금 넘는 돈이 통장에 들어왔다.


온전히 집을 사는데 돈이 들어가는데 써버ㄹ리게 되었지만...


ㅋㅋ 이게 어디냐...






Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[JavaScript] 파일업로드시 용량 검사하기[JavaScript] 파일업로드시 용량 검사하기

Posted at 2019. 12. 26. 11:25 | Posted in JavaScript & jQuery/JavaScript



참고 : https://zzznara2.tistory.com/617




■ 파일업로드시 용량 검사하기




# 소스코드

<html>

<head>

<title>:: JAVASCRIPT 파일업로드 ::</title>

<script type="text/javascript">

    function imgFileUpload() {


        /// @brief 업로드할 이미지의 크기( Byte )를 구해온다.

        const imgSize = document.getElementById("personImg").files[0].size;


        /// @brief 업로드할 이미지 사이즈의 크기는 4MB 이하로 설정

        const maxSize = 4 * 1024 * 1024;


        /// @brief 이미지

        if(imgSize > maxSize) {


            alert("첨부할 수 있는 이미지 파일은 4MB 이하여야 합니다.");

            document.getElementById("personImg").focus();

            return false;


        } else {


            alert("업로드 가능한 이미지입니다.");


        }

    }

</script>

</head>

<body>

<form enctype="multipart/form-data" id="upFrm" method="post">

    <input type="file" id="personImg" name="personImg" value=""/>

    <input type="button" onClick="imgFileUpload();" value="업로드"/>

</form>

</body>

</html>




# 출력결과 - 수정예정






관련문서 : [JavaScript] 파일업로드시 확장자 검사하기







Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[Flow.Txt] 나이가 들어 변했다는 표현에 대해서(2019.12.23)[Flow.Txt] 나이가 들어 변했다는 표현에 대해서(2019.12.23)

Posted at 2019. 12. 24. 06:16 | Posted in Flow.Txt





요즘 한창 재미있게 보고 있는 드라마가 하나 있다.


얼마전 SBS에서 방영한 스토브리그...


왠지 재미 있을것 같다라는 냄새가 강하게 나서,


그냥 아무런 사전정보 없이 보게 되었다.




그러던중 지난 2019.12.20 방영된 4회 분량에서...


고세혁 팀장의 비리가 밝혀지는 부분에서


좀 계속 와닿는게 있어서 캡쳐를 해본다.






#scene01. 해고 징계를 받고 있는 고세혁 팀장





권경민 상무 : 추잡하게 돈은 왜 받아요.

고세혁 팀장 : 아니 많은 돈(오천만원)도 아니고...

권경민 상무 : 많이 받았음면 내가 잘했다고 칭찬이라도 해주지

                  왜 적은 돈을 받고 이렇게 치사한 소리를 듣습니까

                  마음아프게 아 진짜~

                  나가요





돈 오천만원이 적은돈이라니...


물론 야구선수출신이었고 한 구단의 프렌차이즈 선수였던 사람에게는 그리 큰돈이 아니게 느껴질 수 있겠지만.


뭐랄까... 


또다른 의미로라면, 그정도 돈이면 내가 힘좀 써보겠다 라는 의미로 받았을 돈이었을 텐데.


적은 돈이었을까?


하는 내 1년치 회사 연봉과 맞먹는 금액을 참 그리도 가벼이 말하는거에서...


무언가 씁쓸함이 느껴지기도...







#scene02. 떠나는 고세혁 팀장과 잠시 과거 이야기를 하는 이세영 팀장




사실 더 생각나는 장면은 이장면이다.

(뭐 위에도 좀 크게 와닿았던건 사실인지라...)



고세혁 팀장 : 그땐 뭐 젊었으니까?

이세영 팀장 : 아니요 정의로웠으니까!

                  그때 야구 재미있었죠





짐을 정리하고 떠나는 고세혁 팀장과 운영팀 이세형 팀장의 대화에서...


이세영 팀장이 과거 고세혁 팀장의 선수시절에 보였던.


양심적인 모습을 이야기 하자.


고세혁은 자신은 젊었으니까? 라는 대답을 한다.


여기서 이세영은 정의로웠으니까! 라는 말로 화답한다.



사람은 나이가 들고 경험이 쌓이면 영악해 지는것은 어쩔 수 없는 모습이기도 하다.


그렇다고 선을 위반하는 행위를 그것이 나이들었기에 어쩔 수 없다라는 모습...


개인적으로 참 되기 싫은 모습이다.



변할 수도 있고 흔들릴 수도 있다...


그렇다고 그것을 젊었기 때문에, 혹은 나이들었기 때문에라는 핑계는...


살면서 하지 않기를 바라는 내 모습을 그려 보았다.







아마도 정주행 할 것 같은 드라마이다.


그리고 완결도 되지 않은 상태에서.


내 외장하드에 영구보존이 결정된 드라마 이기도 하다.



세상 모든게 열정하나로 이루어 지는것은 아니지만...


그래도 뜨거운 것이 남아있다면...


이 드라마는 무조건 빠질 수 밖에 없는 그런 드라마 이지 않을까?






Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[API] Bittly API v4 연동, 단축 URL 생성하기 - PHP[API] Bittly API v4 연동, 단축 URL 생성하기 - PHP

Posted at 2019. 12. 23. 19:34 | Posted in API/Bitly




참고 : https://stackoverflow.com/questions/55681871/how-to-shorten-url-using-php-bitly-v4?answertab=active#tab-top





■ Bittly API v4 토큰 발급받기




① 먼저 Bittly 계정이 필요하다.

    가지고 있는 Bittly계정이 존재하지 않다면 https://bitly.com/a/sign_up 페이지에 접속하여 계정을 생성한다.






② 가입된 계정이 준비되었다면 https://app.bitly.com/ 페이지에 접근한다.(로그인 되어 있지 않은 상태로 접근 불가)

    자신의 계정정보가 노출되는 페이지에 접속 했다면 상단 우측의 메뉴 항목을 클릭한다.






③  자신의 계정을 클릭한다.






④ Generic Access Token 카테고리를 클릭한다.






패스워드를 입력하고 클릭하면 화면 하단에 GENERATE TOKEN 버튼이 나타난다.

     GENERATE TOKEN 버튼을 클릭한다.





토큰이 발급된 것을 확인 할 수 있다.










■ Bittly API v4 연동하여 짧은 URL 생성하기





PHP에서 Bittly API와 연동하여 짧은 URL을 생성해 보도록 하겠다.


PHP의 cURL을 사용하였다.




# 소스코드

<?php


/// @brief URI 값 생성

$getUri = "num=1&lang=ko";


/// @brief 접근할 URL 주소 생성

$longUrl = "http://도메인주소?".$getUri;


/// @brief  생성한 URL을 $data['long_url']에 담고 JSON 형태로 변환한다.

$data['long_url'] = $longUrl;

$payload = json_encode($data);


/// @brief BITLY API 접근 URL

$bitApi = "https://api-ssl.bitly.com/v4/bitlinks";


/// @brief 발급받은 BITLY API 토큰

$bitToken = "발급받은 API 토큰 값";


/// @brief CURL 사용

$cURL = curl_init();

curl_setopt($cURL, CURLOPT_URL$bitApi);

curl_setopt($cURL, CURLOPT_CUSTOMREQUEST, "POST");

curl_setopt($cURL, CURLOPT_POSTFIELDS$payload);

curl_setopt($cURL, CURLOPT_RETURNTRANSFER, TRUE);

curl_setopt($cURL, CURLOPT_HTTPHEADER, array(

  "Authorization:Bearer ".$bitToken         // Bearer { $token } (공백필수)

, "Content-Type:application/json"

, "Content-Length:".strlen($payload)

)

);


/// @brief 결과값 조회

$result = json_decode(curl_exec($cURL), TRUE);


echo "<pre>";

print_r($result);

echo "</pre>";


/// @brief 출력결과

if(isset($result['link']) == 1) {

echo $result['link'];

}

?> 




# 출력결과







'API > Bitly' 카테고리의 다른 글

[API] Bittly API v4 연동, 단축 URL 생성하기 - PHP  (0) 2019.12.23

Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[Flow.Txt] 동기가 있는 기업, 그리고 아싸(2019.12.20)[Flow.Txt] 동기가 있는 기업, 그리고 아싸(2019.12.20)

Posted at 2019. 12. 23. 06:00 | Posted in Flow.Txt



현재 재직중인 회사는 중소기업이다.

(여기저기 사업자 나눠논걸 보면 중견기업에 아슬아슬하게 미칠것 같지만)


암튼 나는 이곳에 32이란 나이의 어린 과장(?)으로 입사하였다.




회사에는 동기제도가 있고...


영어이름을 쓰며, 직급을 부르지 않는체제였다.

(과장을 달았는데 왜 과장이라 불리질 못하누... ㅠ.ㅠ)




암튼 크리스마스를 앞둔 어느 금요일...


사내 메신저중 동기들 방에 갑자기 알림이 쏟아졌다.






ㅋㅋㅋㅋㅋㅋ


다른 사람 사진을 참....







어쩌다 보니 인기 자랑 글이 된것같지만...


천성이 아싸이다...


움직이는고 활동하는건 엄청 좋아하지만,


피곤해지고 지치는건 정말 싫어하는





그저 어쩌다 왠지 인기 있는것 같은 일이 생기니까 한번 적어보는...


그치만 회사생활중 5일중 한번은...


주변 사람덕분에 웃을 수 있는거는 좋은일이라고...


그리고 이게 딱 적당한 일이라는 생각이 들며 글을 마무리 해본다.




멋진 짤을 만들고 공유해준 동기들에게 감사를~ ㅎㅎ







Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[JavaScript] 체크박스 전체 선택 - Sample[JavaScript] 체크박스 전체 선택 - Sample

Posted at 2019. 12. 19. 11:34 | Posted in JavaScript & jQuery/JavaScript




■ 전체영역을 선택하는 체크박스 샘플 코드




# 소스코드

<html>

<head>

<title>:: JavaScript 체크박스 ::</title>

<script type="text/javascript">


    // @command 전체선택

    function allCheckedBox(obj) {


        // @brief 선택한 체크박스의 클래스 명칭을 가져온다.

        const termClassobj.getAttribute("class");


        // @brief 선택한 클래스명과 같은 클래스의 갯수

        console.log(document.getElementsByClassName(termClass).length);


        Array.prototype.forEach.call(document.getElementsByClassName(termClass), function(element, index, array) {


            // @brief 엘리먼트의 값 출력

            console.log(element.value);


            // @brief 선택한 클래스의 첫번째 checkbox의 상태가 체크가 되있는 경우

            if(document.getElementsByClassName(termClass)[0].checked == true) {


                // @brief 같은 클래스명을 가진 모든 checkbox의 상태를 선택 완료 처리 한다.

                element.checked = true;

            }


            // @brief 선택한 클래스의 첫번째 checkbox의 상태가 체크가 해제된 경우

            else {


                // @brief 같은 클래스명을 가진 모든 checkbox의 상태를 선택 해제 처리 한다.

                element.checked = false;

            }

        });

    }


    // @command 개별 선택이 이루어진 경우에 전체값 체크의 예외처리

    function eachCheckedBox(obj) {


        // @brief 선택한 체크박스의 상태가 선택해제인 경우

        if(obj.checked == false) {


            // @brief 선택한 체크박스의 클래스 명칭을 가져온다.

            const termClass = obj.getAttribute("class");


            // @brief 첫번째 checkbox의 상태가 체크가 되어있는경우

            if(document.getElementsByClassName(termClass)[0].checked == true) {


                // @brief 첫번째 checkbox의 상태를 체크해제한다.

                document.getElementsByClassName(termClass)[0].checked = false;

            }

        }

    }

</script>

</head>

<body>

     <h1>■ 체크박스 전체 선택 - SAMPLE</h1>


    <!-- @brief 전체의 선택의 경우 반드시 index값이 0인 첫번째에 위치해야 한다. -->

    <label>

        <input type="checkbox" class="neHeros" value="" onChange="allCheckedBox(this);"/>&nbsp;전체

    </label>


    <!-- @brief 개별선택될 체크박스들 -->

    <label>

        <input type="checkboxclass="neHeros" value="D" onChange="eachCheckedBox(this);"/>&nbsp;데몬헌터

    </label>

    <label>

        <input type="checkboxclass="neHeros" value="W" onChange="eachCheckedBox(this);"/>&nbsp;워든

    </label>

    <label>

        <input type="checkboxclass="neHeros" value="K" onChange="eachCheckedBox(this);"/>&nbsp;키퍼 오브 더 그루브

    </label>

    <label>

        <input type="checkboxclass="neHeros" value="P" onChange="eachCheckedBox(this);"/>&nbsp;프리시스 오브 더 문

    </label>

</body>

</html>




# 출력결과







Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기