ugrás a tartalomhoz

File letőltés

alkony4 · Ápr. 22. (P), 20.22
Tisztelet!

Tudna valaki abban segíteni, hogy az alábbi kódot, hogy lehet úgy módisítanom, hogy fennmaradjon az oldal és a kliens között az interakció?

(ez egy külön fileban fut, mondjuk download.php de közben minden más meghal az oldalon)

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename;
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $filesize);

ob_clean();
$handle = fopen($filedir, 'rb');
while (!feof($handle)){
	echo fread($handle, 5242880);
	ob_flush();
	flush();
	sleep(1);
}
fclose($handle);
Főként azért szeretném ezt a kódot alkalmazni, mert a nagy fájlok letöltésévél meggyűlt a bajom és ez tökéletesen megfelelt erre a célra.

Válaszaitok előre is köszönöm.
 
1

Hali!

Pepita · Ápr. 25. (H), 08.01
A 16. sorban a sleep(1); mire kell? Korlátozni akarod a letöltés sebességét 5 MB/s körülire? (Egyébként lassabb lesz, mert azután vár 1 secet, miután már lement az 5 mega.)

úgy módisítanom, hogy fennmaradjon az oldal és a kliens között az interakció
Ha egy link mutat a download.php - re, akkor a legegyszerűbb a target="_blank" attribútummal új lapon / ablakban "nyitni" a letöltést, így az eredeti megmarad.
Mondjuk elvileg ugyanazon ablakban is meg kéne maradnia, csak elindul egy letöltés, de gyanítom, hogy nem ez a teljes download.php, így nem látom a konkrét okot.

Interakció alatt ugye azt értetted, hogy marad felület, ahova tud kattintani?
2

Köszi a választ, némi keresés

alkony4 · Ápr. 25. (H), 17.56
Köszi a választ, némi keresés kutatás után rájöttem mi a probléma. Illetve arra is rájöttem, hogy ennek fényében eléggé pontatlanul tettem fel a kérdést.
Van egy adott oldal, mindenféle dinamikus oldal betöltessél stb.
Van egy linkünk ami a download.php-re mutat (és a sleep valóban a korlátozást hivatott előidézni). És amíg a download.php pörög (külön lapon), masszívan dolgozik a php és magán az oldalon közbe megszűnik minden server irányába történő lekérdezés mert a download.php befoglalja. Mint kiderült a php nem képes párhuzamos munkamenet kezelésre. Ezért megoldásként egy redirectelt vhostot hoztam létre ami mindig másik vhoston kezdi el betölteni a tartalmat (így működik a párhuzamosítás).

Tehát ugyan a probléma megoldódott, azért érdekelne, hogy van e erre pure megoldás.

Továbbá nagyon köszönöm a segítőkész válasz kolléga : )
3

Azért ez így nem feltétlenül

mind1 valami név · Ápr. 25. (H), 18.22
Azért ez így nem feltétlenül igaz.
Most nem tudok linket hozni, de a php multi threading (miért három szó, azt nem tudom) kifejezésre keresve az elsők közt van egy jó régi stackoverflow találat, amiben ezt részletezik.
Ha maga a php egy szálon is fut, a web szervernek szerintem meg lehet mondani, hogy hány "worker" fusson.
Pythonnál is ez volt a bajom, míg rá nem jöttem, hogy tud ilyet: a python kód egy szálon fut, de sok példányt indít az nginx.
5

Szerintem

Pepita · Ápr. 29. (P), 08.21
Szerintem erre gondoltál.

Viszont ez is csak parancssori módban működik (egyébként úgy tűnik, már nem fejlesztik, elavult), PHP dokumentációból:

Warning
The pthreads extension cannot be used in a web server environment. Threading in PHP is therefore restricted to CLI-based applications only.


Egyébként a php önmagában (és webszerver "mögött" is) multi threaded, nem azon múlik a fenti "homokórázás". Talán valamilyen webszerver-beállításon, de ahhoz a részéhez nem értek eléggé.
6

Valószínű. Azt hiszem, privát

mind1 valami név · Ápr. 29. (P), 08.40
Valószínű. Azt hiszem, privát módban futott a böngésző, mert a history-ból nem tudtam előszedni már akkor sem. :)

A végét viszont nem értem. Hogyhogy önmagában multithtraded?
Szerintem a PHP nagyon nem az. Pláne így, hogy azt a modult/library-t/stb nem is fejlesztik már.

