Autor Zpráva
Tequily
Profil
Zdravím,

má file_get_contents nějaký limit?

Jde o to, že čtu textový soubor s produktama a ten má cca 130 000 řádků.

Dnes jsem zjistil, že skript mi neprojde přes řádek 104220. Na dalším řádke se prostě zastaví.

Nevíte někdo v čem by mohla být chyba, případně nějaký jiný způsob jak číst soubor po řádcích a spolehlivě?
Tori
Profil
Např. po řádcích pomocí fgets (v manuálu je příklad).
Chyba může být např. v příliš velké spotřebě paměti. Ostatně mělo by vám to nějakou chybu hlásit, nemáte vypnuté zobrazování chyb?
Tequily
Profil
Tori:
Někde jsem četl, že fgets má problémy s velkými soubory (tento má 60Mb), je to možné?

Chybu to žádnou nehlásí, bohužel. Prostě se skript zastaví. V průběhu si skládám SQL dotaz, který se pak i úspěšně vykoná, ale pouze se 104 220 IDčky.
Tori
Profil
Tequily:
Aha, no tak to pak ale nemusí být chyba čtení ze souboru, ale např. překročení max. délky SQL dotazu nebo kolize ve sloupci s unikátním klíčem. Nechte si vypsat ten SQL dotaz, jestli obsahuje to co má. Pokud ano, pak je problém někde mezi skriptem a DB. (třeba jednoduchý test - pokud místo INSERT použijete INSERT IGNORE a vloží se jiný počet řádků, tak je problém v pokusu vložit duplicitní hodnotu do sloupce s unikátním klíčem)
Tequily
Profil
Tori:
Ještě jinak, asi to špatně popisuju. Přiložím část kódu.

if($knihy > 104220) var_dump($atribut)."<br />";
$knihy++;

Výsledek:
array(4) { [0]=> string(8) ""0126010" [1]=> string(21) "Světová válka měn" [2]=> string(21) "Světová válka měn" [3]=> string(19) "Euro, zlato, nebo j" }

Celé pole má obsahovat 29 položek. Navíc, by se mělo vypsat dalších cca 20 000 knížek.

V SQL (pouze UPDATE pomocí CASE WHEN) chyba není, tím jsem si jist, zásadním problémem je právě počet přečtených záznamů.
Davex
Profil
Tequily:
Nemůže být chyba někde před nebo po načtení souboru? Třeba při uploadu souboru na server nebo při vytváření pole?
Tequily
Profil
Davex:
Právě že ne.
Když si soubor stáhnu k sobě a zobrazím, je v pořádku.
Když si vardumpuju $atribut, tak to vypisuje vše správně.

$atribut = explode('","', $v);

U té poslední knížky je napsáno Euro, zlato, nebo jan - která z měn se stane nástupcem dolaru?
Takže explode to nijak neomezí. A právě po tomhle, už se nic dál nepřečte, takže jediné co mě napadlo, je nějaká maximální velikost souboru, která lze přečíst.

Takže jediná možnost, která mě napadá, je rozdělit soubor na části.
Davex
Profil
Tequily:
Pokud se soubor načte celý, tak problém není ve čtení.

ini_set('display_errors', 1);
error_reporting(E_ALL);
echo strlen(file_get_contents('soubor'));
Tori
Profil
Tequily:
Někde jsem četl, že fgets má problémy s velkými soubory (tento má 60Mb), je to možné?
Zkoušela jsem to dohledat, ale možná se to týkalo spíš dlouhých řádků? Viz např. http://stackoverflow.com/a/242067.
Z 590MB souboru (několik desítek znaků na řádek, přes 10^7 řádků) je fgets schopné číst i miliontý řádek.

Nečtete ten soubor z URL (=jestli nedojde k timeoutu nebo nějaké jiné chybě při přenosu dat)? A na jednotlivé řádky rozdělujete pomocí explode("\n", file_get_contents(...)) či jinak?

jediné co mě napadlo, je nějaká maximální velikost souboru, která lze přečíst. [...] Takže jediná možnost, která mě napadá, je rozdělit soubor na části.
Anebo číst pomocí fread po třeba 5-10MB velkých blocích, rozsekat na řádky a zpracovat, poslední (= necelý) řádek přilepit k následujícímu bloku.

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: