Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Losowe dodawanie rekordów do bazy z pliku.
Forum PHP.pl > Forum > PHP
krzysoolloo
Witam wszystkich!
Chcę napisać skrypt który dodaje do MySQL-a rekordy zapisane w pliku. Linijki w pliku wyglądają np tak:

INSERT INTO `Taabela123` VALUES (1, 'tekst1', 'admin');
INSERT INTO `Taabela123` VALUES (1, 'tekst2', 'admin');
INSERT INTO `Taabela123` VALUES (1, 'tekst3', 'admin');


I tutaj mam pytanie jak wczytać np losowe 100 linijek, dodać je do bazy i usunąć z pliku, aby uniknąć ponownego dodania?

Dziękuję za podpowiedzi,
Krzysiek
seth-kk
file() - wczytuje plik do tablicy
mt_rand() - w petli losuje indeksy (linie ktore maja trafic do bazy)
array_splice() - usuwa wylosowany wczesniej indeks
implode() - laczcy reste tablicy w ciag znakow
file_put_contents() - wrzoca ciag znakow spowrotem do pliku (domyslnie nadpisuje jesli moze)
w razie potrzeb szczegoly poszczegolnych funkcji na php.net winksmiley.jpg
krzysoolloo
Napisałem takie coś:

  1. <?php
  2.    $nazwa_pliku = "plik.sql";
  3.    $lines = file("$nazwa_pliku");
  4.    
  5.    $linijeczki = count($lines);
  6.    
  7.    for($i = 0; $i < 100; $i++)
  8.    {
  9.    $liczba = mt_rand(0, $linijeczki);
  10.    mysql_query("$lines[$liczba]");
  11.    
  12.    array_splice($lines, $liczba, 1);
  13.    implode("\n", $lines);
  14.    file_put_contents($nazwa_pliku, $lines);
  15.    }
  16.    $linijeczki = count($lines);
  17.    ?>


Lecz "zjada" mi niektóre linijki i czasami zatrzymuje ładowanie się w przeglądarce (ściąganie plik.php). Mógłby ktoś poprawić kod?
seth-kk
tak na oko:
  1. <?php
  2. $nazwa_pliku = "plik.sql";
  3. $lines = file("$nazwa_pliku");
  4.  
  5. $linijeczki = min(count($lines), 100); //na wypadek gdyby bylo mniej linii
  6.  
  7. for($i = 0; $i < $linijeczki; $i++)
  8. {
  9.   $liczba = mt_rand(0, $linijeczki-$i); //tablica robi sie krotsza po kazdym wywolaniu
  10.   mysql_query("$lines[$liczba]");
  11.  
  12.   array_splice($lines, $liczba, 1);
  13. }
  14. $lines = implode("\n", $lines); //implode zwraca wynik a nie odwoluje sie przez referencje
  15. file_put_contents($nazwa_pliku, $lines); //nie ma wiekszego sensu zapisywac zmiany wewnatrz petli lepiej postawic locka na plik
  16.  
  17. ?>
krzysoolloo
Niestety nie działa jak należy:/
Nie zapisuje zmienionego pliku (bez dodanych linijek)... Dodam, że nie wyskakuje żaden błąd i nadałem CHMOD na plik.
Pilsener
Najpierw policzymy rekordy w pliku:
  1. <?php
  2. $uchwyt = fopen($pliczek,'r');  
  3.   while(!feof($uchwyt)){
  4.      if(fgets($uchwyt)){
  5.            $ile_rekordow++;
  6.        }
  7.   }
  8. fclose($uchwyt);
  9. echo $ile_rekordow;
  10. ?>


- zakładam, że jak wyskoczy np. 2345 to umiesz wylosować 100 liczb z przedziału od 1 do 2345 i zrobić z tego tablicę np. $wylosowane? Pomijam zaten ten etap winksmiley.jpg

