PDO tablolarda sütun adlarını Kaçmak

4 Cevap php

Şu vea, alan / sütun ve değeri bölümleri her ikisi de muhtemelen kullanıcı girilen verilerin oluşan bir sorgu inşa ediyorum.

The problem is escaping the fieldnames. I'm using prepvardırd statements in order to properly escape ve quote the values but when escaping the fieldnames i run into trouble.

  • dışladı böylece mysql_real_escape_string bize amacıyla bir mysql bağlantı kaynak gerektirir
  • PDO :: alıntı da bir sorguda onları işe yaramaz hale FIELDNAMES tırnak ekler
  • işleri addslashes ama gerçekten güvenli değil

Herkes iyi yolu hazırlamak :: PDO geçirmeden önce düzgün bir sorgu içine FieldNames eklemek için ne bir fikir var?

4 Cevap

Ayrılmış bir tanıtıcı yapmanın ANSI standardı yoludur:

SELECT "field1" ...

ve varsa bir "isim, bunu iki katına:

SELECT "some""thing" ...

MySQL çift tırnak dize hazır tek tırnak için bir alternatif olduğunu düşünüyorum tercih çünkü ne yazık ki bu, varsayılan ayarları ile MySQL çalışmıyor. Bu durumda backticks (Björn tarafından belirtildiği gibi) ve ters bölü-kaçışa kullanmak zorunda.

O karakter-set-bağımlı çünkü doğru kaçan ters eğik yapmak için would, mysql_real_escape_string gerekir. Çünkü neither mysql_real_escape_string nor addslashes escape the backquote character Ama nokta, tartışılır. Eğer sadece elle `ve \ karakterler-kaçan BACKSLASH paçayı sütun adları ASCII olmayan karakterler var olmayacak emin olabilirsiniz eğer.

Her iki şekilde de, bu diğer veritabanları ile uyumlu değildir. Sen config seçeneği ANSI_QUOTES ayarlayarak ANSI sözdizimi izin MySQL söyleyebilirim. Benzer şekilde, SQL Server varsayılan olarak çift tırnak bobinleri; henüz başka bir sözdizimi, yani köşeli parantez kullanır. Yine, 'quoted_ıdentıfıer' seçeneği ile ANSI sözdizimi desteklemek için yapılandırabilirsiniz.

Özet: Eğer sadece MySQL uyumluluk gerekirse:

a. Onları kaçan güvenilmez çünkü backquotes kullanmak ve isimler backquote, ters eğik çizgi ve boş karakter vermemek

Çapraz-DBMS uyumluluk gerekiyorsa, ya:

b. çift ​​tırnak kullanımı ve uygun yapılandırmasını değiştirmek için MySQL / SQL Server kullanıcıları gerektirir. (Oracle onları bile kaçmış işleyemez gibi) adı çift tırnak karakterleri izin verme. Ya da,

c. Diğerleri vs SQL Server vs MySQL için bir ayar var ve buna bağlı olarak backquote, köşeli ayraç, ya da çift tırnak sözdizimi ya üretirler. Çift tırnak ve ters bölü / backquote / nul hem de izin verme.

Bu veri erişim katmanı için bir işleve sahip olacağını umut ediyorum bir şeydir, ama PDO değil.

Özetin özeti: keyfi sütun isimleri size yardımcı olabilir en iyi kaçınılmalıdır, bir sorun vardır.

Özet Özetin özeti: gnnnnnnnnnnnh.

Doğru cevap,

str_replace("`", "``", $fieldname)
olduğunu

Yanlış:

mysql> SELECT `col\"umn` FROM user;
ERROR 1054 (42S22): Unknown column 'col\"umn' in 'field list'

Sağ:

mysql> SELECT `kid``s` FROM user;
ERROR 1054 (42S22): Unknown column 'kid`s' in 'field list'
mysql> SELECT ```column``name``` FROM user;
ERROR 1054 (42S22): Unknown column '`column`name`' in 'field list'

(Son örnekte, sütun adı sadece aşırı bir durumda göstermek için, onun içinde 3 (üç) ekstra arka-kene olduğunu unutmayın)

Bu performansını etkileyebilir, ancak bu güvenli olmalıdır.

İlk işletilen bir kullanıcı sunulan verilere agaisnt bu maç sonra, izin verilen alan adlarının bir listesini almak için tablo yapma sorgusu DESCRIBE.

Bir maç varsa o zaman herhangi kaçması için ihtiyaç duymadan kullanıcı tarafından gönderilen verileri kullanabilirsiniz.

Orada maç değilse o zaman bir yazım hatası veya kesmek - her iki şekilde girilen verilerin bir 'hata' olduğunu ve sorgu çalıştırmak edilmemelidir.

Aynı SHOW TABLOLAR sorgu çalıştıran ve bu sonuç kümesinden eşleştirerek 'dinamik' tablo isimleri için yapılabilir.

Benim uygulamaları birinde bir 'install' script var; Bu parçası veritabanı ve tablo alan adlarını sorgular ve ardından hep bu yüzden sürekli örneğin, veritabanı agains DESCRIBE sorguları kaçmıyorum geri denir bir php dosyası yazar

$db_allowed_names['tableName1']['id'] = 1;
$db_allowed_names['tableName1']['field1'] = 1;
$db_allowed_names['tableName1']['field2'] = 1;
$db_allowed_names['tableName2']['id'] = 1;
$db_allowed_names['tableName2']['field1'] = 1;
$db_allowed_names['tableName2']['field2'] = 1;
$db_allowed_names['tableName2']['field3'] = 1;

if($db_allowed_names['tableName1'][$_POST['field']]) {
     //ok
}

Deyimi biraz daha hızlı bir in_array'in aramasından daha eğer ben gibi böyle dizi tuşlarını kullanın

Bir projenin garip tasarım, ancak sorun için: `ile alan adlarını Surround ve de adı addslashes kullanın.

select `field1`, `field2` from table where `field3`=:value