[PHP] Wizard systeem

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • -J00P-
  • Registratie: September 2004
  • Laatst online: 20-09 16:45
Hallo,

Ik probeer een wizard script met php te schrijven. De bedoeling is dat de grootste pc-analfabeet gegevens toe kan voegen (bijv. een product aan een webwinkel).
Er kan gebladerd worden tussen verschillende pagina's met formulieren. En wanneer alles ingevuld en gevalideerd is, worden de gegevens in een database opgeslagen.

Het probleem zit m bij het tussentijds opslaan van de gegevens.
Wanneer de gebruiker zich bij pagina1 begint, vervolgens naar pagina2 gaat enz. tot paginaX waar de boel wordt opgeslagen, moet alles gedurende die tijd onthouden worden op de een of andere manier.

In eerste instantie dacht ik aan het gebruik van sessions, maar dat geeft moeilijkheden wanneer er plaatjes/bestanden opgeslagen moeten worden (heb tevergeefs geprobeerd om een bestand in een session te proppen :9, heb de conclusie getrokken dat dit niet mogenlijk is, of wel??)

Het direct opslaan van de bestanden vindt ik ook geen nette oplossing; wanneer de wizard namelijk halverwege wordt gesloten staat het plaatje al op de server terwijl deze dan wrs niet gebruikt wordt en onnodig ruimte in beslag neemt.

Teneinde raad ben ik nu hierheen gekomen :+ , mss weet iemand hier een goede manier voor het opslaan van de data.

Acties:
  • 0 Henk 'm!

  • RSpliet
  • Registratie: Juni 2003
  • Laatst online: 08-09 21:45

RSpliet

*blink*

er voor zorgen dat het plaatje de laatste stap is, en voor de rest met hidden formuliertjes werken, of idd sessions, dat is het makkelijkst. Anders de data in een database duwen, en om de uur een cronjob opzetten, die een PHP pagina opvraagt om de ongebruikte boel leeg te grazen ofzo?

Schaadt het niet, dan baat het niet


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Je kan een sessietabel maken in je database en daar tijdelijk alles in opslaan. Je plaatje moet dan in een BLOB field.
Maar volgens mij moet je de inhoud van een plaatje ook wel in een sessie kunnen opslaan:
PHP:
1
$_SESSION['filecontents'] = file_get_contents($_FILES['invoerveld']['temp_name']);

Zo uit het blote hoofd, zal waarschijnlijk niet direct werken, maar je snapt het idee wel. :)
edit:
2e dimensie van de array vergeten. :)

