일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ES6
- 배열
- 1064
- 동작안함
- myshortcut
- 특수문자 포함여부
- srtpos()
- implode()
- explode()
- 중간에추가
- 오류
- 일부 문자열 포함여부
- error
- jQuery
- 이걸 그렇게 쓸 줄은 몰랐지
- 문자열 포함여부
- formula
- SQL
- php
- includes()
- primary_key
- getimagesize()
- MySQL
- strpos()
- 정규식
- Excel
- 지직거림
- 서버부하
- 노션
- 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
설정을 해두어 자동으로 전달받은 문자열이 이스케이프된 것이었죠.
[PHP] addslashes(), stripslashes() 그리고, get_magic_quotes_gpc()
addslashes() 함수와 그와 반대되는 stripslashes() 함수 DB 작업을 하기 위해서 쿼리를 작성하게 되는데, 이때 DB 시스템은 작은따옴표 ' 와 큰따옴표 " 그리고 백슬래시 / 그리고, NULL byte 를 문자열을 구
zzaps.tistory.com
이걸 몰라서 한참을 혼자 해매다가 차선책으로 배열을 주고받으려 시도했습니다.
아래 두번째 시도에서 배열 주고 받기가 나오는 이유입니다...
추가
이 외에도 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로 주고 받는 방법을 찾다가 이분의 글을 찾았습니다.
POST, GET으로 배열값 받기(직렬화)
간혹 많은 량의 변수 및 데이터를 다른 페이지로 이동시켜서 처리해야할 경우가 많습니다. 이를 위해서 최...
blog.naver.com
이 분 덕분에 문자열 이스케이프도 알게 되었고 배열의 직렬화가 왜 필요한지도 알게 되었습니다. ㅠㅠ
앞서 배열을 전송하면 가장 첫번째 행인 Array만 전송되는 것을 보셨죠?
그렇기에 배열을 한 줄로 바꿔주는 직렬화 작업이 필요합니다.
물론 배열값에 따옴표가 있을 수 있으니 addslashes() 또는 urlencode() 해줍니다.
$seri_array = urlencode(serialize($array));
// 직렬화한 다음 엔코딩 해준다
이것을 POST나 GET으로 넘겨 받았다면,
다시 원래대로 바꿔줘야겠죠?
$array = unserialize(urldecode($seri_array));
// 보낼 때와 반대로 디코딩 후 직렬화 해제
맺음
배열을 주고받아 엑셀을 다운로드하는 코드를 만들었을 때,
조회되는 결과가 100 줄이 넘어가면 트래픽이 쓸데없이 크지 않겠냐는 피드백을 받았습니다.
또 SQL 쿼리문을 주고받을 때,list.php
에 나온 내용과 엑셀로 다운로드할 내용이 다르면 어쩔 거냐는 피드백도 있었습니다.
물론 나름대로 해결책을 찾아 해결했습니다만..
백엔드는 참 많은 걸 고려해야 하고 비판적으로 보는 시야도 갖춰야 하는 것 같습니다ㅎㅎ