PHP - Fatal Error: Maximum execution time... Komma runt tids begränsningen

Permalänk
Medlem

PHP - Fatal Error: Maximum execution time... Komma runt tids begränsningen

Håller på med ett litet projekt som går ut på att göra en "custom" tvguide.

Så här långt har jag kommit och stöter på ett problem där jag når den maximala tidsbegränsningen som ett script kan köra.

Jag har en funktion som laddar in html kod från en sida. Sedan söker den igeom html koden och plockar ut tidpunkten och vilket program som sänds då. Inga problem där.

Problemet uppstår när jag försöker ladda många kanaler samtidigt. Då når den begränsningen.

Koden jag kör för att ladda alla kanaler är:

public function loadAllActiveCh(){ $sql = 'SELECT chid FROM `tvguidecouk` WHERE active = 1'; /* Kör frågan mot databasen */ $r = $this->mysqlSelect($sql); /* Plockar ut rad för rad ur reultatet från SQL frågan */ while($row = mysql_fetch_assoc($r[0])){ /* Skriver ut kanalinnehållet med hjälp av echo i funktionen */ $this->loadChContent($row['chid'], date('Y-m-d')); } } }

Kan jag göra på något annat sätt för jag gissar på att det är while-loopen som ställer till det. Funktionen är en del av en class som jag skrivit. Saknar ni någon information som behövs för att lösa problemet säg till. Hoppas någon kan peka mig i rätt riktning.

Visa signatur

Apple Mackbook Pro 15" Retina 2013

Permalänk
Medlem

Det skulle ju vara intressant att veta vad din maximum execution time är inställd på. Default är 30 sekunder, men om du kör på nåt webbhotell kan de ha sänkt den för att minska belastningen på deras servrar. Har du själv kontroll över servern kan du ändra det i php.ini. Men hur länge tar det innan du får felmeddelandet, så kan man uppskatta vad max execution time är inställt på.

Permalänk
Medlem

Vad händer med $r är det en array med queries eller bara en query?
Om det bara är en query så ska det väl stå mysql_fetch_assoc($r) Tänk på att MySQL är föråldrad använd MySQLi istället.

Du kan testa att använda usleep om det bara är så att det är för många radar. Men bäst skulle vara att dela upp det på något sätt.

Visa signatur
Permalänk

Antar att funktionen loadChContent laddar innehåll från en extern sida? detta anrop tar lång tid och skulle förmodligen gå snabbare att lösa igenom en cahce-lösning där tablån hämtas och parsas en gång och läggs in direkt i databasen (alternativs sparar en kopia av html-outputen från parsningen för varja kanal och dag).
En lämplig metod vore att varje natt köra:
*ett script som hämtar hem alla tablåer och parsar dom
*generera html-sniplets i stil med: chid-2013-02-25.html
*spara dessa i en katalog
*vid laddning läs in de html-filerna som behövs för att generera tablån.

Detta avlastar dessutom den sidan du parsar tablån ifrån.

EDIT: som XzaR skriver så bör "while($row = mysql_fetch_assoc($r[0]))" vara "while($row = mysql_fetch_assoc($r))", som sagt är det även rekomenderat att använda MySQLi: http://php.net/manual/en/book.mysqli.php

Permalänk
Medlem

1. Execution time är 30s
2. $r som kommer tillbaka är en array. $r[0] är resultatet från databasen. Ska kika på mysqli
3. Precis så som du beskriver gör jag. Hämtar infon från sidan. Det sparas i databasen så att jag inte behöva hämta fler gånger. Men när jag ska ladda dagens tv tablå då kommer begränsningen.

Visa signatur

Apple Mackbook Pro 15" Retina 2013

Permalänk
Medlem

Om det tar längre än 30s är ju inte problemet att php execution time är för låg, utan att scriptet är på tok för långsamt.

Allt som tar längre än 1 sekund är generellt klassificerat som dåligt, då man blir irriterad som användare och siten känns klumpig.

Om du inte kan trimma loadChContent() så att den blir snabbare, bör du kanske ladda kanalerna asyncront med ajax. - Skicka ut 8 stycken frågor för 8 kanaler, sätt in en loading placeholder i varje box som håller kanalerna och låt de ladda samtidigt. Kommer fortfarande vara irriterande, men inte lika irriterande.

Utan att ha sett koden i loadChContent() tror jag nog att det är där du bör börja för att optimera saker.

Permalänk
Medlem
Skrivet av Ernesto:

Om det tar längre än 30s är ju inte problemet att php execution time är för låg, utan att scriptet är på tok för långsamt.

Allt som tar längre än 1 sekund är generellt klassificerat som dåligt, då man blir irriterad som användare och siten känns klumpig.

Om du inte kan trimma loadChContent() så att den blir snabbare, bör du kanske ladda kanalerna asyncront med ajax. - Skicka ut 8 stycken frågor för 8 kanaler, sätt in en loading placeholder i varje box som håller kanalerna och låt de ladda samtidigt. Kommer fortfarande vara irriterande, men inte lika irriterande.

Utan att ha sett koden i loadChContent() tror jag nog att det är där du bör börja för att optimera saker.

loadChContent() läser först in html kod från en webbsida. Sedan parsar den koden så att bara tid och programinnehåll tas ut och sedan sparar den det i databasen.

Kör jag loadChContent() individuellt, alltså kör funktionen sedan ändrar jag vilken kanal manuellt som den ska hämta och kör funktionen igen. Men kör jag den genom whileloopen så tar det för lång tid. Finns det inget sätt att köra koden engång paus köra koden igen? Testade med sleep() men det gjorde itne saken bättre eftersom den räknar det bara som en körning.

Visa signatur

Apple Mackbook Pro 15" Retina 2013

Permalänk
Medlem

Jag tror du bör göra de olika uppgifterna separat - d.v.s parsa kanalsidorna med ett jobb, sen spara ner resultatet i databasen och sedan rendera informationen på din sida därifrån istället.

Alternativt att du cachar resultatet från webbsidan du scrapar från och parsar det lokalt.

Att scrapa live kommer alltid ta alldeles för lång tid så länge du måste parsa html och inte bara läsa xml/json

Permalänk
Medlem

Min tanke är att första gången jag vill se kanalinformationen så kollar funktionen mot databasen om det finns något innehåll. Finns där inte det så hämtar den infon från websidan och samtidigt sparar ner det i databasen. När man sedan besöker samma kanal igen som finns det redan i databasen och då hämtas informationen där ifrån.

Men vill jag t.ex. visa säg 8 kanaler samtidigt och informationen inte finns i databasen så måste jag hämta informationen från 8 olika sidor. Det tar ca. 5s att köra loadChInfo() när den ska hämta htmlkoden. Kör jag då funktionen för att hämta 8 kanaler samtidigt så tar det 40s och begränsningen träder i kraft. Värre blir det när jag ska ladda 50+ kanaler samtidigt.

Om jag har en array med olika kanalnummer (1-50). Kör jag en loop och hämtar kanal 1, sedan kanal 2 osv så kommer begränsningen in. Kan man köra den koden på ett annat sätt? Den tolkar ju hela loopen som en körning. Kan man göra om det så att den tolkar loopen som enskilda körningar om ni förstår vad jag menar?

Visa signatur

Apple Mackbook Pro 15" Retina 2013