PHP apostroplarla ekleme nerede olmamalı

4 Cevap php

Burada bu kadar oluyor, ne de emin değil benim için standart bir uygulama gibi görünmüyor. Ama temelde o oluyor bir temel veritabanı zımbırtı kullanıcı kodu parçacıkları göndermenizi sağlar var. Onlar sunulması için 5 etiketleri kadar sağlayabilir.

Şimdi hala bu açıktır eğer öyleyse beni affet öğreniyorum!

İşte (orada bazı CodeIgniter özel işlevleri olabilir unutmayın) tüm iş yapar PHP script:

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');
    }
  }

Orada kodu bu sıkıcı saçmalık üzgünüm. Ben muhtemelen orada bir kaç kötü uygulamaları fark var - eğer öyleyse onları işaret edin.

Bu, (bu hatayla sonuçlanır ve hiç sorgulanmaz) gibi Çıktılanan sorgu görünüyor budur:

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)

Sen ŞİMDİ sonra biraz da görürsünüz (), 'test2, test2, test2, test2, test2' - Ben kesme tüm bu koymak için istemedim. I Did?

Ne yapabilirdim bu gibi bu hatların her biri alınır:

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

Etrafında tek tırnak $ adet [0] vs - ama sonra benim sorunum kullanıcı sadece 4 etiketleri, ya 3, ya da her neyse girdiğinde bu tür başarısız olmasıdır.

O tarihte kötü phrased soru Üzgünüm, ben denedim, ama beynim lapa döndü.

Yardımlarınız için teşekkürler!

Kriko

4 Cevap

Emin olmak zor, ama bu, ilgili hat olduğuna inanıyorum

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

Ben set_value() ne bilmiyorum çünkü söylemek zor

Bu tek-tırnak o patlayacak ve yine hep birlikte koyun sonra bile, dize içinde kalmak - Ben bu dize test2 test2 test2 test2 test2 'test2 test2 test2 test2 test2' dönüşür tahmin gidiyorum.

Ama bu kodun tüm really dağınık, söylemek zorundayım. Aslında, problemi yaşıyorsanız bile (dinamik değişken sütunları ile bir INSERT bina) hakkında endişelenmenize gerek olmamalıdır biridir. Bu bana şema bir zayıflığını gösterir - etiketler N olmalıdır: code masaya değil, sütun sert bir sınırı M (çok-çok) ilişkisi. Burada bunu yaptık yolu database normalization arasında 2. Normal formun kırar.

Yani, kesinlikle hızlı düzeltmek için gitmek ve bu etiket değerleri kaçıyorlar nasıl değiştirebilirim, ama ben senin şema güncellenmesi tavsiye ederim edebilir.

Aslında böyle yaparak etrafında koymak tırnak yapmak söyle:

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

Sizin DB sınıf Birden çok değer (nasıl olması gerektiği?) Sağlamak olduğunu bilmiyor. Bu dize ve dizeleri kaçtı gerekir gibi set_value('tags') alma değerini davranır.

Daha sonra bu dizeyi patlayabilir:

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

Size mesela vermeli

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

"'Test1, Test2, Test3'": Daha sonra size sonunda verir tekrar parçaları birleştirerek vardır.

Bana tuhaf görünüyor tek şey dizeden karakter son kaldırmak gibi biten tek tırnak olduğunu.

Bunu yapabileceğiniz sorunu çözmek için: Don't kaçış set_value('tags') önceden. Yerine tek değerleri kaçış:

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

Başka bir konu: Ben senin DB tasarım hiçbir fikir var ama o tags kendi bir tabloya gidin (ve sonra da bir-çok veya çok-çok ilişki yoluyla ilgili) gerektiği gibi görünüyor. Aksi takdirde, sadece altı etiketleri ile sınırlı olacaktır. Ancak bu gerçek amacına bağlıdır.

Tarayıcılar için aynı: yeni bir tarayıcı piyasaya alır ne olur? Eğer tablo uzatmak gerekir. Iyi tüm tarayıcılarda bir tablo var olduğunu, örneğin,

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

ve kodları bir ara masanın üzerinden onları ilgilidir:

 --table code_browser

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

 etc.

Sorusuna tarafından ama benim anlayış kafam karıştı biraz ben size birkaç sorun olduğunu düşünüyorum

a) Kimlik sütun için (benim görüşüme göre biraz daha okunaklı hale getirir 0 değil'' kullanarak öneriyoruz.

b) Eğer boş dizeleri tanımlamak $ti1 = "";

Sonra onlara eklemek

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

$ TI1 şimdi tag1, eşittir

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

$ TI1 şimdi tag1, tag2, eşittir

Ne yapıyor olması gerektiğini düşünüyorum

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

(note the addition of the single quotes inside the double quotes, so instead of having $ TI1 şimdi tag1, tag2, eşittiryou will have $ti1 is now equal to 'tag1', 'tag2', etc

c) Ben bu etiketleri ne anlama geldiğini tamamen emin değil temsil edilecek ama sütun ve ONE etiketinin kimlikli bir katılmadan tablo yaratacak. Bu, her id katılmadan tabloda 5 satır kadar maç olacak demektir. Bu, bu etiketleri vb sayma için daha iyi sorguları oluşturmak için izin verir.

Tek bir değişken verilmektedir, bu nedenle gibi tedavi ediliyor.

Ifadeleri doğrudan $ sql sorgu dışarı oluşturmak için eğer kullanabilirsiniz.

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

vb