일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 1064
- error
- formula
- 오류
- explode()
- 지직거림
- 노션
- myshortcut
- 정규식
- includes()
- 중간에추가
- ES6
- implode()
- strpos()
- 서버부하
- srtpos()
- 동작안함
- 문자열 포함여부
- SQL
- primary_key
- 이걸 그렇게 쓸 줄은 몰랐지
- 배열
- MySQL
- Excel
- getimagesize()
- 일부 문자열 포함여부
- php
- jQuery
- JavaScript
- 특수문자 포함여부
- Today
- Total
코딩짜는 일상
[PHP] 문자열, 배열 주고 받기- addslashes(), urlencode(), serialize() 본문
일단 이야기는 다음과 같습니다.
DB에서 조회한 내용들을 List로 보여주는 list.php
가 있습니다.
저는 이 내용을 EXCEL로 다운로드하고자 PHPExcel
라이브러리를 사용하는 코드를 작성하였습니다.
그리고 해당 코드가 길어서 따로 분리하고자 별도의 excel_down.php
를 만들었는데
이때 조회 조건을 GET으로 넘겨 excel_down.php
에서 DB를 조회하게 했습니다.
이 경우 list.php
의 조회 쿼리를 수정하면 excel_down.php
도 똑같이 수정해줘야 하는 단점이 있죠.
그래서 유지보수를 용이하게 하기 위해 list.php
에서 DB를 조회하고
그 결과를 excel_down.php
가 넘겨받는 방식으로 바꾸고자 했습니다.
첫번째 시도
조회 쿼리(문자열)를 주고받기
list.php
는 해당 페이지에 text box, select box 등을 두어 검색 조건을 입력받습니다.
그리고 입력받은 조건으로 DB를 조회할 쿼리를 작성하죠.
list.php
에서 DB를 조회할 때 썼던 쿼리를
excel_down.php
가 똑같이 사용하면 둘의 결과값이 같을 거라는 생각을 했습니다.
$string = " SELECT * FROM member WHERE name LIKE '김%' ORDER BY name ASC; ";
// (예시)성이 김씨인 사람을 조회하는 쿼리
다만 여기에는 문제가 하나 있습니다.
검색조건이 숫자면 상관없지만 문자라면,
작은 따옴표'
또는 큰 따옴표"
를 써서 구분해야 합니다.
'김%' // 예시의 이 부분
문제는 PHP가 이것을 단순히 문장 내용의 일부로써 인식하는 게 아니라
PHP문법의 시작 또는 종결로 인식하고 잘못된 쿼리로 인식한다는 점이죠.
만약 "SELECT * FROM member WHERE name LIKE "김%" ORDER BY name ASC;" 이렇게 작성하면
"SELECT * FROM member WHERE name LIKE " // 여기는 문자열 1
김% // 여기는 PHP 코드 또는 변수 (어느 쪽이던 에러)
" ORDER BY name ASC;" // 여기는 문자열 2로 인식합니다.
그래서 따옴표 앞에 백슬러쉬\
를 입력해 이스케이프(Escape) 해줍니다.
$escape_string = addslashes($string);
// 출력
// SELECT * FROM member WHERE name LIKE '김%' ORDER BY name ASC;
그 후 GET이나 POST로 이스케이프한 문자열을 excel_down.php
에 전달했다면,
SQL 쿼리에선 \'
를 인식하지 못하니 백슬러쉬를 전부 빼줘야겠죠.
$string = stripcslashes($escape_string);
// 출력
// SELECT * FROM member WHERE name LIKE '김%' ORDER BY name ASC;
여담이지만 처음엔 왜 전달받은 문자열에 백슬러쉬\
가 섞이는지 알지 못했습니다.
앞서 서버를 설치한 사람이 magic_quotes_gpc
설정을 해두어 자동으로 전달받은 문자열이 이스케이프된 것이었죠.
이걸 몰라서 한참을 혼자 해매다가 차선책으로 배열을 주고받으려 시도했습니다.
아래 두번째 시도에서 배열 주고 받기가 나오는 이유입니다...
추가
이 외에도 urlencode()
와 urldecode()
를 이용하는 방법dl 있습니다.
_
와 -
을 제외한 모든 문자열을 %16진수와 +기호 등으로 바꾸어주죠!
// 문자열 전달을 위해 엔코딩
$encoding = urlencode($string);
// 전달받은 내용을 문자열로 디코딩
$string = urldecode($encoding);
두번째 시도
배열을 주고 받기
Array
(
[0] => Array
(
[0] => apple
[1] => america
[2] => 1000
)
[1] => Array
(
[0] => samsung
[1] => korea
[2] => 500
)
[2] => Array
(
[0] => TSMC
[1] => taiwan
[2] => 250
)
)
위 배열을 GET 또는 POST로 주고 받은 뒤 출력하면 아래와 같습니다.
Array
원인을 자세히는 모르겠지만 아마 첫번째 행만 전달되어 Array
라고 뜨는 것 같습니다.
배열을 GET 또는 POST로 주고 받는 방법을 찾다가 이분의 글을 찾았습니다.
이 분 덕분에 문자열 이스케이프도 알게 되었고 배열의 직렬화가 왜 필요한지도 알게 되었습니다. ㅠㅠ
앞서 배열을 전송하면 가장 첫번째 행인 Array만 전송되는 것을 보셨죠?
그렇기에 배열을 한 줄로 바꿔주는 직렬화 작업이 필요합니다.
물론 배열값에 따옴표가 있을 수 있으니 addslashes() 또는 urlencode() 해줍니다.
$seri_array = urlencode(serialize($array));
// 직렬화한 다음 엔코딩 해준다
이것을 POST나 GET으로 넘겨 받았다면,
다시 원래대로 바꿔줘야겠죠?
$array = unserialize(urldecode($seri_array));
// 보낼 때와 반대로 디코딩 후 직렬화 해제
맺음
배열을 주고받아 엑셀을 다운로드하는 코드를 만들었을 때,
조회되는 결과가 100 줄이 넘어가면 트래픽이 쓸데없이 크지 않겠냐는 피드백을 받았습니다.
또 SQL 쿼리문을 주고받을 때,list.php
에 나온 내용과 엑셀로 다운로드할 내용이 다르면 어쩔 거냐는 피드백도 있었습니다.
물론 나름대로 해결책을 찾아 해결했습니다만..
백엔드는 참 많은 걸 고려해야 하고 비판적으로 보는 시야도 갖춰야 하는 것 같습니다ㅎㅎ