Zadejte hledaný výraz...

Zápis do.gz za běhu

crs
verified
rating uzivatele
(1 hodnocení)
16. 1. 2021 02:17:20
Zdravím,
Mám projekt na webhostingu, kde mi zbývá 20 MB do FTP kvóty a potřebuju zapisovat do textového souboru, který má rozbalený 26 MB a sbalený 2 MB (ve formátu .gz, který preferuju).
Prozatím nechci připlácet za místo.
Chtěl bych soubor zabalit bez překročení kvóty.
Zkoušel jsem:
$fp = fopen("compress.zlib://soubor.txt.gz");
fwrite($fp, "...");
fclose($fp);
---
$gz = gzopen("soubor.txt.gz", "wb");
gzwrite($fp, "...");
gzclose($fp);
---
$output = "";
unlink("soubor.txt.gz");
$output = gzencode($output, 9); // zkoušel jsem různé parametry komprese i FORCE_GZIP i FORCE_DEFLATE
file_put_contents("soubor.txt.gz", $output); // nebo zápis $output přes fopen() a fwrite();
---
Všechno selže - hodí chybu 500. Předpokládám, že oba způsoby se dočasně snaží vytvořit 26MB soubor, narazí na kvótu a skončí chybou. (Kdyžtak upozorněte, pokud je to chybný předpoklad.)
Zkoušel jsem velikost nesbaleného souboru omezit pod kvótu, pak ve všech případech vše dopadlo bez chyby.
Jestli víte, prosím, poraďte, jak soubor sbalit. Díky.
(hosting jede na PHP 7.3.26, ini(memory_limit)=128M, všechny běžné knihovny pro archivy povolené)
16. 1. 2021 02:17:20
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474953
TomasX
verified
rating uzivatele
(4 hodnocení)
16. 1. 2021 09:34:50
chtělo by to vědět tu chybu, kterou to vyhodí. Nechceš si jí někam vypsat?
Zkoušel jsi ty tvoje příklady s malými soubory, jestli to také vyhodí chybu?
Podle mě ty kódy nevytváří dočasný rozbalený soubor a dělají to in-memory
16. 1. 2021 09:34:50
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474952
jarocelebrate
verified
rating uzivatele
16. 1. 2021 11:40:31
Kdyby sis priplatil ta ten hosting, tak vlastně ne výsledku usetris víc, nez kdyz se s tom budes tyden mrdat
16. 1. 2021 11:40:31
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474951
crs
verified
rating uzivatele
(1 hodnocení)
17. 1. 2021 00:12:25
Napsal TomášX;1611627
chtělo by to vědět tu chybu, kterou to vyhodí. Nechceš si jí někam vypsat?
500 Internal Server Error - HTTP | MDN
Pokud před tím nezapíšu nic na výstup (tj. lze modifikovat HTTP hlavičky), pak se z výsledku nezobrazí nic a dostanu standardní hlášku 500 Internal Server Error (každý prohlížeč to interpretuje po svém). Pokud před tím něco na výstup zapíšu, tak v daném místě výstup HTML skončí. Nic mezi tím, ani pro error_reporting(E_ALL);
Napsal TomášX;1611627
Zkoušel jsi ty tvoje příklady s malými soubory, jestli to také vyhodí chybu?
Zápis menšího souboru je bez chyb (jak jsem zmínil).
Napsal TomášX;1611627
Podle mě ty kódy nevytváří dočasný rozbalený soubor a dělají to in-memory
Co znamená „in-memory“? A co ohledně toho mohu udělat?
Napsal jarocelebrate;1611665
Kdyby sis priplatil ta ten hosting, tak vlastně ne výsledku usetris víc, nez kdyz se s tom budes tyden mrdat
Strašně pomohlo, dík.
17. 1. 2021 00:12:25
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474950
skorozacatecnik
verified
rating uzivatele
17. 1. 2021 01:29:30
Pokud dobře chápu, otevření gz souboru pro zápis a samotný zápis malých dat funguje.
Ta data do souboru zapisuješ jako jeden celek, nebo jsi zkoušel i zapisovat po částech?
gzopen, fopen a pod. by měly jen otevřít soubor a v paměti si udržují ukazatel na pozici v tom souboru (proto in-memory = neměl by se vytvářet tmp file na disku)
17. 1. 2021 01:29:30
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474949
TomasX
verified
rating uzivatele
(4 hodnocení)
17. 1. 2021 01:39:32
No, já myslel tu chybu v php, která způsobila ten 500 Internal Server Error, je jedno, že to každý prohlížeč zobrazí jinak, je důležité vědět, proč jí php způsobilo. Pokud nepoužíváš nějaký framework, který to ošetřuje nebo nemáš přístup k php logům, můžeš si nadefinovat vlastní error handler, viz https://www.php.net/manual/en/function.set-error-handler.php
Tj. hoď úplně na začátek skriptu něco takovéhoto, odchytí to chyby a vypíše na výstup.
set_error_handler(function($errno, $errstr, $errfile, $errline ){
$err = htmlspecialchars($errstr);
echo "Error $errno on line $errline in file $errfile";
echo "$err";
});
Pokud chceš potlačit násilně tu 500 hlavičku (aby ti prohlížeč vypsal text chyby a ne jeho chybovou hlášku), stačí dát na začátek skriptu prázdné echo, vypíšou se tím hlavičky, pro jistotu i vypínám output buffering.
ob_end_flush();
ob_implicit_flush();
echo "";
Kód na první pohled vypadá dobře, teď jsem to vyzkoušel a v php 7 bez problémů zapíšu 1 MB soubor na 1,1 MB velký disk.
17. 1. 2021 01:39:32
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474948
crs
verified
rating uzivatele
(1 hodnocení)
18. 1. 2021 01:21:51
Napsal TomášX;1611740
No, já myslel tu chybu v php, která způsobila ten 500 Internal Server Error, ...
To bych také rád věděl. Žádná hláška se nevypisuje. Asi jsi automaticky předpokládal, že to tak musí být, ale není tomu tak. Díky za radu s error handlerem, ale nepomohla - ať s ním či bez něj dostanu buď vše bez chyb nebo 500 na úrovni serveru a nic mezi (jak jsem již psal). Ani, když echo v handleru změním na zápis do souboru, po spuštění se nevytvoří. Skoro jako by vykonávání skriptu utnulo něco o úroveň výš.
Btw, fwrite, gzwrite a file_put_contents při chybě nehází chybu, jen vrátí false. Zmínku o případu, kdy není dost místa, jsem na php.net nezahlédl. Po chvilce googlování jsem narazil akorát na hlášku "Disk quota exceeded (122) in /path/file at line #" viz, ale to může být specifické ke knihovně na dané stránce.
Napsal skorozacatecnik;1611739
Pokud dobře chápu, otevření gz souboru pro zápis a samotný zápis malých dat funguje.
Ano.
Napsal skorozacatecnik;1611739
Ta data do souboru zapisuješ jako jeden celek, nebo jsi zkoušel i zapisovat po částech?
Všechny způsoby, které jsem uvedl na začátku tohoto threadu.
18. 1. 2021 01:21:51
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474947
TomasX
verified
rating uzivatele
(4 hodnocení)
18. 1. 2021 02:24:27
používáš nějaký framework nebo redakční systém? Nějak se mi nezdá, že by chyba nešla odchytit a poslat na výstup. Ten error handler může někdo další přepsat.
Apache má php napojené přes (f)cgi, vyhazuje 500 pokud samotné php se ukončí (aka proces umře aniž by poslal chybu ven, to by byl nejspíš špatně natavený hosting a chyba v jejich systémovém logu).
Těžko říct bez dalších podrobností.
18. 1. 2021 02:24:27
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474946
TomasX
verified
rating uzivatele
(4 hodnocení)
18. 1. 2021 02:27:34
jaký používáš prohlížeč? Tuhle stránku s chybou neznám, výchozí vypadá jinak, to máš vlastní?
18. 1. 2021 02:27:34
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474945
crs
verified
rating uzivatele
(1 hodnocení)
18. 1. 2021 14:41:21
Napsal TomášX;1611843
používáš nějaký framework nebo redakční systém?
Ne - čisté PHP. Přemýšlím, že bych na to zkusil přidat Tracy, ale pochybuju, že by to pomohlo.
Napsal TomášX;1611843
jaký používáš prohlížeč? Tuhle stránku s chybou neznám, výchozí vypadá jinak, to máš vlastní?
Avast Secure Browser. V normálním Chrome je stejná chyba, zobrazená jinak.
18. 1. 2021 14:41:21
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474944
hm
verified
rating uzivatele
(20 hodnocení)
18. 1. 2021 14:56:09
Musis mrknout do error logu apache, uz leta se nedoporucuje an produkci mit vystupy php chyb primo do prohlizece, takze pokud mas hosting co to dodrzuje, tak se v prohlizeci nedozvis vic nez ze se neco nepovedlo...
prpadne muzes zkusit
ini_set('display_errors', 1);
zalezi jestli to hosting ma povolene, nektere ne...
18. 1. 2021 14:56:09
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474943
TomasX
verified
rating uzivatele
(4 hodnocení)
18. 1. 2021 15:50:31
zkus si to na jiném hostingu nebo u sebe. Případně sem hoď celý kód a výpis php ini. U všech tří variant tvého pseudokódu jsem byl schopný zapsat soubor na plný disk, pokud zapisuji více než se na disk vejde, php končí warningem a nikoliv fatal error.
Opravdu to s menším souborem zapíšeš bez chyby? Memory limit 128 MB je opravdu aplikovaný? Jakou velikost mají data, když jsou rozbalená, vejdou se do paměti a náhodou nekončí to na out of memory chybě kvůli vysoké efektivitě komprese?
18. 1. 2021 15:50:31
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474942
skorozacatecnik
verified
rating uzivatele
18. 1. 2021 17:29:05
Jakým způsobem se dostanou data do proměnné v php?
Jsou přijímána z POSTu, nebo jsou načítána ze vzdáleného zdroje, případně jak?
Pokud jsou přijímána z POSTu (resp $_FILES), tak to možná umře na tmp file, do kterého se ukládá vstup. K samotnému scriptu a ukládání gz pak vůbec nedojde.
$_FILES
"The temporary filename of the file in which the uploaded file was stored on the server."
Ten tmp file se možná (přišlo by mi to logické) bude počítat do diskové kvoty taky.
18. 1. 2021 17:29:05
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474941
crs
verified
rating uzivatele
(1 hodnocení)
20. 1. 2021 01:28:31
Napsal Aleš Jiříček;1611930
ini_set('display_errors', 1);
Díky moc, toto pomohlo.
Když to shrnu, vypsalo mi to hlášku, která sice souvisela s překročením místa v paměti -v procesu generování souboru-, ale ne s pakováním do .gz.
Po opravení vše funguje.
Díky všem za spolupráci.
20. 1. 2021 01:28:31
https://webtrh.cz/diskuse/zapis-do-gz-za-behu#reply1474940
Pro odpověď se přihlašte.
Přihlásit