• 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

Object Storage Arubacloud
0 głosów
259 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 (253,420 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 290 wizyt
pytanie zadane 6 lutego 2021 w PHP przez mat19 Obywatel (1,580 p.)
0 głosów
1 odpowiedź 216 wizyt
pytanie zadane 10 maja 2020 w PHP przez XiverKi Bywalec (2,050 p.)
0 głosów
1 odpowiedź 536 wizyt
pytanie zadane 5 kwietnia 2020 w PHP przez Assasz Nałogowiec (30,460 p.)

92,579 zapytań

141,432 odpowiedzi

319,664 komentarzy

61,964 pasjonatów

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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...