[ Voor 11% gewijzigd door NMe op 13-09-2004 18:51 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 21-09 14:28
Als je het mij vraagt kan je veel beter de complete wizzard in 1x naar de browser sturen en vervolgens met behulp van JS iedere keer een pagina tonen. Dan kan je de PHP verwerking namelijk gewoon "goed" houden. Want imo is een wizzard een layout vorm, het zou net zo goed een formulier van 1 pagina kunnen zijn.

Acties:
  • 0 Henk 'm!

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 21:22
Wat je oplossing is voor het plaatje:

Je zet het plaatje in een TEMP-directory. Als de sessie klaar is, dus het product moet worden toegevoegd, haal je het plaatje (waar je een link naar toe opslaat in de sessie array) uit de temp dir en gooi je het in een gewone dir.
Verder laat je een cronjobje of zoiets draaien dat om de zoveel tijd die directory leeghaalt. (maar wel checken hoe oud de plaatjes zijn; plaatjes jonger dan, laten we zeggen, 2 uur ofzo moet hij verwijderen, anderen laten staan.)

Verbouwing


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

djluc schreef op 13 september 2004 @ 19:07:
Als je het mij vraagt kan je veel beter de complete wizzard in 1x naar de browser sturen en vervolgens met behulp van JS iedere keer een pagina tonen. Dan kan je de PHP verwerking namelijk gewoon "goed" houden. Want imo is een wizzard een layout vorm, het zou net zo goed een formulier van 1 pagina kunnen zijn.
Je hebt wel een punt, maar waarom zou je? Kun je een beetje lastig gaan zitten scripten terwijl je het ook prima even kan opslaan in een sessie of een database. Bovendien hoeft Javascript niet aan te staan, en zie maar dat een complete digibeet dat activeert...

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 21-09 14:28
Ik ben uitgegaan van het voorbeeld. Daarin gaat het over producten toevoegen, ik neem aan dat we het dus over backend applicaties hebben. Verder weet ik niet wat je lastig scripten vind? Een divje X verbergen en een divje met nummer X+1 tonen als deze bestaat is niet echt moeilijk? Andere zaken als specifieke pagina's tonen na een bepaalde keuze e.d. zijn uiteraard ook mogelijk met wat meer scripting.

[ Voor 18% gewijzigd door djluc op 13-09-2004 19:13 ]


Acties:
  • 0 Henk 'm!

  • -J00P-
  • Registratie: September 2004
  • Laatst online: 20-09 16:45
[quote]NMe84 schreef op 13 september 2004 @ 18:50:
PHP:
1
$_SESSION['filecontents'] = file_get_contents($_FILES['invoerveld']['temp_name']);


mja... zo zal t wel lukken |:( --> tnQ :)

--btw.. weet iemend toevallig of er een max zit aan de grootte van een sessie?
djluc schreef op 13 september 2004 @ 19:07:
Als je het mij vraagt kan je veel beter de complete wizzard in 1x naar de browser sturen en vervolgens met behulp van JS iedere keer een pagina tonen. Dan kan je de PHP verwerking namelijk gewoon "goed" houden. Want imo is een wizzard een layout vorm, het zou net zo goed een formulier van 1 pagina kunnen zijn.
Ik had het zelf nog niet zo bekeken, maar ik ben het eigenlijk wel met je eens.
K zal eens kijken of ik het toe kan passen.

bedankt!

Acties:
  • 0 Henk 'm!

  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

djluc schreef op 13 september 2004 @ 19:07:
Als je het mij vraagt kan je veel beter de complete wizzard in 1x naar de browser sturen en vervolgens met behulp van JS iedere keer een pagina tonen. Dan kan je de PHP verwerking namelijk gewoon "goed" houden. Want imo is een wizzard een layout vorm, het zou net zo goed een formulier van 1 pagina kunnen zijn.
Ben ik het niet helemaal mee eens. Ik gebruik juist vaak Wizards, als bepaalde stappen afhankelijk zijn van eerder gemaakte keuzes. Stel, dat je een product in een bepaalde subcategorie moet gaan onderbrengen. Dan laat je de gebruiker eerst de hoofd-categorie kiezen, om vervolgens naar aanleiding van die keuze uit de database de lijst met subcategorieen te halen.

Wanneer je dit soort dingen met JavaScript gaat oplossen, heb je het risico dat er bij een flinke database enorme pagina's gaan ontstaan, waarin alle mogelijke opties opgenomen zijn.

Acties:
  • 0 Henk 'm!

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

[quote]-J00P- schreef op 13 september 2004 @ 21:31:
NMe84 schreef op 13 september 2004 @ 18:50:
PHP:
1
$_SESSION['filecontents'] = file_get_contents($_FILES['invoerveld']['temp_name']);


mja... zo zal t wel lukken |:( --> tnQ :)

--btw.. weet iemend toevallig of er een max zit aan de grootte van een sessie?


[...]


Ik had het zelf nog niet zo bekeken, maar ik ben het eigenlijk wel met je eens.
K zal eens kijken of ik het toe kan passen.

bedankt!
Volgens mij zit er geen max aan een session, maar hou er wel rekening mee dat elke keer als een script gestart word. En er een session wordt gestart dat de complete session in het geheugen geladen wordt. Dus als je complete bestanden in een session gooit kan dit best wel veel geheugen vreten.

Programmer - an organism that turns coffee into software.


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 21-09 14:28
gvanh schreef op 14 september 2004 @ 09:33:
[...]Wanneer je dit soort dingen met JavaScript gaat oplossen, heb je het risico dat er bij een flinke database enorme pagina's gaan ontstaan, waarin alle mogelijke opties opgenomen zijn.
In dat soort gevallen kan je ook kiezen voor oplossingen waarbij je de gegevens laad met JS, denk aan XML/Iframe oplossingen. Daar kan je eenmalig een standaard systeem voor maken waarna dit geen probleem meer op mag leveren.

Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Sla gewoon alle gegevens direct op in je database, maar gebruik een flag om te bepalen of de 'wizard' al is voltooid.
Neem dus een xtra kolom welke standaard op 0 staat, en zet deze pas op 1 als de user op Voltooid heeft geklikt.

Als je er ook een timestamp veld bijgooit kun je alle records ouder dan een dag en welke nog steeds op 0 staan verwijderen

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 21-09 14:28
frickY schreef op 14 september 2004 @ 15:49:
Sla gewoon alle gegevens direct op in je database, maar gebruik een flag om te bepalen of de 'wizard' al is voltooid.
Neem dus een xtra kolom welke standaard op 0 staat, en zet deze pas op 1 als de user op Voltooid heeft geklikt.

Als je er ook een timestamp veld bijgooit kun je alle records ouder dan een dag en welke nog steeds op 0 staan verwijderen
Ik zie een wizzard voor me waarmee je een record kan editten. Vervolgens wil je de gebruiker natuurlijk ook een annuleren knop geven, zoals in Windows. Dan heb je met jou opzet een probleem omdat je dan het oude record nog niet mag voorzien van nieuwe informatie. Dat lijkt me dus niet zo handig.

Acties:
  • 0 Henk 'm!

  • bas.kb
  • Registratie: Oktober 2002
  • Laatst online: 04-05 23:35

bas.kb

BI'er :P

Ik zou van alle tabellen in je database een structuur kopie maken, en die tabelnaamtemp noemen. Je kwakt tijdens het invullen alles in die temptabellen, en zodra de gebruiker klaar is prop je alles in je originele tabelletjes en dump je alle gegevens met het sessienummer van die gebruiker je temp tabel.

Acties:
  • 0 Henk 'm!

  • sniek
  • Registratie: September 2004
  • Laatst online: 30-07 13:04

sniek

Got root?

Ik gebruik vaak hidden forms in hetzelfde bestand. Je kunt dan zoveel
code:
1
$_POST[var]
maken als je wilt en alles pas opslaan in de dbase als je klaar bent. Dit is in vele gevallen erg dbase vriendelijk en bespaart de de cron job weer die elke dag / 10 minuten de ellende eruit haalt. Dit kan bij grotere dbases ook erg veel performance kosten.

Irrelevant by default - rm -rf /


Acties:
  • 0 Henk 'm!

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 21:22
sniek schreef op 14 september 2004 @ 16:36:
Ik gebruik vaak hidden forms in hetzelfde bestand. Je kunt dan zoveel
code:
1
$_POST[var]
maken als je wilt en alles pas opslaan in de dbase als je klaar bent. Dit is in vele gevallen erg dbase vriendelijk en bespaart de de cron job weer die elke dag / 10 minuten de ellende eruit haalt. Dit kan bij grotere dbases ook erg veel performance kosten.
En als gebruikers op vorige klikken is de nieuwe informatie niet meer beschikbaar. Dat wrkt zeer frustrerend voor de gebruikers.

Verbouwing


Acties:
  • 0 Henk 'm!

  • BetuweKees
  • Registratie: Januari 2003
  • Laatst online: 15-07 20:53

BetuweKees

Flipje uit Tiel

Mithrandir schreef op 14 september 2004 @ 16:49:
En als gebruikers op vorige klikken is de nieuwe informatie niet meer beschikbaar. Dat wrkt zeer frustrerend voor de gebruikers.
dat ligt er maar net aan hoe je eea ontwerpt..
kan me nog herrinneren dat ik vorig jaar eens een soort gelijke app ontworpen heb, waarbij bij een klik op de back button een submit werd gedaan naar de voorgaande pagina die door de meegestuurde vars heenlas en het formpje weer netjes vulde met de reeds opgegeven waarden.. werkte perfect..

Through meditation I program my heart to beat breakbeats and hum basslines on exhalation -Blackalicious || *BetuweKees was AFK; op de fiets richting China en verder


Acties:
  • 0 Henk 'm!

Verwijderd

frickY schreef op 14 september 2004 @ 15:49:
Sla gewoon alle gegevens direct op in je database, maar gebruik een flag om te bepalen of de 'wizard' al is voltooid.
Neem dus een xtra kolom welke standaard op 0 staat, en zet deze pas op 1 als de user op Voltooid heeft geklikt.

Als je er ook een timestamp veld bijgooit kun je alle records ouder dan een dag en welke nog steeds op 0 staan verwijderen
Leuk maar dat kost je een bak met misschien wel onnodige queries (bv 1 insert en meerdere updates)

Ik ben met ook zoiets bezig, en indien mogelijk gooi ik de gegevens in een sessie om ze vervolgens weer lekker uit te lezen :)

Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Hmm ja, sessie is waarschijnlijk ook wel een stuk handiger.
En de file-upload moet je toch per direct afhandelen. Dus file laten uploaden, en bestandsnaam in je sessie meenemen.

