[PHP] HELP! Error: 310 (RedirectLoop)
ik ben aan gigantische import aan het doen met een csv file.
Ik upload een bestand mbv een formulier, daarna kan ik dynamisch kiezen welke kolom bij welke tabel field hoort, en dan verwerken.
Dit process bevat importeren, bestanden downloaden, snapshot maken van video's, afbeeldingen bewerken (vierkant maken, en 4 verschillende formaten)
Iedereen begrijpt dat afhankelijk van wat voor soort bijlagen, en het aantal ervan zorgt voor nogal lange duur van uitvoeren. Dus om de timeout te omzeilen houdt alle gegevens bij in een sessie (gekozen kolom->field, filenaam waarmee gewerkt wordt, en de laatst geimporteerde record) en redirect terug naar de pagina (nu ondertussen naar een 2e en 3e))
Helaas geeft mijn firefox en chrome error 310 terug na enige tijd (Ongeveer na 15-18 redirects)
Ik zie het niet bepaald zitten om elke 300 records alles weer opnieuw te doen om m'n browser maar te gehoorzamen. Het moet juist andersom.
Hoe kan ik dit fixen? Ik zit nou al weken hier aan te werken. Eigenlijk voorheen importeer problemen, en het dynamisch maken van importeer mogelijkheden, downloaden van externe bestanden adv een url etc.
Heeft iemand een workaround hiervoor? Ik hoop het ten zeerste
Moet ongeveer 20.000 records doen om te beginnen, en naderhand zullen deze regelmatig ook nog eens een 'UPDATE' ondergaan.
Gewijzigd op 26/09/2016 20:35:47 door Dennis WhoCares
1) uit de database leest of er een actieve taak is.
2) uit de database leest bij welke regel/snapshot/afbeelding hij gebleven is de vorige keer
3) een aantal wenselijke bewerkingen uitvoert op een X aantal regels/snapshots/afbeeldingen
4) in de database schrijft waar hij gebleven is
5) de taak op inactief zet als alle regels/snapshots/afbeeldingen behandeld zijn.
6) een emailtje naar jou stuurt dat de taak volbracht is
Waarom doe je dit met de browser? Processing doe je toch gewoon op de commandline? Kan ook prima met PHP.
Ben van Velzen op 27/09/2016 00:03:49:
Waarom doe je dit met de browser? Processing doe je toch gewoon op de commandline? Kan ook prima met PHP.
Zat ik ook aan te denken :-)
Krijg je dan geen timeout vroeg ik me af?
Krijgt hij ook, en daar probeert hij met redirects omheen te werken.
max_execution_time standaard 0 voor oneindig. Je kunt ook proberen daarmee de time-out te voorkomen:
Of:
Als je PHP uitvoert vanaf de command line, is Of:
Maar.....wees er dan wel ZEKER van dat je script niet in een loop draait. Want de enige weg is dan een KILL-command op de CLI.
Of je past regelmatig je execution time aan, wanneer je met loops bezig bent bijvoorbeeld. Bij elke set_time_limit() call wordt immers de lopende teller gereset naar 0. Geeft je net even wat meer mogelijkheden om echte timeouts wel op te vangen.
Of je verbinding heeft 2 seconden de hik en je browser is de verbinding kwijt.
Dit soort processen doe je bij voorkeur via de command line of een cronjob.
Daarbij moet je je afvragen of dat dan in 1 grote job uitgevoerd wordt, of dat je elke 5 minuten iets wilt doen.
Als je voor dat laatste kiest, moet je er ook zeker van zijn dat de vorige job klaar is, of dat het geen probleem is als 2 of meer processen gelijktijdig draaien.
(oh, en die cronjob dan niet weer via wget toch een http-proces laten starten.)
mijn excuses voor de late reactie, ik kom net terug vanuit CZ... >.<
Iedereen hartstikke bedankt voor de reacties.
Deze import is eigenlijk maar 1 keer. Daarna is het alleen 'update' en alleen 'update' van tekst in de database, geen afbeeldingen etc meer.
Zoals ik hieruit begrijp in CLI heeft de commando 'php' geen timeout !?
Dan doe ik dit liever gewoon zonder te redirecten in 1 keer via CLI
Echter zal ik m'n redirects er weer uit moeten halen, en even wat verzinnen op m'n 'settings' die ik instel. Misschien een txt file of even hardcoded bijvoegen voor deze 'incidentele' actie.
Ik was al bijna van plan om alle afbeeldingen handmatig te downloaden (soort van dan, gewoon met 'curl -o <filename> "<url to file>"' en dan te gaan bewerken.
Komt ook weer het een en ander bij kijken.
Ik zal de execution time erbij doen voor de zekerheid zoals Ward van der Put aangeeft.
Ben van Velzen, betekend dit dat.. als ik set_time_limit(0) aan het begin en aan het eind van m'n for loop zet, dat ik geen timeout krijg ?
Want uiteindelijk moet zulke imports wel mogelijk zijn via de browser, eigenlijk...
De import zal nooit zo vreselijk lang duren, ik denk hooguit 3-4 minuten.
Frank Nietbelangrijk,
inderdaad, heb ik ook aan zitten denken. Ik doe hetzelfde met een ander project van mij op het werk, als de cronjob nog steeds als 'running' aangegeven staat, houdt ik ook bij hoevaak deze 'geblokkeerd' is en na 5 keer, dan wordt deze gereset en doet ie het weer.
Ik zou zelfs in de loop de tijd kunnen bij houden dat deze zelf al draait en dan na X minuten de data weg te schrijven voor de volgende 'trigger'.
Momenteel heb ik even last van migraine, maar ik ga morgen ermee aan de slag met de CLI. Is niet heel veel werk, maar nu eventjes niet ;)
Nogmaals bedankt allemaal!
Bijna. Als je het aan het begin van een loop zet, en je weet dat 1 keer loopen max 5 seconden kost zet je set_time_limit(5) aan het begin van je loop. Sowieso nooit 0. Om het via de browser te kunnen doen zul je je webserver instellingen moeten wijzigen om te zorgen dat er vanuit daar geen timeout komt, en natuurlijk regelmatig output naar de browser sturen om te voorkomen dat de browser geen timeout ziet.
Daarbij: je hoeft het helemaal niet via de browser te doen. Je kunt prima het proces starten in de browser (bijvoorbeeld via een upload), en dan laten overpakken door bijvoorbeeld een cronjob, die op een statuspagina weergeeft hoe ver de import is.
Gewijzigd op 27/09/2016 21:00:48 door Ben van Velzen
Ben van Velzen op 27/09/2016 20:48:07:
Daarbij: je hoeft het helemaal niet via de browser te doen. Je kunt prima het proces starten in de browser (bijvoorbeeld via een upload), en dan laten overpakken door bijvoorbeeld een cronjob, die op een statuspagina weergeeft hoe ver de import is.
Daar had ik eigenlijk nog nieteens aan gedacht :-$
Thanks! Dat is natuurlijk de beste oplossing.
ofwel upload je iets met de browser, waarbij in map /x/y een bestand geplaatst wordt, en elke 5 minuten kijkt een cronjob of daar iets te doen is.
ofwel trigger je met de browser een commando, dat doorloopt terwijl de output naar de browser daar niet op wacht.
voorbeeld uit een script van mij dat op de achtergrond een berg pdf's maakt en daarna uitprint:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$command = ('/usr/bin/nohup /usr/bin/php ' . CLI_DIR . 'print.php' . ' ' . $sType . ' ' . $args . ' ' .
' > ' . CLI_OUTPUT . '.' . time() . '.txt' . ' & echo $!');
?>
$command = ('/usr/bin/nohup /usr/bin/php ' . CLI_DIR . 'print.php' . ' ' . $sType . ' ' . $args . ' ' .
' > ' . CLI_OUTPUT . '.' . time() . '.txt' . ' & echo $!');
?>
nohup en & echo $! zorgen dat eea op de achtergrond uitgevoerd wordt.
/usr/bin/php is de plek waar php staat.
Het path naar de scripts voor cli staat in de constante CLI_DIR en print.php het script dat ik aanroep.
omdat we hier geen print.php?type=a&id=10 kunnen gebruiken, staan de argumenten er gewoon achter.
net als je "cp a b" kunt doen om het commande cp te vertellen dat hij iets moet doen, kan dat ook voor een php script.
met > outputfile kun je de output die eventueel komt, wegschrijven naar een file, om later terug te kijken of alles zonder fouten verlopen is.
Je kunt uiteraard ook in de database, of naar een mailbox je meldingen laten versturen.
Ivo P op 28/09/2016 09:08:40:
hierin zijn ook nog 2 varianten:
ofwel upload je iets met de browser, waarbij in map /x/y een bestand geplaatst wordt, en elke 5 minuten kijkt een cronjob of daar iets te doen is.
ofwel trigger je met de browser een commando, dat doorloopt terwijl de output naar de browser daar niet op wacht.
voorbeeld uit een script van mij dat op de achtergrond een berg pdf's maakt en daarna uitprint:
nohup en & echo $! zorgen dat eea op de achtergrond uitgevoerd wordt.
/usr/bin/php is de plek waar php staat.
Het path naar de scripts voor cli staat in de constante CLI_DIR en print.php het script dat ik aanroep.
omdat we hier geen print.php?type=a&id=10 kunnen gebruiken, staan de argumenten er gewoon achter.
net als je "cp a b" kunt doen om het commande cp te vertellen dat hij iets moet doen, kan dat ook voor een php script.
met > outputfile kun je de output die eventueel komt, wegschrijven naar een file, om later terug te kijken of alles zonder fouten verlopen is.
Je kunt uiteraard ook in de database, of naar een mailbox je meldingen laten versturen.
ofwel upload je iets met de browser, waarbij in map /x/y een bestand geplaatst wordt, en elke 5 minuten kijkt een cronjob of daar iets te doen is.
ofwel trigger je met de browser een commando, dat doorloopt terwijl de output naar de browser daar niet op wacht.
voorbeeld uit een script van mij dat op de achtergrond een berg pdf's maakt en daarna uitprint:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$command = ('/usr/bin/nohup /usr/bin/php ' . CLI_DIR . 'print.php' . ' ' . $sType . ' ' . $args . ' ' .
' > ' . CLI_OUTPUT . '.' . time() . '.txt' . ' & echo $!');
?>
$command = ('/usr/bin/nohup /usr/bin/php ' . CLI_DIR . 'print.php' . ' ' . $sType . ' ' . $args . ' ' .
' > ' . CLI_OUTPUT . '.' . time() . '.txt' . ' & echo $!');
?>
nohup en & echo $! zorgen dat eea op de achtergrond uitgevoerd wordt.
/usr/bin/php is de plek waar php staat.
Het path naar de scripts voor cli staat in de constante CLI_DIR en print.php het script dat ik aanroep.
omdat we hier geen print.php?type=a&id=10 kunnen gebruiken, staan de argumenten er gewoon achter.
net als je "cp a b" kunt doen om het commande cp te vertellen dat hij iets moet doen, kan dat ook voor een php script.
met > outputfile kun je de output die eventueel komt, wegschrijven naar een file, om later terug te kijken of alles zonder fouten verlopen is.
Je kunt uiteraard ook in de database, of naar een mailbox je meldingen laten versturen.
Hi Ivo,
ik ben idd bekend met parameters doorgeven in CLI aan php.
de $argv array.
Jouw voorbeeld, gebruik je dit met shell_exec($command) ??
Stopt de browser dan wel, maar gaat de shell gewoon door (server side), dus kan de browser gesloten worden?
Daarna kun je een andere pagina bezoeken, site verlaten; pc afsluiten etc.
Ik gebruik dit om een stapel van een stuk of 100 pdfs te maken en naar de printer te sturen (door de server). Daar hoeft de gebruiker niet op te wachten achter zijn pc.
Ivo P op 28/09/2016 20:33:18:
klopt. browser maakt de pagina gewoon af, terwijl dit proces op de achtergrond draait.
Daarna kun je een andere pagina bezoeken, site verlaten; pc afsluiten etc.
Ik gebruik dit om een stapel van een stuk of 100 pdfs te maken en naar de printer te sturen (door de server). Daar hoeft de gebruiker niet op te wachten achter zijn pc.
Daarna kun je een andere pagina bezoeken, site verlaten; pc afsluiten etc.
Ik gebruik dit om een stapel van een stuk of 100 pdfs te maken en naar de printer te sturen (door de server). Daar hoeft de gebruiker niet op te wachten achter zijn pc.
*praise the lord*
je bent geweldig!!!!
moet ik trouwens niet && echo gebruiken ?
Toevoeging op 29/09/2016 07:42:41:
Werkt geweldig! Enorm bedankt Ivo.
Hij is nu gewoon op z'n gemak aan het importeren :)
Houdt ook een log file bij, die ik 'live' kan inzien dmv jquery requests :)
Ik zeg, close topic :)
Nogmaals alle anderen bedankt voor de reacties!
Gewijzigd op 29/09/2016 07:43:28 door Dennis WhoCares
Ivo P op 28/09/2016 20:33:18:
klopt. browser maakt de pagina gewoon af, terwijl dit proces op de achtergrond draait.
Daarna kun je een andere pagina bezoeken, site verlaten; pc afsluiten etc.
Ik gebruik dit om een stapel van een stuk of 100 pdfs te maken en naar de printer te sturen (door de server). Daar hoeft de gebruiker niet op te wachten achter zijn pc.
Daarna kun je een andere pagina bezoeken, site verlaten; pc afsluiten etc.
Ik gebruik dit om een stapel van een stuk of 100 pdfs te maken en naar de printer te sturen (door de server). Daar hoeft de gebruiker niet op te wachten achter zijn pc.
Hi Ivo,
klein vraagje over deze aanpak. Ik heb op een ander project mijn backend ook gemaakt op het basis van het MVC model en 'seo friendly' urls icm .htaccess
Dit kan ik niet zo aanroepen met de /usr/bin/php commando.
Is hier een workaround voor, of is het gewoon beter om hier ook gewoon een statisch script van te maken?
Alvast bedankt!
Het rewriten wordt door Apache gedaan, nog voor PHP door Apache aangesproken wordt. Maar dat is een heel andere benadering.
Niet voor niets staat in mijn voorbeeld ook CLI_DIR, de directory waarin de command line scripts staan. Die staan bij mijn opzet buiten de normale ingang die altijd via index.php loopt.
Ivo P op 03/10/2016 12:14:11:
Je roept niet een url aan, maar een script.
Het rewriten wordt door Apache gedaan, nog voor PHP door Apache aangesproken wordt. Maar dat is een heel andere benadering.
Niet voor niets staat in mijn voorbeeld ook CLI_DIR, de directory waarin de command line scripts staan. Die staan bij mijn opzet buiten de normale ingang die altijd via index.php loopt.
Het rewriten wordt door Apache gedaan, nog voor PHP door Apache aangesproken wordt. Maar dat is een heel andere benadering.
Niet voor niets staat in mijn voorbeeld ook CLI_DIR, de directory waarin de command line scripts staan. Die staan bij mijn opzet buiten de normale ingang die altijd via index.php loopt.
Aaahhh zo ;-) Ik snap m! Thanks again