Autor Zpráva
rabbit
Profil
Už ve více situacích jsem narazil na podobný problém. Obecně jde asi o následující:

Bývají situace, kdy vykonávaný php skript na serveru je z důvodů výpočetních/updatovacích časově náročný, přičemž se jedná o dodatečné výpočty prováděné až po vrácení výstupu (resp. z těchto výpočtů už není žádný výstup, jde pouze o update stavu databáze).

Prohlížeč zašle požadavek na server, ten začne zpracovávat příslušný skript a vracet prohlížeči výstup. Dokud však běh skriptu neskončí, apache neukončí spojení s prohlížečem. Dá se nějak za běhu skriptu oznámit apachi a tak i prohlížeči, že už nebude žádný další výstup? Tak, aby zbytek skriptu proběhl "na pozadí"?

Doufám, že je to jasné, jinak případně doplním konkréta.
Leo
Profil
Otazka jasna je, s odpovedi je to horsi (aspon u me), takze je to zajimavy dotaz :-) PHP ma prostredky pro pripad, ze spojeni ukonci klient

http://php.ftp.cvut.cz/manual/en/features.connection-handling.php

ale vy chcete ukoncit spojeni z iniciativy serveru, resp. PHP. Zkusil bych output buffering, pak flush a pridat hlavicku Content-legth (musite jeste vedet jestli se to gzipuje atd.) Mozna to jde mnohem jednoduseji, ale z hlavy nevim. Zkuste experiment, nebo se primo poptat na Builderu v sekci PHP

http://forum.builder.cz/list.php?f=20

Tam to urcite bude nekdo vedet. Leo
Acci
Profil
Jediné, co mě napadá, je někde na začátku skriptu dát
header('Location: http://www.example.org'); 

Skript by měl doběhnout a prohlížeč se přesměruje na jinou adresu.
Leo
Profil
To je podle me nesmysl. Provede se presmerovani, a to asi nechceme. Chceme do prohlizece vystup a kod 200 OK. Leo
koudi
Profil
Acci
To je docela dobrej nápad.
koudi
Profil
Leo
Proč? Další výstup už nebude třeba (aspoň tak sem to pochopil) >Tak, aby zbytek skriptu proběhl "na pozadí"?
Leo
Profil
Samozrejme idealni by bylo predelat aplikaci tak, aby se casove narocne veci pri kazdem pozadavku na stranku nedely, pokud prace s db trva dyl jak sekundu, tak je nekde neco spatne, asi. Ale kdo vi, co se zpracovava... Leo
Leo
Profil
"Další výstup už nebude třeba"

DALSI vystup. Takze uz nejaky byl. A pak vam Location udela co? :-) A co udela prohlizec? Uvidi uzivatel html vystupu? Leo
koudi
Profil
>pokud prace s db trva dyl jak sekundu
Tak to maj asi někde ucpaný trubky :)
koudi
Profil
Leo
Samozřejmě, že další už neni možný. Ale je možnost nedat žádný a přes location to poslat na stránku, kde je něco jako "zpracovávám", nebo co já vim. Takhle se to blbě odhaduje, co to má dělat a jak se to chová.
Hugo
Profil
A co spustit jen malý skript, který zavolá jiný skript a skončí. Tím by se to mohlo vyřešit.
rabbit
Profil
Tak jsem rád, že se našlo pár ideí. Pro lepší představu nastíním jednu z praktických situací:
U aplikací sledujících návštěvnost stránek se na sledovaných stránkách volá se script, který má vrátit obrázek (ikonu) vloženou do stránky. Zároveň s jeho vygenerováním/zasláním (resp. po něm) je třeba provést update databáze (statistiky atp.), které jsou výpočetně náročnější. A protože např. na stránce není zavolána JS akce onload(), dokud není načten celý obsah, čeká se i na dotažení této ikony. Pak jsou delší čekací doby nepřípustné.
Samozřejmě, jedna možnost je oddělení funkcí - místo provedení všech operací jen zapsat údaje potřebné pro další zpracování do nějaké fronty, která je zpracovávána např. dávkově cronem, ale už to není aktuálnost v reálném čase.

Z výše popsaného snad vyplývá, že header(Location:...) není to pravé ořechové.

To Leo... vyzkouším ten output buffering, výpočet jeho obsahu a tu hlavičku Content-length. Jen tuším, že by měla asi být zapsána/zaslána před flushem ;-)
Btw. Ten kod 200 OK se zasílá na konci skriptu?

add. koudi
>pokud prace s db trva dyl jak sekundu
Tak to maj asi někde ucpaný trubky :)

Mno, občas pracuji s optimalizovanými (bez ironie) aplikacemi/db, které zpracovávají data i v řádu minut ;)

add. Hugo "A co spustit jen malý skript, který zavolá jiný skript a skončí. Tím by se to mohlo vyřešit."
Nevím přesně, co myslíte ... include(), require() ... to vše se vkládá dovnitř skriptu, takže skript sám bude pokračovat až po provedení. Stejně tak virtual().
Kajman_
Profil *
Z výše popsaného snad vyplývá, že header(Location:...) není to pravé ořechové.

Myslím, že to stále je možné. Jen se to rozloží na dva skripty.

No a pokud ten přístup ukládáte do db a umí triggery a vlastní procedury, tak by se to dalo updatování db řesit přes to.

Nebo si prostě v systému spusťte php parser na výpočetní skript, tak aby se na výsledek nečekalo.
rabbit
Profil
Kajman_
Dělám většinou v PostgreSQL a samozřejmě triggery i procedury využívám. To je taky možnost, ale opět je třeba zajistit, aby se nečekalo na output z db.

Tomu s tím parserem asi nerozumím, můžete to upřesnit?
Hugo
Profil
rabbit

No, já jsem to myslel spíš tak, že by se pomocí system() zavolal jiný skript, který potom poběží na pozadí, takže původní skript skončí. Ale nevím jestli to bude vyhovovat tvým požadavkům.
Hugo
Profil
rabbit

No, já jsem to myslel spíš tak, že by se pomocí system() zavolal jiný skript, který potom poběží na pozadí, takže původní skript skončí. Ale nevím jestli to bude vyhovovat tvým požadavkům.
rabbit
Profil
Použití system() je kulišácké řešení ... spuštění druhého skriptu přes příkazovou řádku? Kdyby to pomohlo, tak proč ne ;) Podle dokumentace ale soudím, že by výsledek byl jako u include(), stejně by se ten skript zasekl u toho system() a čekal na jeho dokončení.

Nebrat prosím srovnání s include() doslova ... vím, že jde o úplně jinou funkčnost.
Hugo
Profil
rabbit

Pokud to pustíš na pozadí, tak to poběží samo a ten původní skript skončí.
Toto téma je uzamčeno. Odpověď nelze zaslat.