Autor Zpráva
Trdlo
Profil *
Existuje nějaká možnost v PHP stáhnout rozměrnější soubor (2.3 Mb) na webhosting? Soubor je na adrese http://stranka.cz/soubor.gz.
Snažím se zkrátka rozbalit spakovaný soubor z url a uložit ho do databáze.
- Pokud se ho snažím rozpakovat PHP skriptem přímo z url pomocí funkce gzfile(), tak to dlouho trvá a vyhodí mě to.
- Pokud ho stáhnu "ručně" na webhosting a snažím se ho rozpakovat pomocí PHP skriptu, tak je málo paměti na serveru a vyhodí mě to .
- Pokud to dokonce "ručne" stáhnu i rozpakuji, tak to PHP skript nedá do databáze, protože to dluho trvá (Fatal error: Maximum execution time of 30 seconds exceeded).
Přitom jistě vím, že to jiným funguje. To je opravdu 2.3 Mb tolik? Záleží to pouze na webhostingu? Jak v PHP zpracovávat rozměrnější soubory? Jak je stahovat z url na webhosting? Jde to nějak po kouskách? Je vůbec 2.3 Mb rozměrnější soubor? A co na to Zelený Raoul?
P.S. snažil jsem se GOOGLEovat, ale s výrazy php, download, webhosting a file to opravdu nejde. :-( Předem díky i za pochopení :-)
Joker
Profil
Trdlo:
Přitom jistě vím, že to jiným funguje.
Třeba ti "jiní" mají k dispozici více paměti nebo delší maximum execution time (případně výkonnější server, takže zpracování netrvá tak dlouho)?

I když se mi nezdá, že by vložení 2MB do databáze trvalo přes 30 sekund.
kvoky
Profil
Trdlo:
A na lokálu ti to šlape?
Trdlo
Profil *
kvoky: na localhostu mám taky Fatal error: Maximum execution time of 30 seconds exceeded - co to znamená ?
Majkl578
Profil
Trdlo:
Google translator neznáme? Kupodivu to přeložil poměrně dobře.

Doporučuji optimalizovat script nebo zvýšit hodnotu max_execution_time.
Trdlo
Profil *
Majkl578: jak už jsem napsal "... s výrazy php, download, webhosting a file to opravdu nejde"

kvoky: když jsem na localhostu zaměnil mysql_query za echo, tak to vypsalo, co chci, ale to vypisování trvalo odhadem několik desítek sekund a pak se na několikatisícím řádku napsalo opět Fatal error: Maximum execution time of 30 seconds exceeded
Trdlo
Profil *
... takže, kdyby se změnila ta hodnota max_execution_time, tak by to možná šlapalo?
Trdlo
Profil *
Zvýšení max_execution_time akorát prodloužilo agónii a zamrzlo to na id=99000 (tabulka má pouze 7 sloupců, 2Mb), optimalizovat skript, který má dva řádky - jeden gzfile( ) a druhý mysql_query("INSERT INTO..) asi taky nepůjde. Jak to ti lidi, co stahují z url XML-FEEDy např. se zbožím s eshopů dělají?
mattyZEM
Profil
Tak to budeš muset rozdělit :P
Trdlo
Profil *
mattyZEM: to bych chtěl, ale jak to mám udělat s komprimovaným souborem '.gz' , na který mám odkaz pouze url: http://..../...gz ? To se asi nedá nějak rozpakovávat postupně...nebo dá?
Alphard
Profil
Trdlo:
kvoky: když jsem na localhostu zaměnil mysql_query za echo, tak to vypsalo, co chci, ale to vypisování trvalo odhadem několik desítek sekund a pak se na několikatisícím řádku napsalo opět Fatal error: Maximum execution time of 30 seconds exceeded
V tom vidím problém, snad neprovádíte několik tisíc dotazů do databáze. To by položilo i server googlu :-)

Znáte tuhle syntaxi?
insert into tabulka (slupec) values
('1. řádek'),
('2. řádek'),
('3. řádek'),
('4. řádek'),
('n. řádek')


Bez kódu se můžeme jen dohadovat. Ukažte nám svůj script, ať je kde začít.
Trdlo
Profil *
Alphard: problém asi bude v nějakém nastavení
$lines = gzfile(http://file.gz');
if(!is_array($lines)) die("Chyba"); 
foreach($lines as $line) {
	list($i, $n,$x, $y, $p, $ps, $r) = explode(',', $line);
	$n = urldecode($n);
	$n = addslashes($n);
	echo 'i='.$i.' n='.$n.' x='.$x.' y='.$y.' p='.$p.' ps='.$ps.' r='.$r;
	//mysql_query("INSERT INTO table SET i='$i', n='$n', x='$x', y='$y', pr='$pr', ps='$ps', r='$r'");
	}

mysql_query jsem odkomentoval, protože to nic nedělalo a dal jsem tam to echo - to konečně vypisuje, co chci, ale vypisuje, vypisuje a sekne se...
asi nějaké nastavení.... nevím
Trdlo
Profil *
Alphard: takže problém je podle Vás foreach, že se dělá ve smyčce moc dotazů?
Alphard
Profil
Zkouším trochu upravit váš script, dejte mi pár minut.
Alphard
Profil
Nějak takhle, píši to zpaměti, takže tam asi budou překlepy, ale filozofie je asi jasná.
<?php
$temp = "./temp.gz";
copy('http://file.gz', $temp); // nevím, jak přesně pracuje gzfile, ale tohle by mohlo být rychlejší

$lines = gzfile($temp);
if(!is_array($lines)) die("Chyba");
foreach($lines as $line) {
    list($i, $n,$x, $y, $p, $ps, $r) = explode(',', $line);  // přístup přes pole a klíče, tj. $line[2] by byl asi trochu rychlejší
    $n = urldecode($n);
    $n = addslashes($n);
    $buffer[] = "('$i', '$n', '$x', '$y', '$p', '$ps', '$r')";
    
    if(count($buffer) > 500)
    {
      mysql_query("insert into table (i, n, x, y, pr, ps, r) values ".implode(",", $buffer));
      $buffer = array()
    }
    }
if(count($buffer)>0)
{
  mysql_query("insert into table (i, n, x, y, pr, ps, r) values ".implode(",", $buffer));
}
unlink($temp);


Edit, zapomněl jsem na poslední krok :-) opraveno.
Trdlo
Profil *
Alphard: Velké díky mistře!!! Nechápu, nerozumím, ale zítra, jak se vyspím, tak si to rozeberu! Teď už na to nemám, tak se alespoň vyspím do růžova. Nejen stroje, ale i lidi musí vydávat výkony! Nevěřil bych, že úprava skriptu, co má pár řádků, přecigání paměť a výkon serveru :-D . Ještě se mám, co učit. Zatím dobrou.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: