Upload velkých souborů v IIS7 a PHP
Září 17th, 2009
Pokud potřebujete v PHP povolit upload velkých souborů, jistě víte, že stačí v php.ini přenastavit hodnoty post_max_size a upload_max_filesize (nevím jak pro apache, pro IIS7 jsou nutné obě hodnoty, stejně tak je třeba do formuláře, který data odesílá vložit alespoň jeden standardní post element – třeba hidden, jinak php nedostane ani uploadovaný soubor). Toto řešení vám bude bez problémů fungovat lokálně, ale ne, jakmile přesunete web na reálný server, tam na vás při uploadu většího souboru vyskočí anonymní chybová hláška:
Unspecified error (0×80004005)
žádná větší konkretizace, než že se jedná o chybu při spouštění fast-cgi modulu php vás už nečeká. Dlouho jsem hledal v čem vůbec problém vězí a jaké je jeho řešení, nakonec jsem příčinu našel a to ve standardních limitech FastCGI.
IIS7 obsahuje jeden drobný, nepěkná věc – totiž modulům hlídá maximální čas vykonávání, ale hlídá ho i ve chvíli, kdy teprve přicházejí request data. A protože většina uživatelů není schopná odesílat soubory rychlostí páteřní linky, překročí časový limit a php je násilně ukončeno ještě dříve, než se spustí vykonávání vašeho skriptu.
Řešením je úprava konfigurace IIS a nastavení časových limitů ručně – to bohužel nelze provést přes grafické rozhraní, ale modifikací konfiguračního XML souboru:
c:\windows\system32\inetsrv\config\applicationHost.config
(budete potřebovat administrátorská práva, takže ve Windows Vista / 2008 je třeba editor spustit jako správce)
tam naleznete řádek:
<application fullPath=„C:\PHP5\php-cgi.exe“ />
nebo jemu velmi podobný a upravíte jej na následující:
<application fullPath=„C:\PHP5\php-cgi.exe“
requestTimeout=„3600“ />
tím nastavíte limit na zpracování požadavku na jednu hodinu. Teď už stačí jen restartovat IIS, aby se nová nastavení načetla.
Pokud potřebujete nastavit i čas běhu skriptu, případně zvýšit frontu požadavků na jednu instanci php, je tu přo vás rozšířené nastavení:
<application fullPath=„C:\PHP5\php-cgi.exe“
activityTimeout=„3600“ requestTimeout=„3600“
instanceMaxRequests=„10000“>
<environmentVariables>
<environmentVariable name=„PHP_FCGI_MAX_REQUESTS“ value=„10000“
/> </environmentVariables>
</application> jen je třeba nezapomenout
maximální počet požadavků sdělit i PHP pomocí oné environment
variable.
Home
Září 17th, 2009 at 13.26
Hezká finta :) Timeout samotného PHP to ale neovlivní, že… tzn. stále hrozí, že by třeba transformace obrázku mohla způsobit timeout? (logicky a očekávatelně)
Září 29th, 2009 at 13.58
Neovlivni, timeout php je samozrejme potreba nastavit v php.ini nebo pomoci inisetu ;) tady slo o to, ze iis si veskere FastCGI procesy samozrejme hlida a urcuje jim jak dlouho mohou vytezovat system.