2012-11-19 17 views
8

Mam funkcję, która jest jakucieczce nazwa kolumny z PDO

function getInfoById($id, $info) { 

} 

pomysł jest mieć kwerendy być "SELECT $info FROM table WHERE id = $id"

ta nie działa z PDO, ponieważ nie można uciec nazwy kolumn. Ja również nie chcę używać "SELECT *", ponieważ nie zwraca większy zestaw wyników i więcej pamięci?

+0

powinien działać poprawnie ... spróbuj 'id = '$ id'" ' –

+0

możliwy duplikat [Escaping nazwy kolumn w instrukcjach PDO] (http://stackoverflow.com/questions/1542627/escaping-column-names -in-pdo-statement) – hakre

Odpowiedz

14

Tak, PDO nie posiada wbudowaną funkcję ograniczającą identyfikatory takie jak nazwy tabel i nazwy kolumn. Funkcja PDO::quote() służy tylko do literałów ciągów i literałów daty.

Za to, co warto, gdy pracowałem nad Zend Framework, zaimplementowałem funkcję quoteIdentifier().

Masz rację, że SELECT * pobiera wszystkie kolumny, prawdopodobnie zużywając więcej pamięci i psując korzyści związane z indeksami.

Moje zalecenie to białą listę nazw kolumn. To znaczy, upewnij się, że $ info w rzeczywistości nazywa kolumnę table. Wtedy nie musisz się martwić, że nazwa kolumny nie istnieje lub zawiera dziwną postać lub cokolwiek innego. Możesz kontrolować zestaw kolumn, które są uprawnione do umieszczenia w zapytaniu.

W każdym razie powinieneś także ograniczyć nazwę kolumny. Rozdzielne identyfikatory są niezbędne, jeśli nazwa kolumny zawiera znaki interpunkcyjne, białe znaki, znaki międzynarodowe lub odpowiada słowom zastrzeżonemu SQL. Zobacz Do different databases use different name quote?

function getInfoById($id, $info) { 
    // you can make this a literal list, or query it from DESC or INFORMATION_SCHEMA 
    $cols = array('col1', 'col2', 'col3'); 

    if (array_search($info, $cols) === false) { 
     return false; 
    } 
    $sql = "SELECT `$info` FROM table WHERE id = :id"; 
    $stmt = $pdo->prepare($sql); 
    if ($stmt === false) { 
     return false; 
    } 
    . . . 
} 

pokażę więcej przykładów whitelistingiem w mojej prezentacji SQL Injection Myths and Fallacies.

+2

Zgadzam się, biała lista ing jest drogą do zrobienia. – wesside

+0

'in_array' FTW ... – developerbmw

+0

' in_array' z 'true' dla dokładnego porównania – Bell

5

Po prostu odfiltrowuję to z pewnym wyrażeniem regularnym. Nie komplikuj.

Ponadto, należy wiązać $id i mają być :id

$info = preg_replace('/[^A-Za-z0-9_]+/', '', $info); 

$stmt = $pdo->prepare('SELECT $info FROM table WHERE id = :id'); 
$stmt->bindParam(':id', $id); 
$stmt->execute(); 
+0

-1 dla lepszego rozwiązania, kocham tę stronę czasami – wesside

+1

Cóż, to jest lepsze niż interpolacja dowolnych informacji $, ale jest to niepełne rozwiązanie.Na przykład, jeśli moja nazwa kolumny to 'order' (SQL zarezerwowane słowo), zapytanie łamie się, –

+1

@ Bill Bill Bill, zgadzam się, chociaż ja właśnie robiłem punkt.Jak powiedziałeś powyżej, biała lista jest do zrobienia, to jak wolę sobie z tym poradzić. to samo tutaj: http://stackoverflow.com/questions/13424009/updating-sql-column/13424037#13424037 Po prostu przejrzałem pokaz slajdów, dobre rzeczy – wesside

Powiązane problemy