2010-04-01 2 views
0

나에게 표준적인 실행처럼 보이지 않으므로 여기에서 무슨 일이 일어나는지 확실하지 않습니다. 하지만 기본적으로 사용자가 코드 스 니펫을 제출할 수 있도록하는 기본적인 데이터베이스가 있습니다. 제출을 위해 최대 5 개의 태그를 제공 할 수 있습니다.PHP가 아포스트로피를 삽입하지 않아야하는 곳

지금은 아직 배우지 않으므로 이것이 분명한 경우 나에게 용서해주세요. 이 코드의 지루한 군침에 대한

function submitform() 
    { 
    $this->load->helper(array('form', 'url')); 

    $this->load->library('form_validation'); 
    $this->load->database(); 

    $this->form_validation->set_error_delimiters('<p style="color:#FF0000;">', '</p>'); 

     $this->form_validation->set_rules('title', 'Title', 'trim|required|min_length[5]|max_length[255]|xss_clean'); 
     $this->form_validation->set_rules('summary', 'Summary', 'trim|required|min_length[5]|max_length[255]|xss_clean'); 
     $this->form_validation->set_rules('bbcode', 'Code', 'required|min_length[5]'); // No XSS clean (or <script> tags etc. are gone) 
     $this->form_validation->set_rules('tags', 'Tags', 'trim|xss_clean|required|max_length[254]'); 

    if ($this->form_validation->run() == FALSE) 
    { 
     // Do some stuff if it fails 
    } 
    else 
    { 
     // User's input values 
     $title = $this->db->escape(set_value('title')); 
     $summary = $this->db->escape(set_value('summary')); 
     $code = $this->db->escape(set_value('bbcode')); 
     $tags = $this->db->escape(set_value('tags')); 

     // Stop things like <script> tags working 
     $codesanitised = htmlspecialchars($code); 

     // Other values to be entered 
     $author = $this->tank_auth->get_user_id(); 

     $bi1 = ""; 
     $bi2 = ""; 

     // This long messy bit basically sees which browsers the code is compatible with. 
     if (isset($_POST['IE6'])) {$bi1 .= "IE6, "; $bi2 .= "1, ";} else {$bi1 .= "IE6, "; $bi2 .= "NULL, ";} 
     if (isset($_POST['IE7'])) {$bi1 .= "IE7, "; $bi2 .= "1, ";} else {$bi1 .= "IE7, "; $bi2 .= "NULL, ";} 
     if (isset($_POST['IE8'])) {$bi1 .= "IE8, "; $bi2 .= "1, ";} else {$bi1 .= "IE8, "; $bi2 .= "NULL, ";} 
     if (isset($_POST['FF2'])) {$bi1 .= "FF2, "; $bi2 .= "1, ";} else {$bi1 .= "FF2, "; $bi2 .= "NULL, ";} 
     if (isset($_POST['FF3'])) {$bi1 .= "FF3, "; $bi2 .= "1, ";} else {$bi1 .= "FF3, "; $bi2 .= "NULL, ";} 
     if (isset($_POST['SA3'])) {$bi1 .= "SA3, "; $bi2 .= "1, ";} else {$bi1 .= "SA3, "; $bi2 .= "NULL, ";} 
     if (isset($_POST['SA4'])) {$bi1 .= "SA4, "; $bi2 .= "1, ";} else {$bi1 .= "SA4, "; $bi2 .= "NULL, ";} 
     if (isset($_POST['CHR'])) {$bi1 .= "CHR, "; $bi2 .= "1, ";} else {$bi1 .= "CHR, "; $bi2 .= "NULL, ";} 
     if (isset($_POST['OPE'])) {$bi1 .= "OPE, "; $bi2 .= "1, ";} else {$bi1 .= "OPE, "; $bi2 .= "NULL, ";} 
     if (isset($_POST['OTH'])) {$bi1 .= "OTH, "; $bi2 .= "1, ";} else {$bi1 .= "OTH, "; $bi2 .= "NULL, ";} 

     // $b1 is $bi1 without the last two characters (,) which would cause a query error 
     $b1 = substr($bi1, 0, -2); 
     $b2 = substr($bi2, 0, -2); 

// :::::::::::THIS IS WHERE THE IMPORTANT STUFF IS, STACKOVERFLOW READERS:::::::::: 

     // Split up all the words in $tags into individual variables - each tag is seperated with a space 
     $pieces = explode(" ", $tags); 
     // Usage: 
     // echo $pieces[0]; // piece1 etc 

     $ti1 = ""; 
     $ti2 = ""; 

     // Now we'll do similar to what we did with the compatible browsers to generate a bit of a query string 
     if ($pieces[0]!=NULL) {$ti1 .= "tag1, "; $ti2 .= "$pieces[0], ";} else {$ti1 .= "tag1, "; $ti2 .= "NULL, ";} 
     if ($pieces[1]!=NULL) {$ti1 .= "tag2, "; $ti2 .= "$pieces[1], ";} else {$ti1 .= "tag2, "; $ti2 .= "NULL, ";} 
     if ($pieces[2]!=NULL) {$ti1 .= "tag3, "; $ti2 .= "$pieces[2], ";} else {$ti1 .= "tag3, "; $ti2 .= "NULL, ";} 
     if ($pieces[3]!=NULL) {$ti1 .= "tag4, "; $ti2 .= "$pieces[3], ";} else {$ti1 .= "tag4, "; $ti2 .= "NULL, ";} 
     if ($pieces[4]!=NULL) {$ti1 .= "tag5, "; $ti2 .= "$pieces[4], ";} else {$ti1 .= "tag5, "; $ti2 .= "NULL, ";} 

     $t1 = substr($ti1, 0, -2); 
     $t2 = substr($ti2, 0, -2); 

     $sql = "INSERT INTO code (id, title, author, summary, code, date, $t1, $b1) VALUES ('', $title, $author, $summary, $codesanitised, NOW(), $t2, $b2)"; 
     $this->db->query($sql); 

      $this->load->view('subviews/template/headerview'); 
      $this->load->view('subviews/template/menuview'); 
      $this->load->view('subviews/template/sidebar'); 

      $this->load->view('thanksforsubmission'); 
      $this->load->view('subviews/template/footerview'); 
    } 
    } 