Je kunt in elke pagina iets gooien als;
PHP:
1
2
while(list($name, $value) = each($_POST))
  echo "<input name='$name' type='hidden' value='$value'>\n";


Het op de "BACK"-button van de browser klikken kan je afvangen met een onunload-event in Javascript.

Maar of dat nou zo n mooie oplossing is...

[ Voor 9% gewijzigd door frickY op 14-09-2004 20:41 ]


Acties:
  • 0 Henk 'm!

  • Basszje
  • Registratie: Augustus 2000
  • Laatst online: 21-09 16:37

Basszje

Reisvaap!]

frickY schreef op 14 september 2004 @ 15:49:
Sla gewoon alle gegevens direct op in je database, maar gebruik een flag om te bepalen of de 'wizard' al is voltooid.
Neem dus een xtra kolom welke standaard op 0 staat, en zet deze pas op 1 als de user op Voltooid heeft geklikt.

Als je er ook een timestamp veld bijgooit kun je alle records ouder dan een dag en welke nog steeds op 0 staan verwijderen
Dit lijkt mij ook een prima oplossing eerlijk gezegd. Als je meerdere tabellen heb is het wellict handig om een grote temp tabel te fabriceren met alle velden 'slordig' opgeslagen. Als is het maar tijdelijk, dan is het niet zo'n grote ramp denk ik .
djluc schreef op 14 september 2004 @ 16:25:
[...]
Ik zie een wizzard voor me waarmee je een record kan editten. Vervolgens wil je de gebruiker natuurlijk ook een annuleren knop geven, zoals in Windows. Dan heb je met jou opzet een probleem omdat je dan het oude record nog niet mag voorzien van nieuwe informatie. Dat lijkt me dus niet zo handig.
Dat hoeft natuurlijk niet. Je kan je script opsplitsen in een toon op site script en een edit script ( of een flag meegeven ) waarbij je dus in het ene geval wel de niet voltooide items toont en in een ander dit niet toont. Druk je annuleren verwijdert de wizard gewoon alles wat je tot nu toe hebt opgeslagen.

