Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] Krótka funkcja ułatwiająca korzystanie z zapytań do bazy danych
Forum PHP.pl > Inne > Oceny
Kildyt
Witajcie!

Piszę aktualnie nową wersję redbooka i pomyślałem, że niektórym powinna ułatwić życie krótka funkcja, która generuje ciąg do zapytań do bazy danych.
Przy okazji proszę o ocenę.

Oto kod:
  1. <?php
  2. function pull($item, $method = NULL) { // Generowanie ciągu do zapytania mysql
  3.    $return = NULL;
  4.    
  5.    /*
  6.     OJAŚNIENIE SYTUACJI
  7.     1 - Została podana jedynie nazwa elementu
  8.         Przykład: array('imie', 'nazwisko')
  9.     2 - Została podana tablica zawierająca nazwę elementu i jej wartość, która nie jest obiektem
  10.         Przykład: array(
  11.                                         array('imie', 'Jan'),
  12.                                         array('imie', $autor),
  13.                                         array('imie', $_POST['autor'])
  14.                                     )
  15.     3 - Została podana tablica zawierająca nazwę elementu i jej wartość, która jest tablicą i przyjmuje wartość nazwy elementu
  16.         Przykład: array(
  17.                                         array('imie', $_POST),
  18.                                         array('imie', $_GET)
  19.                                     )
  20.     */
  21.    
  22.    if (empty($method)) {
  23.        $method = $_POST;
  24.    }
  25.    
  26.    for ($i = 0, $to = count($item)-1; $i <= $to; $i++) {
  27.        if (is_array($item[$i])) {
  28.            if (is_array($item[$i][1])) {
  29.                // Sytuacja 3
  30.                $return .= '`'.$item[$i].'` = ''.$item[$i][1][$item[$i][0]].'', ';
  31.            } else {
  32.                // Sytuacja 2
  33.                $return .= '`'.$item[$i][0].'` = ''.$item[$i][1].'', ';
  34.            }
  35.        } else {
  36.            // Sytuacja 1
  37.            $return .= '`'.$item[$i].'` = ''.$method[$item[$i]].'', ';
  38.        }
  39.    }
  40.    
  41.    return substr($return, 0, -2);
  42. }
  43. ?>


I stąd zamiast:
  1. <?php
  2. mysql_query("INSERT INTO `name` SET `imie`='$_POST[imie]', `nazwisko`='$_POST[nazwisko]', `gg`='$_POST[gg]', `jabber`='$_POST[jabber]', `email`='$_POST[email]'");
  3. ?>
Mamy:
  1. <?php
  2. mysql_query("INSERT INTO `name` SET ".pull(array('imie', 'nazwisko', 'gg', 'jabber', 'email')));
  3. ?>


