Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Naruszenie zasad ochrony pamieci?
Forum PHP.pl > Forum > PHP
pietrekk
Witam,

Mam skrypt, ktory wykorzystuje rekurencje i czasem wywala taki blad na konsoli: "Naruszenie zasad ochrony pamieci".
Ktos wie w czym moze tkwic problem albo jak to mozna sprawdzic?

i druga kwestia czy jest jakies rozwiazanie, ktore jesli dzialanie skryptu zostaje przerwane wywoluje inna funkcje/plik ?

nospor
rekurencja ma to do siebie, ze zjada duzo pamieci. Jak sie twoja rekurencja dlugo nie konczy to taki jest efekt smile.gif
pietrekk
hmmm czyli jakie rozwiazania mozna zastosowac zeby tego uniknac?
nospor
unikac rekurencji jak ognia. A jak sie nie da, to tak ją pisac by bylo optymalnie.
No ale wrozką nie jestem - pokaz kod i co on ma robic.
pietrekk
a mozna jakos sprawdzic ile pamieci juz rekurencja pozarla, i np przerwac wykonywanie skryptu zanim zezre wszystko co dostepne i np zwolnic pamiec i uruchomic skrypt od nowa ? (wtedy i tak bedzie kontynuuowal od momentu przerwania bo to operacje na bazie danych );
nospor
Cytat
wtedy i tak bedzie kontynuuowal od momentu przerwania bo to operacje na bazie danych
Skoro jestes w stanie kontynuowac, to po co ci ta rekurencja tam? POkaz kod to ci poprawimy smile.gif
pietrekk
to jest taki spider/crawler do np robienia sitemap'y, zrobilem to z wykorzystaniem mysql:

function crawl($domain)
{
//select url not crawled yet
$sql = "SELECT * FROM tmpUrlCrawled WHERE visited IS NULL LIMIT 1";
$result = mysql_query($sql) or die (mysql_error()."<br>Query: $sql");
if(mysql_num_rows($result)>0)
{
$url = mysql_result($result,0,"url");
$url = mysql_real_escape_string($url);
//update url which was crawled
$sql = "UPDATE tmpUrlCrawled set visited = 'y' WHERE url = '$url'";
$result = mysql_query($sql) or die (mysql_error()."<br>Query: $sql");
//crawl links
if(preg_match("/^http[s]?:\/\/[^\/]*".str_replace('.', '\.', $domain)."/i", $url))
{
$tmpLinks = getUrls($url);
$tmpLinks = array_unique($tmpLinks);
}
//add crawled links to DB
if($tmpLinks)
foreach ($tmpLinks as $tmpLink)
{
$tmpLink = mysql_real_escape_string($tmpLink);
$sql = "INSERT IGNORE INTO tmpUrlCrawled set url = '$tmpLink'";
$result = mysql_query($sql) or die (mysql_error()."<br>Query: $sql");
}
//rekurencja
crawl($domain);
}

}
thek
Tutaj rekurencja? Ty chyba zgłupiałeś... winksmiley.jpg Chcesz cały net zaindeksować? Ktoś zrobi motyw http://www.domena.pl?url=http://www.domena2.pl i wlatujesz z crawlerem na całkiem inną domenę. Ewentualnie wpadasz na farmę linków i znów masz dym. Sprawdzaj wpierw czy znajdujesz się nadal na domenie z jakiej wyruszyłeś i sprawdzaj poziom zagłębienia. Bo jak wpadniesz w pętlę przekierowań to się robi potem jazda... A nie widzę byś się zabezpieczał jakkolwiek na taką sytuację. Poza tym myśl trochę przy pisaniu. Robisz dziesiątki zapytań i bazę zarżynasz. A powinieneś wyciągnąć z bazy listę linków aktualnie dla tej strony zaindeksowanych i w pętlach porównywać oznaczając: ta już była, ta jest nowa itd. Bo inaczej robisz sieczkę ostrą.
Do sitemapy Twojej własnej strony wystarcza znajomość jej struktury. Pewne linki masz stałe i możesz je na pałę wpisać do kodu. To co z bazy to zwykłe pętle while i banalne zapytania:
  1. <?php require_once("danebazy.php");
  2. $content = '<?xml version="1.0" encoding="UTF-8"?>
  3. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0....p.xsd">
  4. <url>
  5. <loc>http://www.domena.pl/</loc>
  6. <priority>1.0</priority>
  7. <changefreq>daily</changefreq>
  8. </url>
  9. <url>
  10. <loc>http://www.domena.pl/kontakt.php</loc>
  11. <priority>0.5</priority>
  12. <changefreq>monthly</changefreq>
  13. </url>';
  14. $kategorie = mysql_query( "SELECT * FROM artykuly_kategorie" );
  15. while($wynik = mysql_fetch_assoc( $kategorie ) ) {
  16. $content .= '<url>
  17. <loc>http://www.domena.pl/kategoria_artykulow_'.string2filename( polskie( $wynik['nazwa'] ) ).','.$wynik['id'].'.php</loc>
  18. <priority>0.4</priority>
  19. <changefreq>weekly</changefreq>
  20. </url>
  21. ';
  22. }
  23. $artykuly = mysql_query("SELECT tytul, id FROM artykuly WHERE stan = 1");
  24. while($wynik = mysql_fetch_assoc( $artykuly ) ) {
  25. $content .= '<url>
  26. <loc>http://www.domena.pl/art-'.string2filename( polskie( $wynik['tytul'] ) ).','.$wynik['id'].'.php</loc>
  27. <priority>0.4</priority>
  28. <changefreq>weekly</changefreq>
  29. </url>
  30. ';
  31. }
  32. $content .= '</urlset>';
  33. fputs($file, $content);
  34. fclose($file);
  35. ping_google();
  36. ?>
Tak się to robi, choć ja mocno okroiłem, ale żadne crawlery bo to mocno niewydajne i jedzie zarówno po serwisie, jak i po bazie. Nawet mocno rozbudowane serwisy się tak robi. Tyle, że wtedy robi kilka plików sitemap, nie zaś jeden duży. Ludzie myślcie trochę chociaż...
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.