Sessies is imo kut. Stel je voor dat de gebruiker even een aantal dingen moet opzoeken, even luncht en daarna weer verder wil met dat product. Dan is een half uur al lang verstreken en is je sessie weg. Gevolg : Errors en de gebruiker kan overnieuw inloggen.

Beware of listening to the imposter; you are undone if you once forget that the fruits of the earth belong to us all, and the earth itself to nobody.


Acties:
  • 0 Henk 'm!

  • usr-local-dick
  • Registratie: September 2001
  • Niet online
Als je gebruikt maakt van pearDB (pear.php.net) en een database die transacties ondersteunt (bv Postgres) dan kun je allerlei queries doen en pas op het laatste moment een $db->Commit(); doen.
Die lukt alleen als alle voorgaande queries ook zouden lukken.

Acties:
  • 0 Henk 'm!

  • Xenon
  • Registratie: Januari 2001
  • Laatst online: 21-08 09:12
Wat ook een leuke manier van werken is, is alles in een array gooien, en dit in een hidden field zetten en via je form doorgeven

eerst de array serializen, dan eventueel nog base64-encoden en bij de opvang omgekeerd

PHP:
1
2
3
4
echo '<input type="hidden" name="data" value="'.base64_encode(serialize($data_array)).'">';


$data_array = unserialize(base64_decode($_POST['data']));

