Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Dodawanie wielu elementów tablicy $_FILES do bazy danych
Forum PHP.pl > Forum > Przedszkole
babcia_smierc
Mam taki problem:
Użytkownik wskazuje ilosc zdjec do galeri newsa do wgrania na serwer, po czym tworzona jest tablica $_FILES. W jaki sposób dodać zawartość tej tablicy (wielu rekordów) za pomocą jednego zapytania ?

tabela news_gal do ktorej wstawic chiałbym wiele rekordów wyglada tak:(id, id_newsa, obraz)

oto kod dynamicznego tworzenia ilosci zdjec do wstawienia:

  1. if(@$_POST['submit'] AND ($_POST['ilosc_zdj'])>0) {
  2. //form start
  3. echo('<form enctype="multipart/form-data" action="dodaj_zdj_akt.php?id_newsa='. $id . '" method="POST">
  4. <input type="hidden" name="MAX_FILE_SIZE" value="1000000" />');
  5. $ilosc = (int)$_POST['ilosc_zdj'];
  6. for($x=1;$x<=$ilosc;$x++) {
  7. echo('<input name="plik[]" type="file" /><br />');
  8. }


A to kod (błędny) zapytania

  1. if(@$_POST['submit2']) {
  2.  
  3.  
  4. $add_news_pic = "INSERT INTO `wtz`.`news_gal`(id, id_newsa, obraz) VALUES (NULL, '" . $id . "')";
  5. mysql_query($add_news_pic) or die(mysql_error());
  6.  
  7. }
Damonsson
Zrób sobie foreach tej tablicy i w nim INSERT, przy okazji możesz skorzystać z transakcji.
Sephirus
Ogólnie możesz zastosować wiele dodawanych wartości w INSERT w SQL przecież smile.gif

Przykład:

  1.  
  2. $sql = "INSERT INTO tabelka (id,pole1,pole2) VALUES ";
  3. $sqlValues = array();
  4.  
  5. foreach($tablica AS $element) {
  6. $sqlValues[] = "(NULL,'{$element['pole1']}','{$element['pole2']}')";
  7. }
  8.  
  9. $sql = $sql . implode(', ',$sqlValues);
  10.  
  11.  
Damonsson
Ładowanie wszystkiego do jednego INSERT'a po przecinku, jest szybsze/wydajniejsze/lepsze, niż oddzielne wykonywanie INSERT'ów bez korzystania z transakcji/z wykorzystaniem transakcji?
Sephirus
W tym przypadku - sam sobie odpowiedz smile.gif

EDIT: Transakcja tutaj to dodatek - możesz jej równie dobrze użyć w moim zapytaniu lub nie - to już zależy od twórcy - nie to było tematem.
Damonsson
Gdybym wiedział, nie pytałbym tongue.gif

Ale zaryzykuję, że jest równe oddzielnym insertom z wykorzystaniem transakcji?

edit: w tym konkretnym przypadku, to nie ma znaczenia pewnie, ale przy większej ilości, to już ma znaczenie, chodzi mi o ten drugi przypadek.
Sephirus
Cytat
Gdybym wiedział, nie pytałbym

Ale zaryzykuję, że jest równe oddzielnym insertom z wykorzystaniem transakcji?


Ogólnie tak - zgadzam się z tym, ale tylko jeśli autor zbierze wszystkie zapytania w kupę (w jakiś jeden ciąg - łącznie ze startem transakcji) i je wyśle raz do DB - inaczej wykonywanie oddzielnych zapytań (autor korzysta z mysql_***) będzie mniej wydajne smile.gif

EDIT: Dla duuuuużej liczby rekordów to nawet moją metodę trzeba by było dzielić dodając po X rekordów tak by nie przekroczyć maksymalnej długości zapytania. Tu bardziej chodzi o dobry nawyk. Lepiej od razu zrobić coś na zasadzie:

Kod
pętla() {
    Tu generuje całe zapytanie SQL z dodawaniem wielu rekordów
}

Tu wykonuje jedno zapytanie


Niż:

Kod
pętla() {
    Każdorazowo wykonuje zapytanie
}


Dla dużej liczby tych plików poszła by masa zapytań, a że autor korzysta z funkcji rodziny mysql_*** to z wydajnością było by to na bakier wink.gif

EDIT2: Bo zapomniałem - moja metoda wymusza po prostu takie myślenie smile.gif
babcia_smierc
A co jesli $_FILES['name'] tez jest tablica ? Tzn. w formularzy <select> wybieram wiecej niz 1 zdjecie... Wtedy to wyglada tak:
  1.  
  2. (
  3. [plik] => Array
  4. (
  5. [name] => Array
  6. (
  7. [0] => obraz12.jpg
  8. [1] => obraz1.jpg
  9. )
  10. )


Co trzeba zmodyfikować w:

  1. $tablica = $_FILES;
  2. $sql = "INSERT INTO news_gal (id,id_newsa,obraz) VALUES ";
  3. $sqlValues = array();
  4.  
  5. foreach($tablica AS $element) {
  6. $sqlValues[] = "(NULL,' . $id . ','{$element['name'][0]}')";
  7. }
  8.  
  9. $sql = $sql . implode(', ',$sqlValues);
  10.  
  11.  


Dodać jeszcze jedną pętle foreach ?
Sephirus
  1. $tablica = $_FILES['name'];
  2. $sql = "INSERT INTO news_gal (id,id_newsa,obraz) VALUES ";
  3. $sqlValues = array();
  4.  
  5. foreach($tablica AS $element) {
  6. $sqlValues[] = "(NULL,'{$id}','{$element}')";
  7. }
  8.  
  9. $sql = $sql . implode(', ',$sqlValues);
  10.  


smile.gif

EDIT: miałeś mały błąd.
phpion
Cytat(Damonsson @ 20.02.2013, 08:44:56 ) *
Ładowanie wszystkiego do jednego INSERT'a po przecinku, jest szybsze/wydajniejsze/lepsze, niż oddzielne wykonywanie INSERT'ów bez korzystania z transakcji/z wykorzystaniem transakcji?

Zdecydowanie (przynajmniej w przypadku PostgreSQL). Przy jednym projekcie miałem okazję sprawdzić to na własnej skórze. Multi-insert jest zdecydowanie szybszy. Zależy oczywiście ile danych jest do wstawienia. Różnica będzie rosła wraz z ilością danych do wstawienia. Oczywiście przy ogromnej liczbie danych warto rozważyć zapis danych do pliku i późniejsze LOAD DATA INFILE.
babcia_smierc
A błędne czasem nie jest to ze w panelu phpmyadmin w tablei news_gal w ostatniej kolumnie 'obraz' wyswietla nie nazwe obrazu tylko 'Array' ? Bo to własnie tablice mi dodaje a nie konkretna nazwe pliku.
Oto co mi wywala:

Notice: Array to string conversion in E:\xampp\xampp\htdocs\wtz_php\dodaj_zdj_akt.php on line 26

Przypominam, że chciałbym dodać więcej niż jeden plik (obraz). W zakresie 1-10.
Sephirus
Na pewno dobrze przepisałeś ten kod?

Skoro $tablica to $_FILES['name'] to w foreach powinno być wszystko ok...
babcia_smierc
Zrobiłem kopiuj wklej i oto co mi wywala:

Notice: Undefined index: name in E:\xampp\xampp\htdocs\wtz_php\dodaj_zdj_akt.php on line 21

Warning: Invalid argument supplied for foreach() in E:\xampp\xampp\htdocs\wtz_php\dodaj_zdj_akt.php on line 25
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

a oto linia 25:

  1. foreach($tablica AS $element) {
  2. $sqlValues[] = "(NULL,'{$id}','{$element}')";
  3. }
Sephirus
ajjj takie przeoczenie smile.gif sam mogłeś wpaść na to tongue.gif Zapomnieliśmy obaj o tym że INPUT FILE ma swoją nazwę smile.gif

  1. // W tym miejscu powinieneś też sprawdzać czy w ogóle w $_FILES coś jest itd...
  2. $tablica = $_FILES['plik']['name'];
  3. $sql = "INSERT INTO news_gal (id,id_newsa,obraz) VALUES ";
  4. $sqlValues = array();
  5.  
  6. foreach($tablica AS $element) {
  7. $sqlValues[] = "(NULL,'{$id}','{$element}')";
  8. }
  9.  
  10. $sql = $sql . implode(', ',$sqlValues);
  11.  
babcia_smierc
Działa !
Tylko nie dodaje mi identyfikatora newsa do bazy (id,id_newsa,obraz). Nie wiecie dlaczego ?
Sephirus
A odbierasz to ID z parametru GET w ogóle? smile.gif

  1. $id = mysql_real_escape_string($_GET['id_newsa']);
  2.  
  3. // ... dalszy kod
babcia_smierc
Tak, na początku strony:

  1. include("header.php");
  2. if($_SESSION['USERLEVEL'] != 10) {
  3. header("Location: index.php?page=main");
  4. }
  5. @$id = $_GET['id'];
  6.  
  7. ...
Sephirus
Cytat
$_GET['id']


A jak się nazywa parametr w adresie? smile.gif

Co masz w atrybucie ACTION w FORM? smile.gif

Chłopie! ;P facepalmxd.gif
babcia_smierc
Problem w tym ze na jednej stornie mam 2 formularze (1 do okreslenia ilosci zdjec która chce sie uploadowac a 2 do wysyłania tych zdjec).

1:
  1. echo('<form enctype="multipart/form-data" action="dodaj_zdj_akt.php?id_newsa='. $id . '" method="POST">

2:
  1. echo '<form action=dodaj_zdj_akt.php?id_newsa=' . $id . ' method=POST>';
  2. echo '<p class=form>Podaj ilosc zdjęć do wstawienia</p>';
  3. echo '<select name=ilosc_zdj>';
Sephirus
Przecież możesz to połączyć w jeden smile.gif

Liczbę zdjęć możesz określi po liczbie plików wink.gif

Z tym musisz już sobie sam poradzić.
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-2025 Invision Power Services, Inc.