죄송합니다 :

여기이 모든 작업 (거기에 일부 CodeIgniter의 특정 기능이있을 수 있습니다)하게 PHP 스크립트입니다. 나는 아마도 거기에 몇 가지 나쁜 습관을 가지고 있음을 알고 있습니다.

은 (그것이 오류가 발생 전혀 조회되지 않음)처럼 출력 쿼리 모습입니다 :

A Database Error Occurred 
Error Number: 1136 

Column count doesn't match value count at row 1 

INSERT INTO code (id, title, author, summary, code, date, tag1, tag2, tag3, tag4, tag5, IE6, IE7, IE8, FF2, FF3, SA3, SA4, CHR, OPE, OTH) VALUES ('', 'test2', 1, 'test2', 'test2 ', NOW(), 'test2, test2, test2, test2, test2', NULL, NULL, 1, 1, 1, 1, 1, 1, 1, NULL) 

당신은 (NOW 후 비트에서 볼 수), 'TEST2, TEST2 , test2, test2, test2 '- 나는 아포스트로피로 모든 것을 넣지 않았다. 내가 그랬어?

내가 이런 식으로 그 라인의 각을 넣어 할 수있는 : 단일 약 $ 따옴표 조각

if ($pieces[0]!=NULL) {$ti1 .= "tag1, "; $ti2 .= "'$pieces[0]', ";} else {$ti1 .= "tag1, "; $ti2 .= "NULL, ";} 