ProtocoLAN.be: De beste LAN van de Maaskant


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 21-09 14:28
usr-local-dick schreef op 14 september 2004 @ 22:58:
Als je gebruikt maakt van pearDB (pear.php.net) en een database die transacties ondersteunt (bv Postgres) dan kun je allerlei queries doen en pas op het laatste moment een $db->Commit(); doen.
Die lukt alleen als alle voorgaande queries ook zouden lukken.
Dat is niet mogelijk bij de meeste oplossingen hier niet mogelijk omdat deze meerdere requests naar de server doen.

Verwijderd

Ik weet niet hoeveel stappen je moet afhandelen. Als dit er erg veel zijn kun je de data opslaan in een tmp-tabel waarbij je de data op het laatste moment in je daarvoor bestemde tabel stopt en de tmp tabel leeg maakt.

Als het maar een 2 tot 4/5 tal stappen zijn, kun je dit doen met sessies en of hidden fields (ik prefereer sessies).

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 21-09 14:28
Verwijderd schreef op 15 september 2004 @ 14:06:
Ik weet niet hoeveel stappen je moet afhandelen.
Ik zou sowieso een generieke oplossing bedenken zodat je niet constant hetzelfde hoeft te ontwikkelen.

Acties:
  • 0 Henk 'm!

  • sniek
  • Registratie: September 2004
  • Laatst online: 30-07 13:04

sniek

Got root?

Mithrandir schreef op 14 september 2004 @ 16:49:
[...]


En als gebruikers op vorige klikken is de nieuwe informatie niet meer beschikbaar. Dat wrkt zeer frustrerend voor de gebruikers.
je hebt helemaal gelijk, maar alles gebeurt op een pagina, en elke form wordt niet uit een nieuwe pagina gehaald. Als je op back drukt ga je helemaal uit het formulier. Maar als je een switch maakt voor de verschillende forms is dit absoluut geen probleem....

Irrelevant by default - rm -rf /


Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb dat wel eens opgelost met hidden variabelen, werkt best goed:

http://www.recht.nl/members/regulier/

(als je alleen wilt testen a.j.b. niet na 'Controleer uw gegevens' op Next drukken anders komt er zoveel rommel in de DB)

[ Voor 7% gewijzigd door Verwijderd op 17-09-2004 10:18 ]


Acties:
  • 0 Henk 'm!

  • rvrbtcpt
  • Registratie: November 2000
  • Laatst online: 19-09 16:18
Het nadeel van een wizard is inderdaad het terug gaan naar een vorige pagina.
Zelf los ik dit soort dingen met tabs op.
Als je bijvoorbeeld een nieuw product via de administratie wilt toevoegen dan krijg je eerst alleen de pagina met de basis informatie van een product te zien.
Vul je dan een naam en prijs in en nog wat andere dingen dan komt dit in de database terecht.
Na het opslaan zie je dan de overige tabs voor korte en lange omschrijving, toevoegen aan categorieeen, variaties, prijzen en media links.
De gebruiker kan dan ook snel kiezen wat er nog ingevuld moet worden en hoeft niet perse door alle pagina's heen.
Pagina: 1