A mt azt jelenti, hogy pl közös memórián, egyéb erőforrásokon osztoznak a szálak. Ha csak a processzeket listázod, csak egy processzt látsz. A multiprocess környezet más (szerintem ez van PHP esetében), azok önálló programként futnak.
De a PHP önmagában szerintem ezt sem tudja. Az elé rakott web szerver indít több processzt.
(Azért jó lenne, ha ezt valaki megerősítené, mert már túl sok dolog esett ki nekem :(( )

Pythonnal én egy Flask nevű keretrendszert használok, annak már sikerült meglepetést okoznia. Valódi mt működést akartam egy teszt kedvéért, akkor derült ki, hogy a flask saját web szervere tényleg több szálon futtatja az applikációt.
7

multithtraded

Pepita · Május. 6. (P), 08.55
önmagában multithtraded: képes ugyanazon a vason több szálon-példányban futni (és ezt magától tudja, nem kell hozzá plusz eszköz).

A mt azt jelenti, hogy pl közös memórián, egyéb erőforrásokon osztoznak a szálak
Ezzel nem értek egyet. Ha nincs szükség megosztott erőforrásra, akkor már nem nevezhető mt-nek? Szerintem ez nem a megosztott resource függvénye.
Viszont ezzel rávezettél a megoldásra, l. lentebb.

De a PHP önmagában szerintem ezt sem tudja. Az elé rakott web szerver indít több processzt.
Vagy éppen indít párat a web szerver, párat pl cron job (és semmi köze a webszerverhez), van néhány, ami szintén cli és folyamatosan fut (pl MQ csatorna fogadója, websocket, stb) és ezek mind egyidejűleg futnak. Ha annyira ragaszkodunk a közös erőforráshoz, a forráskód mindenképp az, és legtöbb esetben van legalább 1 adatbázisunk is.

A probléma: jelen esetben leginkább a session, mert az bizony természeténél fogva nem "mt-képes", az üzleti logikájából fakadóan egyszerre csak egy szál férhet hozzá, mert megváltoztathatja, ezért a session_start lockolja, a session_write_close "engedi el".
Vagyis a fenti probléma az, hogy a lassított letöltés ameddig fut, addig másik szál nem fér hozzá ugyanahhoz a session-höz.
Megoldás: a lassú szál ne használjon sessiont. Ha felhasználóhoz - jogosultsághoz kötött a letöltés és mindenképpen lassítani kell, akkor pl a link kirakásakor generálni kell egy ideiglenes tokent, amihez a szükséges adatok adatbázisban vannak, a letöltés indításakor ezt kell ellenőrizni és a további felhasználását tiltani. Így ez a szál nyugodtan lehet lassú, nem blokkolja a másik szál session-ét.

A lassításra pedig sokkal jobb Endyl megoldása, vagy valami ahhoz hasonló.
8

A több szál és a több példány

mind1 valami név · Május. 6. (P), 10.03
A több szál és a több példány nem azonos fogalmak.
Nagyon nem mindegy, hogy több szál vagy több processz a több példány.

A mt (egyik?) lényege, hogy kisebb "költséggel" tud párhuzamos működést biztosítani, mint a mp (multiprocessing). Viszont vannak elég komoly megkötései, amiket így fejből nem tudnék felsorolni. Annyi biztos, hogy mt programokat csak ú.n. "thread safe" alkatrészekből szabad összerakni, különben elég fura, random jelentkező hibákat produkálhat a program.

Ami példákat hoztál, azok multiprocess környezetben működnek.
Egy mq olvasás még elképzelhető threadként, csak viszonylag kevés értelme van ilyen felállásban, de egy cron job már mindenképpen külön processz.

olvasnivaló - a browseres példája pont nem jó, mert manapság biztonsági okok miatt önálló processzbrn futnak a tabok. :)
4

Rate-Limit?

Endyl · Ápr. 26. (K), 11.28
Ha csak a letöltés sebességének a korlátozása a cél, akkor a php-s hackelés helyett inkább az apachera (vagy a szerver szoftverre, legyen az bármi is) bíznám a feladatot (pl: mod_ratelimit? Link).
<IfModule mod_ratelimit.c>
    <!-- 100kb/second limit -->
    <Location /tier1>
        SetOutputFilter RATE_LIMIT
        SetEnv rate-limit 100
    </Location>

    <!-- 500kb/second limit -->
    <Location /tier2>
        SetOutputFilter RATE_LIMIT
        SetEnv rate-limit 500
    </Location>
</IfModule>