[0] 등 -하지만 내 문제는 사용자 만 입력하면이 좀 실패하다 4 태그, 또는 3, 또는 뭐든간에.

죄송합니다. 역사상 최악의 문구가 있다면 죄송합니다.하지만 두뇌가 약화되었습니다.

도움 주셔서 감사합니다.

+0

음 ... 코드를 살펴볼 수 없으므로 지금 떠날 것입니다. 그러나 "테스트"는 어딘가에서 왔어야합니까? '$ tags'의 예제 입력을 보여줄 수 있습니까? –

+0

걱정하지 마십시오. 정말 감사드립니다. 아마 사용하기 좋은 예제는 아닙니다. $ tags는 단일 텍스트 상자에서 가져온 $ _POST에서 가져옵니다. 내가 입력 한 내용은 다음과 같습니다. test2 test2 test2 test2 테스트 죄송합니다. 동일한 태그 등. 몇 가지 오류 코드가 표시됩니다. 도움이된다면 더 좋은 예를 게시 할 수 있습니다. – Jack

답변

2

는 확신하기 어렵다, 그러나 나는이 해당 줄 그것은 내가 set_value() 내가이 추측거야

을 무엇을하는지 알 수 없기 때문에 말하기 어렵다

$tags = $this->db->escape(set_value('tags')); 

믿는다 문자열 test2 test2 test2 test2 test2'test2 test2 test2 test2 test2'으로 바꿉니다. 작은 따옴표는 사용자가 코드를 분해하고 다시한데 모아 놓은 후에도 문자열에 남아 있습니다.

하지만이 코드는 모두 입니다. 실제로는 지저분합니다. 사실, 당신이 가지고있는 문제는 당신이 걱정할 필요조차없는 것입니다 (변수 컬럼을 가진 INSERT를 동적으로 구축하십시오). 스키마에 약점이 있음을 나타냅니다. 태그는 열 제한이 아닌 code 테이블과 N : M (다 대다) 관계 여야합니다. 당신이 여기에서했던 방식은 database normalization의 두 번째 정규형을 깰 수 있습니다.

따라서 빠른 수정을 수행하고 이러한 태그 값을 이스케이프 처리하는 방법을 변경할 수는 있지만 스키마를 업데이트하는 것이 좋습니다.

+0

Peter. 고맙습니다. set_value는 기본적으로 CodeIgniter가 $ _POST [] 변수에서 데이터를 가져 오기위한 단축형입니다. $ this-> db-> escape ($ _ POST [ 'tags']); – Jack

+0

또한 의견을 찾고 : 나는 빠른 수정으로 갈 유혹입니다. 네, 미안 해요. 그리고 네, 제 코드가 지저분하고 초보자인데 모든 것을 고쳐야한다고 생각합니다. 그러나 웹 애플리케이션에 사용자가 5 개의 태그로 제한되어야 할 때 n-m 데이터베이스를 얻는 데는 정말로 요점이 있습니까? 나는 그 이상을 원하지 않는다. 정확히 5 개의 태그가 필요합니다. 번거롭게 볼만한 가치가 있습니까? – Jack

+0

태그 집합이나 여러 태그를 쿼리하는 성능에 신경 쓰는 것이 좋습니다. 그리고 제가 언급했듯이, 이것은 스키마 디자인의 꽤 기본적인 규칙을 어기는 것입니다. –

1

사실이 작업을 수행하여 주위에 따옴표를 넣어해야 할 말 :

$tags = $this->db->escape(set_value('tags')); 

귀하의 DB 클래스는 여러 값을 제공하는 것을 알지 못한다 (어떻게 그것을해야합니까?). set_value('tags')에서 값을 문자열로 처리하고 문자열을 이스케이프 처리해야합니다.

$pieces = explode(" ", $tags); 

당신에게, 예를 들어 주어야한다 :

나중에 해당 문자열을 폭발 " 'TEST1, TEST2, TEST3'을"

