Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Optymalizacja skryptu
Forum PHP.pl > Forum > Przedszkole
Cromwell
Mam skrypt, którego zadaniem jest przerobienie pliku txt oraz podział danych w nim zawartych na dwie części - słowa z polskimi znakami, oraz resztę. Skrypt wygląda tak:

  1. <?
  2.  
  3. include 'funkcje.php';
  4.  
  5. echo '<form action="dodaj.php" method="POST">
  6. <input type="hidden" name="add" value="dodaj" />
  7. <input type="submit" value="dodaj" />
  8. </form>';
  9.  
  10.  
  11. $add = $_POST['add'];
  12.  
  13. if ($add == 'dodaj')
  14. {
  15.  
  16. $plik = file_get_contents('aa.txt');
  17. $separator = "\n";
  18.  
  19. $polskie = array();
  20. $inne = array();
  21.  
  22. conn(); //funkcja łączenia z bazą
  23.  
  24. foreach(split($separator,$plik) as $linia)
  25. {
  26. if(preg_match('/[ąćęłńóśźż]/ui', $linia)) //sprawdzenie, czy w słowie jest polski znak
  27. {
  28. $polskie[] = $linia;
  29. $query = "INSERT INTO polskie SET slowo = '$linia';";
  30. @mysql_query($query);
  31. }
  32. else
  33. {
  34. $inne[] = $linia;
  35. $query = "INSERT INTO inne SET slowo = '$linia';";
  36. @mysql_query($query);
  37. }
  38. }
  39.  
  40. //poniższa część służyła do zapisu danych do pliku, jednak na razie chcę je zapisać w bazie danych.
  41. /*
  42. sort($polskie);
  43. sort($inne);
  44. $pol = implode("\n",$polskie);
  45. $inn = implode("\n",$inne);
  46.  
  47. file_put_contents('polskie.txt',$pol);
  48. file_put_contents('inne.txt',$inn);
  49. */
  50. }
  51.  
  52. ?>


Skrypt działa, radzi sobie z małymi plikami, jednak problem jest z większymi.
Korzystając z file_get_contents poradził sobie z plikiem ponad 1mb (2mb już nie chwycił).
Gdy korzystałem wcześniej z fopen, fread itd, nawet 1mb był dla niego za duży.

Początkowo wyskakiwała informacja, że czas wykonywania skryptu jest za długi, jednak po dodaniu linii
  1. conn(); //funkcja łączenia z bazą
  2. foreach(split($separator,$plik) as $linia)

skrypt działa dłużej, ale ostatecznie wysypuje się po kilkunastu minutach przeglądarka.


Najwyraźniej skrypt nie radzi sobie z pierwszą częścią - odczytem pliku i wystartowaniem z pętlą, gdyż do bazy nie są dodawane żadne rekordy.

Zależy mi, aby skrypt radził sobie przynajmniej z plikami 5mb, a najlepiej by było, gdyby ugryzł taki, co waży 40mb.
Fajnie by też było, gdyby nie trzeba było całkiem przerabiać skryptu, aby czytał częściami, czy coś w tym stylu.

W razie czego mogę zmienić rozszerzenie/format pliku z txt na coś innego, mam dostęp do pliku php.ini na serwerze.
tvister
Wczytuj plik partiami oraz po zakończeniu cyklu uzupełnij bd. W file_get_contents określ offset i vista wio.
Cromwell
Z tego co doczytałem w manualu, w file_get_contents mogę ustawić offset od danego znaku do danego.
Niby to jest dobre, ale boję się, że u mnie nie zadziała. Dane w pliku txt są zapisane w ten sposób:
Cytat
pies
kot
abecadło
jakiś
ogórek
szkoła
delfin
marker

Mają różną długość, różne litery. Wspólny jest jedynie znak \n.
Jednak nie wiem, jak podzielić to wczytywanie pliku, aby nie tyle wczytywał część powiedzmy do 500 znaków, a np. określoną ilość słów, czy nawet około 500 znaków, tylko niech fragment kończy się \n.

Ma ktoś pomysł?
Pilsener
http://www.forumweb.pl/viewtopic.php?t=39103

Poczytaj o porcjowaniu danych z pliku:
  1. $uchwyt = fopen($pliczek,'r');
  2. while(!feof($uchwyt)){
  3. $linia = rtrim(fgets($uchwyt));
  4. $licznik++;
  5. if($licznik>$od && $licznik<=$do){
  6. $tabliczka[] = $linia;
  7. }
  8. }
  9. fclose($uchwyt);
- wczyta do "tabliczka" linie pliku od-do, na początek liczysz linie w pliku, potem ustalasz po ile linii ma być wczytanych za jednym razem - wszystko masz opisane w tutorialu.
Cromwell
Ok, wprowadziłem trochę zmian, jednak nie działa do końca..
Część w środku IF (wykonywanego jeśli kliknie się na button 'dodaj') wygląda tak:
  1. $plik = 'slowa.txt';
  2.  
  3. $uchwyt = fopen($plik,'r');
  4.  
  5. while(!feof($uchwyt))
  6. {
  7. $linia = fgets($uchwyt);
  8. $licznik++;
  9. if($licznik>0 && $licznik<=2738870) //od zera do liczby rekordów w pliku
  10. {
  11. if(preg_match('/[ąćęłńóśźż]/ui', $linia))
  12. {
  13. $plik = fopen("polskie.txt", "a");
  14. fwrite($plik, $linia);
  15. fclose($plik);
  16. }
  17. else
  18. {
  19. $plik2 = fopen("inne.txt", "a");
  20. fwrite($plik2, $linia);
  21. fclose($plik2);
  22. }
  23. }
  24. }
  25.  
  26. fclose($uchwyt);

Skrypt fajnie dzieli słowa, zapisuje do plików, jednak w pewnym momencie zaczyna się miotać.
Natrafia na 22 słowa z polskimi znakami, w pliku inne.txt ich nie ma, jednak zamiast następnego słowa za tymi słowami z polskimi znakami, jest pierwsze słowo z pliku (mam nadzieję, że dość zrozumiale tłumaczę).
Co z tym zrobić?
Pilsener
Hej.
1. Po co za każdym razem w pętli otwierasz i zamykasz plik? Fopen powinny być przed pętlą while a fclose za, w pętli tylko fwrite.
2. Sprawdź na kilku pierwszych rekordach jak działa preg_match, może nie do końca tak, jak tego oczekujesz?
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.