고수님들께 checkbox 배열 질문드립니다.
본문
아무리 생각을 해봐도 이해가 안가는 점이 있어서 질문을 드립니다.
현재 다중체크박스를 쓰는 경우가 필요합니다.
(옵션 □1 □2 □3 <= 이런 방식을 사용할 예정입니다. )
여러가지 검색을 통해본 결과.. 대부분이 아래의 방식으로 사용을 하라고 말씀을 해주십니다.
.
.
<label for="wr_1">옵션</label>
<input type="checkbox" name="wr_1[]" id="wr_1" value="1">1
<input type="checkbox" name="wr_1[]" id="wr_1" value="2">2
.
.
그런데... 여기서 문제가 발생을 합니다.
해당의 방식을 이용하면, DB에는 wr_1에 "Array" 가 찍혀버리는 문제가 ;;
과연 이문제가 어디서 발생을 하는것인가에 대한 원인을 찾기 위해 이틀간을 고민했습니다만, 정확한 원인을 찾지 못하였습니다.
해당과 동일한 증상에 관련한 질문( https://sir.kr/qa/232959 ) 이 앞서 있기에, 해당 질문에 연관된 거의 대부분의 질문은 다 찾아보았고, 고수님들의 의견도 충분히 읽어보았습니다.
(물론 구글 및 국내/해외PHP관련포럼도 다 뒤져봤습니다 ㅠㅠ)
implode를 해라, var_dump나 print_r 을 찍어서 원인을 찾아라, 소스상에는 문제가 없는데 등등... 대부분의 의견을 읽어보았습니다만...
체크박스의 네임값이 name="wr_x[]" 의 형태로 지정이 되면 write_update.skin.php 로 넘어오는 과정에서 array의 형태가 string의 형태로 변경되어버린다는 점이 문제입니다.
제가 이해하고 있는 그누보드의 처리순서를 본다면..
1. bbs/write_update.php (대부분의 과정을 처리후 DB에 값을 찍음)
2. 스킨폴더/write_update.skin.php (사용자코드를 실행하여 DB를 재처리하던 뭘하던 사용자마음)
3. bbs/write_update.php (goto_url 을 통하여 view 페이지에서 작성된 내용을 확인함)
(위의 과정에서 goto_url 부분을 주석처리하여 그 이전에 처리되는 과정의 결과를 확인하였습니다.)
그런데.. 넘어오기전 이미 wr_1의 내용은 string 으로 처리가 되어버려서... implode 안되고, var_dump 찍으면 string(5) "Array" 로 나와버리고, print_r 이야.. 뭐 당연히 Array 라는 글씨만 보여주고;;;
혹시 서버자체의 설정같은것이 문제가 있을까 싶어, 그누보드 내부가 아닌 일반적인 html 페이지로 값을 넘기면 정상적으로 배열처리가 됩니다.
(a.html 에서 b.html 로 값을 넘겨서 테스트해봄)
그렇다면.. 그누보드 내부에서는 DB에도 Array 가 찍혀버리니.. DB를 찍기전에 이미 배열이 정상처리가 안된다는 결론에 도달해서 bbs/write_update.php 를 뒤져서 관련 소스를 변경해 보았습니다.
제일 유력한 놈이 이놈 (settype이 string??) 인거 같아서.. 아래소스의 if 문을 주석처리 해봐았습니다.
for ($i=1; $i<=10; $i++) {
$var = "wr_$i";
$$var = "";
if (isset($_POST['wr_'.$i]) && settype($_POST['wr_'.$i], 'string')) {
$$var = trim($_POST['wr_'.$i]);
}
}
어... 배열이 정상적으로 넘어옵니다. 그런데 문제는 wr_x 와 관련된 내용이 DB에 찍히질 않아버리네요;;
여기까지가 제가 이틀간 고민한 내용입니다.
물론 해당의 방식을 피해서 변수명을 바꾸고 쓰던, 별도의 자바스크립트나 기타의 방식을 통해 별도로 처리를 하던 .. 처리에 대한 내용은 저도 모르는 바는 아닙니다.
다만, 이게 왜 이렇게 안되는것인가? 라는 궁금증이 사람을 미치게 만들더라구요 ㅠㅠ
앞에 사설이 너무 길어졌네요. 죄송합니다 ㅠㅠ 질문을 정리하도록 하겠습니다.
1. name="wr_x[]" 의 배열처리가 안되는 것은 제가 지목한 유력용의자가 원인인것이 맞나요?
2. 유력용의자의 소스를 그냥 말로 한다면 조금 이해가 안되는게..
"$_POST['wr_x'] 변수가 존재하고, $_POST['wr_x'] 변수의 타입을 string 으로 만든다면..." 인거 같은데
사실상 조건문은 "$_POST['wr_x'] 변수가 존재하고, $_POST['wr_x'] 변수의 타입이 string 이라면..." 이 맞는게 아닌가요?
(settype 이 아닌 gettype($_POST['wr_'.$i]) == 'string' 이 더 맞는게 아닌지..)
3. 유력용의자의 소스를 변경한다면 제가 미처 생각하지 못한 문제가 생길려는지요...?
4. 유력용의자를 변경하여 name="wr_x[]" 의 형태를 쓸수 있게 만들수는 없는지요...?
5. 유력용의자가 아닌 기타의 이유로 인해 이러한 문제가 발생할수 있는지요...?
(니가 멍청해서 서버설정은 살펴보지도 않았잖아 같은 ...)
서버는 현재 APACHE : 2.4.27 (Win64) / PHP : 7.1.8 / Mysql : 5.7.20 입니다.
개인서버라서 설정파일은 전부 커스터마이징이 가능합니다.
-------------------------------------------------------------------------------------------------------
모든 테스트는 하나도 손대지 않은 순정 그누보드를 기반으로 하였습니다.
지식이 짧아 많은 고수님들의 조언이 필요합니다.
조그마한 도움이라도 주시면 감사하겠습니다 ㅠㅠ
답변 1
체크박스를 어떤용도로 사용하실지에 대한
논리적인 정리가 중요할겁니다.
일을 처리하는 사람 입장에서는 그너 저거나 라고 볼수있지만
먼저 그누보드의 특징인
wr_1[] 로 값을 넘기면 1개를 넘겨도
값을 저장할때
$_REQUEST/$_POST/$_GET 등으로 수신하면
wr_1 은 배열로 넘어갑니다.
sql이 저장될때 배열은 Array 라는 타입값 저장 혹은 오류를 발생시킬수밖에 없습니다.
그러면
wr_1에는 어떤형태의 값이 저장되어야 하나요?
보통 체크박스는 멀티값을 저장하기에
wr_1 = "사과|배|포도"의 선택된 값들이 저장되고 싶어합니다.
그런데 넘기는 값 wr_1 과
저장되는 wr_1의 구분이 어려워집니다.
그래서 흔히들 wr_1 은 sql 을 처리할때 사용하고(실제 table 의 필드도 wr_1 이죠)
에디팅폼인 wr_1은 wr1[] 과 같은 구조로 약간 변형해서들 많이 사용합니다.
넘기기 전이에 결합하여 wr_1 으로 string을 만들어 넘기던지 (Javascript로)
넘겨받아서 wr1 을 count(wr1)으로 loop로 결합시키던지
등의 방법을 선택하시면 해결될겁니다.
이미 많이 와 있는 상태에서 개념만 정리하면 해결하실듯 하여 개념만 설명드립니다.