$pieces[0] = "'test1"; 
$pieces[1] = "test2"; 
$pieces[2] = "test3'"; 

당신은 결국 당신을 제공하는 다시 조각을 연결합니다.

나에게 이상한 유일한 점은 문자열에서 마지막 문자를 제거 할 때 끝 작은 인용입니다.

문제를 해결하려면 도망 치지 마십시오. set_value('tags') 사전에.대신에 하나의 값을 탈출 :

if ($pieces[0]!=NULL) {$ti1 .= "tag1, "; $ti2 .= $this->db->escape($pieces[0]) . ',';} 

또 다른 문제 : 나는 당신의 DB 설계에 어떤 통찰력이 없다하지만 tags이 관련된 다음 자신의 테이블에 가서 (그리고해야 것 같습니다 통해 하나 일대 또는 다 대 다 관계). 그렇지 않으면 태그가 6 개로 제한됩니다. 그러나 그것은 실제 목적에 달려 있습니다.

브라우저와 동일 : 새로운 브라우저가 출시되면 어떻게 될까요? 테이블을 확장해야합니다. 모든 브라우저가있는 테이블을 만드는 것이 더 좋습니다.

id | browser 
------------------- 
    0 | IE6 
    1 | IE7 
    2 | IE8 
    3 | FF2 
etc. 

및 코드에 중간 테이블을 통해 그들을 관련 :

--table code_browser 

code_id | browser_id 
-------------------- 
    0 | 0 
    0 | 1 
    0 | 3 
    1 | 2 
    2 | 1 

etc. 
+0

나는 두 번째로 set_value ('tags')를 의미한다고 생각하지만 답변 해 주셔서 감사합니다. 더 자세히 조사하겠습니다 :) – Jack

0

질문에 의해하지만 내 이해에서 조금 혼란 내가 들어)이 문제

의 몇 가지 생각 당신의 ID 칼럼은 0을 사용하는 것을 권하고 싶습니다. ''(내 의견으로는 좀 더 읽기 쉽게합니다.) 빈 문자열을 정의하십시오 $ti1 = "";

은 그럼 당신은 $ TI1 내가 당신 일을해야이

생각 무엇 tag1, tag2,

지금 동일 $ TI1 지금 tag1,

if ($pieces[1]!=NULL) {$ti1 .= "tag2, "; $ti2 .= "$pieces[1], ";} else {$ti1 .= "tag2, "; $ti2 .= "NULL, ";} 

같다

if ($pieces[0]!=NULL) {$ti1 .= "tag1, "; $ti2 .= "$pieces[0], ";} else {$ti1 .= "tag1, "; $ti2 .= "NULL, ";} 

그들에 추가

if ($pieces[0]!=NULL) {$ti1 .= "'tag1', "; $ti2 .= "$pieces[0], ";} else {$ti1 .= "'tag1', "; $ti2 .= "'NULL, ";} 

는 (큰 따옴표 안에 작은 따옴표를 추가 할 수 있습니다, 그래서 대신 있는의 $ TI1은 $ TI1이있을 것이다 tag1, tag2, 지금 동일 지금 'tag1', 'tag2',

C와 동일) 나는 완전히 확실하지 무엇을이 태그를 나타내는 것을 의미하지만 열의 ID와 ONE 태그가있는 조인 테이블을 만들 것입니다. 즉, 각 ID는 조인 테이블에서 최대 5 개의 행과 일치합니다. 이렇게하면이 태그에 대해 더 세밀하게 쿼리 할 수 ​​있습니다.

0

하나의 변수가 주어 지므로 그대로 취급됩니다.

if 문을 사용하여 $ sql 쿼리를 직접 작성할 수 있습니다.

$sql = "INSERT INTO code (id, title, author, summary, code, date"; 
     if ($pieces[0]!=NULL) {$sql .= ", tag1"; } 
     if ($pieces[1]!=NULL) {$sql .= ", tag2"; } 
    ... 

관련 문제