Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Porównanie nazw plików na dysku do tych, które są w MySQLu
Forum PHP.pl > Forum > PHP
KR2615
Witam
Tak jak w temacie, muszę prześwietlić folder który mam na dysku, znaleść pliki których jeszcze nie ma w MySQLu i dodać je do bazy. Do tego pierwszego znalazłem taka pętlę:
  1. $dir = dir(/usr/share/pliki.");
  2. var_dump($dir);
  3. while (false !== ($entry = $dir->read())) {
  4. <------>// kwerenda mysql typu SELECT * FROM pliki where name = '$entry'
  5. <------>// Jeśli nic nie znajdzie, robi INSERTA
  6. }


Obawiam się jednak, ze w przypadku wielu setek plików to rozwiązanie może być zbyt mocno obciążające. Dlatego wpadłem na pomysł, żeby do drugiej tablicy pobrać wszystkie nazwy plików któe mam w MySQLu i porównać je funkcją taką jak ta:
http://php.net/manual/pl/function.array-diff-uassoc.php

Niestety nie pokazuje to równic, twierdzi, że żadne elementy w tych tablicach się nie pokrywają. Czy ktoś z Was ma pomysł, jak to rozwiązać? Z góry dzięki!
kapslokk
Jeśli w folderze będziesz miał dużo plików to może Ci braknąć pamięci na array_diff. A gdybyś tak założył UNIQUE na nazwe pliku w MySQL i robil INSERT IGNORE po np 50 plikow na raz?
KR2615
Myślisz, że to będzie mniej zasobożerne niż porównywanie dwóch arrayów?
kapslokk
Zależy dla ilu plików tongue.gif Ale w przypadku mojego rozwiązania ogranicza Cię jedynie czas wykonania skryptu, pamięć nie zostanie przekroczona przy odpowiednim ustawieniu wielkości paczki do zapisu.
KR2615
Przy obecnych 50 plikach nie byłoby to problemem, tym bardziej ze rocznie pojawia się ich ok. 250. Jedyny kłopot to taki, że INSERT IGNORE inkrementuje mi id. Wykonałem skrypt dwa razy, dodało jeden rekord a id mam 114 przy czym ostatnim prawidłowym id był 36. Nie podoba mi się to rozwiązanie. W razie czego podaje fragment kodu bo może coś skopałem:
  1. $dir = dir(/usr/share/pliki");
  2. while (false !== ($entry = $dir->read())) {
  3. <------>$q = "INSERT IGNORE INTO `pliki` (`id`, `filename`, `done`, `contents`) VALUES (NULL, '$entry', '0', '0')";
  4. <------>mysql_query($q);
  5. }
kapslokk
Mozesz zmienic IGNORE na INSERT ... ON DUPLICATE KEY UPDATE id=id

Cytat
If you use INSERT IGNORE and the row is ignored, the LAST_INSERT_ID() remains unchanged from the current value (or 0 is returned if the connection has not yet performed a successful INSERT) and, for non-transactional tables, the AUTO_INCREMENT counter is not incremented. For InnoDB tables, the AUTO_INCREMENT counter is incremented if innodb_autoinc_lock_mode is set to 1 or 2
KR2615
Zmieniłem, wykonałem, mam nowe id=153
Finalnie zostawiłem taki kod:
  1. while (false !== ($entry = $dir->read())) {
  2. <------>if($entry != "." && $entry != "..") {
  3. <------> $q = mysql_query("SELECT * FROM `pliki` WHERE filename='$entry'");
  4. <------> if(!mysql_fetch_row($q)) {
  5. <------><------>mysql_query("INSERT INTO `pliki` (`id`, `filename`, `done`, `contents`) VALUES (NULL, '$entry', '0', '0')");
  6. <------> }
  7. <------>}
  8. }
kapslokk
  1. CREATE TABLE test(id int AUTO_INCREMENT, nazwa varchar(255), PRIMARY KEY (id));
  2. ALTER TABLE test ADD UNIQUE (nazwa);
  3. INSERT INTO test (nazwa) VALUES ("test1"), ("test2"), ("test3");
  4. INSERT INTO test (nazwa) VALUES ("test2"), ("test3"), ("test4") ON DUPLICATE KEY UPDATE id = id;

U mnie dziala normalnie cos takiego. max(id) po wykonaniu powyzszego kodu = 4.
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.