Teraz trzeba plik "przewalić":
  1. <?php
  2. $p_dane = fopen('dane.txt','r');
  3. $temp = fopen('temp.txt','a');
  4. $temp2 = fopen('do_bazy.txt','a');
  5. while(!feof($p_dane)){
  6.   ++$licz;
  7.   $linia = fgets($p_dane);
  8.   if(in_array($licz,$wylosowane)){  //warunek
  9.      fputs($temp2, $linia);      
  10.   }else{
  11.      fputs($temp, $linia);  
  12.   }  
  13. }//koniec pętli while
  14. fclose($p_dane);
  15. fclose($temp);
  16. fclose($temp2);
  17. unlink('dane.txt');
  18. rename('temp.txt','dane.txt');
  19. ?>


Jak to działa? Parsujemy plik wejściowy dane.txt w pętli while licząc jego linie - jeśli numer linii jest w tablicy wylosowanych, to wrzucamy linię do pliku do_bazy.txt, jeśli nie jest, to do pliku temp.txt, następnie kasujemy plik dane i zastępujemy plikiem temp (który nie ma już wylosowanych linii) a plik do_bazy.txt pozostaje dodać do bazy korzystając z
  1. LOAD DATA INFILE


Zakładam, że sobie poradzisz.

P.S > wrzucanie całego pliku do tablicy nie polecam, dbajmy o pamięć.
krzysoolloo
Niby wszystko okej, ale czasami powtarza się wylosowana liczba no i wtedy zaczynają wyskakiwać błędy itd...

  1. <?php
  2.   include ('polacz.php');
  3.   $pliczek = "baza2.txt";
  4.   $ile_rekordow = 0;
  5.   $uchwyt = fopen($pliczek,'r');  
  6.     while(!feof($uchwyt)){
  7.        if(fgets($uchwyt)){
  8.              $ile_rekordow++;
  9.          }
  10.     }
  11.   fclose($uchwyt);
  12.   echo $ile_rekordow."<br/><br/>";
  13.  
  14.   for($i = 1; $i <= 10; $i++)
  15.   {
  16.  
  17.   $liczba = mt_rand(1, $ile_rekordow);
  18.  
  19.   $tablica[$i] = $liczba;
  20.   echo $tablica[$i]."<br/>";
  21.  
  22.   }
  23.  
  24.   $licz = 0;
  25.   $p_dane = fopen($pliczek,'r');
  26.   $temp = fopen('temp.txt','a');
  27.   $temp2 = fopen('do_bazy.txt','a');
  28.   while(!feof($p_dane)){
  29.     ++$licz;
  30.     $linia = fgets($p_dane);
  31.     if(in_array($licz,$tablica)){  //warunek
  32.        fputs($temp2, $linia);      
  33.     }else{
  34.        fputs($temp, $linia);  
  35.     }  
  36.   }//koniec pętli while
  37.   fclose($p_dane);
  38.   fclose($temp);
  39.   fclose($temp2);
  40.   unlink($pliczek);
  41.   rename('temp.txt',$pliczek);
  42.  
  43.  
  44.   $lines = file('do_bazy.txt');
  45.   for($j = 1; $j <= 10; $j++)
  46.   {
  47.  
  48.      mysql_query("$lines[$j]");
  49.   echo $lines[$j]."<br/><br/>";
  50.   }
  51.  
  52.   unlink('do_bazy.txt');
  53.  
  54.   ?>
erix
Wpychasz wylosowane liczby do tablicy, przy użyciu in_array" title="Zobacz w manualu PHP" target="_manual sprawdzasz, czy już została wylosowana liczba. Mam nadzieję, że wiesz, jaką pętlę Ci tu sugeruję?

Poza tym, używaj właściwego bbcode.
krzysoolloo
Nie mogę sobie z tym poradzić... Do tej pory nie używałem tablic i plików. Mógłby mi ktoś to dokładnie wytłumaczyć?
erix
Półgotowiec:
  1. <?php
  2. $rnds = array();
  3.  
  4. for($a=0;$a<10;$a++){
  5.    
  6.    do{
  7.        $r = mt_rand();
  8.    }while(in_array($r, $rnds));
  9.    
  10.    $rnds[] = $r;
  11. }
  12. ?>
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.