• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

PDO Metoda do uniwersalnego wstawiania danych

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
321 wizyt
pytanie zadane 16 grudnia 2022 w PHP przez kordix Gaduła (3,910 p.)
edycja 16 grudnia 2022 przez kordix

Tak wygląda kod który dla danych danych tworzy rekord dla określonej tabeli

if(!isset($_SESSION['zalogowany'])){
return
}

$pytajniki = '';
$wartosci = [];
$kolumny = '';

foreach($dane as $key => $value)
{
    $kolumny .= '`'.htmlentities($key, ENT_QUOTES, 'UTF-8').'`';
    $kolumny .= ',';
    $pytajniki .= '?';
    $pytajniki .= ',';
    array_push($wartosci , $value);
}

$pytajniki = substr($pytajniki, 0, -1);
$kolumny = substr($kolumny, 0, -1);
$query = "INSERT INTO test ($kolumny) values ($pytajniki) ";
$sth = $dbh->prepare($query);
$sth->execute($wartosci);



Dla values wartości są preparowane , jednak mam wątpliwości dla kolumn. Tam nie da się niestety użyć parametryzacji z PDO.

Tutaj zakładamy że każdy zalogowany użytkownik może dowolnie edytować dane w tej tabeli, nie ma też możliwości rejestrowania nowego użytkownika.

Możecie powiedzieć co o tym myślicie , czy ta metoda jest do końca bezpieczna.

1 odpowiedź

0 głosów
odpowiedź 16 grudnia 2022 przez VBService Ekspert (256,320 p.)
edycja 3 marca 2023 przez VBService

 jednak mam wątpliwości dla kolumn. Tam nie da się niestety użyć parametryzacji z PDO

Na chwilę obecną, po dokładnym sprawdzeniu, nie da się użyć parametryzacji w nazwach kolumn.

 

Można co najwyżej spróbować np. tak

$columns = ['nazwa_kolumny_1', 'nazwa_kolumny_2'];
$values = ['wartość_1', 'wartość_2'];

$placeholders = implode(', ', array_fill(0, count($columns), '?'));
$columns = implode(', ', array_map([$pdo, 'quote'], $columns));

$sql = "INSERT INTO tabela ($columns) VALUES ($placeholders)";
$stmt = $pdo->prepare($sql);
$stmt->execute([...$values]);

 

W powyższym przykładzie tworzymy tablicę z placeholderem (?) dla każdej nazwy kolumny, a następnie łączymy je za pomocą przecinka.

$placeholders = implode(', ', array_fill(0, count($columns), '?'));

Następnie odpowiednio filtrujemy nazwy kolumn i łączymy je również za pomocą przecinka.

$columns = implode(', ', array_map([$pdo, 'quote'], $columns));

Powyższa linia służy do tworzenia ciągu znaków z nazwami kolumn, które następnie będą wstawione do zapytania SQL.

Funkcja array_map() wykonuje podany callback ,funkcję dla każdego elementu tablicy. W naszym przypadku podajemy callback jako tablicę z dwoma elementami: obiektem PDO oraz nazwą metody (quote). Funkcja quote() jest metodą obiektu PDO, która zwraca bezpieczny ciąg znaków zapytania SQL dla podanego ciągu znaków. Dzięki temu nazwy kolumn są odpowiednio zabezpieczone przed atakami typu SQL injection.

Funkcja implode() łączy elementy tablicy w jeden ciąg znaków. W naszym przypadku elementy tablicy są łączone za pomocą przecinka i spacji.

W rezultacie otrzymujemy ciąg znaków z odpowiednio zabezpieczonymi nazwami kolumn, który możemy wstawić do zapytania SQL.

W końcu łączymy nazwy kolumn i wartości w jedną tablicę i przekazujemy ją jako parametr do metody execute().

[...$values] - splat operator

komentarz 16 grudnia 2022 przez kordix Gaduła (3,910 p.)

No właśnie mi to za Chiny nie działa dla kolumn

Wywala

: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?) VALUES (?)' 

Jakby dawał jakiś apostrof a potem już w ogóle nie zamieniał pytajnika.

Kod praktycznie skopiowany

require 'db.php';

$column = 'subject';
$value  = 'wartość';
$sql = "INSERT INTO test (?) VALUES (?)";
$stmt = $dbh->prepare($sql);
$stmt->execute([$column, $value]);

 

komentarz 16 grudnia 2022 przez kordix Gaduła (3,910 p.)
Przy $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); coś zaczyna łapać, ale dalej się rozwala dla kolumn ,wszytko jest ok jak jest używane dla wartości

 near ''todo' VALUES ('wartość')' at line 1
komentarz 17 grudnia 2022 przez kordix Gaduła (3,910 p.)

@VBService, sory ale gadasz głupoty.

Wyżej dałem linka preparowanie nie działa dla kolumn.

https://phpdelusions.net/pdo/sql_injection_example

Tu jest fajnie opisane 

Rozwiązaniem jest whitelista z dopuszczalnymi nazwami kolumn. Metoda quote wcale nie jest taka super jak tam jest opisane.

 

Podobne pytania

0 głosów
0 odpowiedzi 437 wizyt
pytanie zadane 6 lutego 2021 w PHP przez mat19 Obywatel (1,580 p.)
0 głosów
1 odpowiedź 263 wizyt
pytanie zadane 10 maja 2020 w PHP przez XiverKi Bywalec (2,050 p.)
0 głosów
1 odpowiedź 650 wizyt
pytanie zadane 5 kwietnia 2020 w PHP przez Assasz Nałogowiec (30,460 p.)

93,187 zapytań

142,201 odpowiedzi

322,012 komentarzy

62,514 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 2127p. - dia-Chann
  2. 2092p. - Łukasz Piwowar
  3. 2079p. - Łukasz Eckert
  4. 2037p. - Tomasz Bielak
  5. 2006p. - rucin93
  6. 2006p. - Michal Drewniak
  7. 2005p. - Łukasz Siedlecki
  8. 1964p. - CC PL
  9. 1946p. - Adrian Wieprzkowicz
  10. 1901p. - Mikbac
  11. 1744p. - rafalszastok
  12. 1734p. - Anonim 3619784
  13. 1586p. - Dawid128
  14. 1520p. - Marcin Putra
  15. 1480p. - ssynowiec
Szczegóły i pełne wyniki

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...