Funkcja napisana w kilkanaście minut. Licencja GPL v3.
Może się to wielu wydawać dziwne, że tak prosty kod daję do oceny i publikuję na GPL-u, ale chciałbym dać chociaż mały znak, że wspieram open source! smile.gif
.radex
  1. <?php
  2. for ($i = 0, $to = count($item)-1; $i <= $to; $i++) {
  3. ?>


nie łatwiej

  1. <?php
  2. for ($i = 0, $to = count($item); $i < $to; $i++) {
  3. ?>


?

  1. <?php
  2. @$item[$i][1][$item[$i][0]]
  3. ?>


po co "@" ? I tak nie rozwiązujesz tym żadnego problemu. Po prostu maskujesz błędy (teoretycznie mogłoby wywalić notice) w tej sytuacji

Ogólnie fajna funkcyjka, zapewne przydatna, ale nie lepiej dla użytkownika (w sensie programisty) zrobić:

  1. <?php
  2. pull('imie', 'nazwisko', 'gg', 'jabber', 'email')
  3. ?>


zamiast

  1. <?php
  2. pull(array('imie', 'nazwisko', 'gg', 'jabber', 'email'))
  3. ?>


hm? Żadna filozofia a umila pracę
Kildyt
Używam w nowym CMS-ie: error_reporting(E_ALL), więc dlatego unikam notic-ów.
mike
Cytat(Kildyt @ 2.03.2009, 15:29:50 ) *
Używam w nowym CMS-ie: error_reporting(E_ALL), więc dlatego unikam notic-ów.
Proponuję wejść na przejście dla pieszych na czerwonym świetle. Jak zamkniesz oczy to unikniesz zderzenia.
bim2
count() wydziel do zmiennej i na niej iteruj...

Pomysłwowości ci pogratuluje, ale funkcja taka sobie winksmiley.jpg Juz lepiej funkcje insert dać, albo najlepiej całą klasę ;d
mike
Cytat(bim2 @ 2.03.2009, 16:35:53 ) *
count() wydziel do zmiennej i na niej iteruj..
Przecież ma wydzielone tongue.gif
Kildyt
Cytat(.radex @ 2.03.2009, 17:21:07 ) *
po co "@" ? I tak nie rozwiązujesz tym żadnego problemu. Po prostu maskujesz błędy (teoretycznie mogłoby wywalić notice) w tej sytuacji
Macie rację. smile.gif Błędy ukryłem na wczesnym etapie pracy, kiedy funkcja była wywoływana cały czas, a nie wtedy kiedy powinna. Po kilkunastu minutach zrozumiałem błąd. Kod zmieniam. winksmiley.jpg

Cytat(.radex @ 2.03.2009, 17:21:07 ) *
Ogólnie fajna funkcyjka, zapewne przydatna, ale nie lepiej dla użytkownika (w sensie programisty) zrobić:

  1. <?php
  2. pull('imie', 'nazwisko', 'gg', 'jabber', 'email')
  3. ?>


zamiast

  1. <?php
  2. pull(array('imie', 'nazwisko', 'gg', 'jabber', 'email'))
  3. ?>


hm? Żadna filozofia a umila pracę

Do funkcji nie jest dostarczana tylko jedna wartość. Rozbudowałem ją sobie jeszcze o wyjątki i usunięcia, ale to już pod mój cms.

Dzięki za opinie. winksmiley.jpg
.radex
Cytat(Kildyt @ 2.03.2009, 18:07:53 ) *
Do funkcji nie jest dostarczana tylko jedna wartość.


... a func_get_args() znasz ?
bim2
@mike
Tak jest jak patrzy się na for( i count() ;d;d Ehh...

Zrób od razu może filtracje zmiennych
erix
A czemu nie zrobisz funkcji w stylu:
  1. <?php
  2. pull(
  3.  array('col'=>'val', 'col2'=>'val'),
  4.  'tabela'
  5. );
  6. ?>

?
Crozin
Jak będę miał jakąś wartość numeryczną to efektem będzie
  1. col = 'val'
czy
  1. col=val
? Jak dam null to będzie
  1. col = 'null'
czy
  1. col=NULL
?

Rozumiem, że funkcja przydaje się jedynie do zastosowanie z INSERT INTO, w dodatku w przypadku składni z SET?
Kildyt
Wartość zawsze będzie w apostrofach.
Zastosowanie funkcji nie ogranicza się jedynie do SET-a.
nospor
Cytat
Wartość zawsze będzie w apostrofach.
ale zdajesz sobie sprawę, ze często gęsto chcemy wstawic wartosc NULL a nie tekst 'NULL'?



Cytat
Zastosowanie funkcji nie ogranicza się jedynie do SET-a.
Przy obecnym zapisie to raczej tylko. Czyli INSERT i UPDATE
phpion
Cytat(Kildyt @ 2.03.2009, 16:38:03 ) *
Może się to wielu wydawać dziwne, że tak prosty kod daję do oceny i publikuję na GPL-u, ale chciałbym dać chociaż mały znak, że wspieram open source! smile.gif

Tekst (jak i sama funkcja) słaby. Poprzednicy wspomnieli już o jej ograniczeniach. Ja dodam ze swojej strony kolejne ograniczenie: tylko MySQL. Ogólnie nie sądzę aby ktokolwiek jej używał; jeśli ktoś będzie potrzebował czegoś podobnego to bez problemu sam sobie napisze.
Kildyt
Trochę poprawiłem. Apostrofy nie są obowiązkowe.

  1. <?php
  2.  
  3. function pull($item, $method = NULL) { // Generowanie ciągu do zapytania mysql
  4.   $return = NULL;
  5.  
  6.   /*
  7.    OJAŚNIENIE SYTUACJI
  8.    1 - Została podana jedynie nazwa elementu
  9.        Przykład: array('imie', 'nazwisko')
  10.    2 - Została podana tablica zawierająca nazwę elementu i jej wartość, która nie jest obiektem
  11.        Przykład: array(
  12.                                   array('imie', 'Jan'),
  13.                                   array('imie', $autor),
  14.                                   array('imie', $_POST['autor'])
  15.                               )
  16.    3 - Została podana tablica zawierająca nazwę elementu i jej wartość, która jest tablicą i przyjmuje wartość nazwy elementu
  17.        Przykład: array(
  18.                                  array('imie', $_POST),
  19.                                  array('imie', $_GET)
  20.                              )
  21.    PRZYPISY
  22.    #1 - Dodawanie apostrofów
  23.        Przykład zastosowania: array(
  24.                                array('wiek', 2+1), // Rezultat: `imie` = 3
  25.                                 array('int', '`id`+5', 1) // Rezultat `imie` = `id`+5
  26.                                                           )
  27.    */
  28.  
  29.   if (empty($method)) $method = $_POST;
  30.  
  31.   for ($i = 0, $to = count($item); $i < $to; $i++) {
  32.      $slash[$i] = NULL;
  33.      
  34.       if (is_array($item[$i])) {
  35.           if (is_string($item[$i][1]) AND !isset($item[$i][2])) $slash[$i] = '''; #1
  36.          
  37.           if (is_array($item[$i][1])) {
  38.               // Sytuacja 3
  39.               $return .= '`'.$item[$i].'` = '.$slash[$i].$item[$i][1][$item[$i][0]].$slash[$i].', ';
  40.           } else {
  41.               // Sytuacja 2
  42.               $return .= '`'.$item[$i][0].'` = '.$slash[$i].$item[$i][1].$slash[$i].', ';
  43.           }
  44.       } else {
  45.           // Sytuacja 1
  46.           $return .= '`'.$item[$i].'` = ''.$method[$item[$i]].'', ';
  47.       }
  48.   }
  49.  
  50.   return substr($return, 0, -2);
  51. }
  52.  
  53. ?>
Crozin
A co jak będę chciał np. zrobić UPDATEa:
  1. UPDATE abc SET sthCount = sthCount + 1, sthElse = 'abcdef';
Znowu polegnie.
Kildyt
Cytat(Crozin @ 4.03.2009, 16:36:57 ) *
A co jak będę chciał np. zrobić UPDATEa:
  1. UPDATE abc SET sthCount = sthCount + 1, sthElse = 'abcdef';
Znowu polegnie.


  1. <?php
  2. mysql_query('UPDATE `abc` SET '.pull(array(
  3.                                              array('sthCount', '`sthCount` + 1', 1),
  4.                                              array('sthElse', 'abcdef')
  5.                                             )));
  6. ?>
Rezultat dla funkcji to:
  1. <?php
  2. `sthCount` = `sthCount` + 1, `sthElse` = 'abcdef'
  3. ?>
sowiq
Cytat
array('sthCount', '`sthCount + 1', 1),
Taki mały, nadzorowany SQL Injection? smile.gif Nie obraź się, ale podzielam zdanie ~phpion'a.
Kildyt
Cytat(sowiq @ 4.03.2009, 17:03:19 ) *
Taki mały, nadzorowany SQL Injection? smile.gif Nie obraź się, ale podzielam zdanie ~phpion'a.
Jeżeli chodzi o ` to post zeedytowałem prawie od razu. Musiałeś zobaczyć go przed edycją.
Przecież ja nie mam na co się obrażać. smile.gif Chodziło mi o napisanie prostej funkcji i wiem, że mi się to udało.

Co do filtracji zmiennych to nie napisałem ją w tej funkcji, ponieważ w nowym redbook'u od razu filtruję $_POST i $_GET.
Crozin
Z góry zaśmiecasz wszystkie zmienne z $_POST, $_GET mysql_real_escape_stringiem?
Kildyt
Cytat(Crozin @ 4.03.2009, 18:03:49 ) *
Z góry zaśmiecasz wszystkie zmienne z $_POST, $_GET mysql_real_escape_stringiem?
Zaśmiecam? Nie przesądzaj sprawy jeżeli ją dogłębnie nie znasz. Co jest złego w hurtowym przefiltrowaniu zmiennych przy starcie silnika?
W starej wersji redbook'a filtrowałem za każdym razem zmienne i źle na tym wyszedłem. Filtruje je zawsze, do tego trzeba tworzyć kolejne zmienne, nie ja tu widzę (w mojej sytuacji) same plusy: szybciej, wygodniej, bezpieczniej.
erix
Cytat
Co jest złego w hurtowym przefiltrowaniu zmiennych przy starcie silnika?

Ano to, że w innych miejscach w kodzie filtracja może nie być pożądana. winksmiley.jpg
.radex
Cytat(erix @ 4.03.2009, 20:27:34 ) *
Ano to, że w innych miejscach w kodzie filtracja może nie być pożądana. winksmiley.jpg


to się odfiltruje (jeśli tylko chodzi o mysql_real_escape_string). Ja nie widzę problemu, ale i tak u siebie wolę za każdym razem ręcznie escape'ować, czy zamieniać na dany typ (gdy np. oczekuję int, a od użytkownika dostaję string, w którym może być cokolwiek)

@down: Napisałem wyraźnie: "to się odfiltruje (jeśli tylko chodzi o mysql_real_escape_string)."
nospor
Cytat
to się odfiltruje

To przepuszczaj tez od razu wszystko przez htmlspecialchars(). Jak ci nie bedzie potrzebne to sobie zamienisz spowrotem.
PRzepuszczaj jeszcze przez base64. Jak znowu nei bedzie potrzebne to tez odkodujesz.

smile.gif

Cytat
W starej wersji redbook'a filtrowałem za każdym razem zmienne i źle na tym wyszedłem
Jak sie nie uzywa sprawdzonych narzedzi ala PDO.... winksmiley.jpg

Cytat
ja tu widzę (w mojej sytuacji)
No i ok. Dla Ciebie moze to i git, ale nie wymuszaj tego na innych. Dales skrypt, by zaistniec w sieci, to przyjmij do wiadomosci ze nie kazdy robi tak jak ty i nie kazdy leci po globalnym filtrowaniu
Crozin
Poprzednicy już ładnie skrytykowali za mnie ten pomysł.

I teraz przyczepię się do jednego z Twoim-zdaniem-plusa: wygodniej.
  1. <?php
  2. #taki troche pseudo kod
  3.  
  4. #tutaj globalne filtrowanie
  5.  
  6. if(mb_strlen(odfiltruj_mysql_real_escape_string($login) < 3 || mb_strlen(odfiltruj_mysql_real_escape_string($login) > 100){
  7.  echo 'login jest za dlugi/krotki';
  8. }
  9.  
  10. if(mb_strlen(odfiltruj_mysql_real_escape_string($password) < 6){
  11.  //za krotkie
  12. }
  13.  
  14. if(lavenshtein(odfiltruj_mysql_real_escape_string($login), odfiltruj_mysql_real_escape_string($password)) < 3){
  15.  //haslo jest zbyt podobne do loginu
  16. }
  17.  
  18. //zarejetruj
  19. $sql = '... login = ' . $login . '...';
  20. //no.. tu to było fajnie :)
  21.  
  22. $mailBody = 'dziekujemy za rejestrację ' + odfiltruj_mysql_real_escape_string($login);
  23. //wyslij maila
  24. ?>
Ahh... ale przecież mogę sobie dać na początku:
  1. <?php
  2. $_login = odfiltruj_mysql_real_escape_string($password);
  3. ?>
I potem już nie ma problemu, mogę sobie fajnie na prostej zmiennej operować smile.gif Tylko jaki to ma sens, skoro zrobienie w drugą strone wygląda tak samo, a nie tworzy się burdelu w kodzie? Dodatkowo wspomniany przykład PDO - gdzie takie filtrowanie odbywa się jeszcze "przyjaźniej"
rzymek01
nie dałeś nawiasu w linii 6,7 i 11
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.