[PHP] Recursieve array aanvullen met data

Pagina: 1
Acties:
  • 116 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
De code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Model {
    var $model      = array();
    
    function addModelData()
    {
        if (isset($_SESSION['model'])) {
            $this->model    = $_SESSION['model'];
        }
        $this->iteratePost($_POST);
    }

    function iteratePost($array) {
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                $this->model[$key] = $array[$key];// Dit gaat alleen goed als hij bij het laatste child is. Daarvoor komen deze gegevens (logisch) ook in de array, maar dat moet natuurlijk niet. Op zich klopt bij het laatste child de structuur wel.
                $array[$key] = $this->iteratePost($array[$key]);
            } else {
                $this->model[$key] = $array[$key];// Hier krijg ik nu alleen de laatste key van het laatste child, zodat de structuur niet klopt.
            }
            if ($value == "" || strstr($value, "remove") || empty($value)) {
                unset($array[$key]);
            }
            if (empty($array)) {
                unset($array);
            }
        }
    }
}

Het probleem:
Ik heb de array $this->model en deze wordt gevuld met $_SESSION['model']. Op verschillende pagina's wil ik deze sessie aanvullen. Als er data gewist is (veld leeggemaakt) dan moet deze data ook uit de sessie verdwijnen. De structuur van $this->model gaat niet goed. Er komen of teveel indexen/keys in of juist te weinig. Alle childs komen ook in de root (fout dus).

[ Voor 17% gewijzigd door nemesis_ op 03-10-2005 13:03 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Sorry hoor maar ik snap er vrij weinig van. Even een paar dingen. $array[$key] heeft exact dezelfde waarde als $value. $array[$key] = $this->iteratePost($array[$key]); slaat nergens op, want iteratePost returned niets. Je unset zaken uit $array terwijl je mischien $_SESSION bedoelt? (je info is zo beperkt en wazig dat ik er weinig tot niets uit kan opmaken).

Verder nog. iteratePost is een erg slechte naam voor je functie. Het geeft alleen aan dat je gaat lopen over de $_POST array. Waarom die dan als parameter moet worden meegegeven is me ook een raadsel. Geef hem een naam die wat informatiever is. Eentje die duidelijk maakt wat de functie nou werkelijk doet.

Dit slaat natuurlijk ook nergens op:
PHP:
1
2
3
4
5
6
if (is_array($value)) {
    $this->model[$key] = $array[$key];
    $array[$key] = $this->iteratePost($array[$key]);
} else {
    $this->model[$key] = $array[$key];
}

Korter geschreven is dat gewoon dit:
PHP:
1
2
3
4
$this->model[$key] = $array[$key];
if (is_array($value)) {
    $array[$key] = $this->iteratePost($array[$key]);
}

En zoals gezegd returned iteratePost niets. Dus $array[$key] wordt in dit geval altijd null als $value een array is.

PHP:
1
2
3
if (empty($array)) {
    unset($array);
}

Wat je hiermee bedoelt weet ik ook niet. Als $array null, false (of andere waarde waarop dit true zou kunnen worden, behalve een lege array) zou zijn, dan zou je een error krijgen bij het begin van je foreach loop, en zou dit stukje nooit uitgevoert worden. In geval van een lege array wordt het wel true, maar komt het ook nooit aan, omdat foreach niet 1 keer loopt. In geval van een gevulde array, kom je wel aan op dat stukje, maar is het altijd false. Dus unset($array) wordt in princiepe nooit uitgevoert.

PHP:
1
2
3
if ($value == "" || strstr($value, "remove") || empty($value)) {
      unset($array[$key]);
}

Dan dit stukje nog. Zou je dat kunnen toelichten? Wat ik wel weet is dat het nu niets doet. $array is immers geen reference variabel, dus acties hierop worden niet toegepast op $_POST. In princiepe is dit dus een overbodige actie (of je moet van $array een reference maken).

[ Voor 95% gewijzigd door Michali op 03-10-2005 13:27 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Ik ben zo aan het testen geweest dat er nu nog meer fouten zijn ontstaan.
Hier een nieuwe poging:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function processModelData($array) {
    foreach ($array as $key => $value) {
        if ($key && ($key != "page" && $key != "editreference" && $key != "editasset" &&
            !strstr($key, "publication_") && $key != "author_references" &&
            $key != "publisher" && !strstr($key, "rowCount") && !strstr($key, "asset") &&
            $key != "MAX_FILE_SIZE" && !strstr($key, "delete") && !strstr($key, "update"))) {
            if (is_array($value)) {
                if ($this->hasChilds($value)) {
                    $this->processModelData($value);
                } else {
                    $this->model[$key] = $value;
                }
            } else {
                if ($value == "" || strstr($value, "remove") || empty($value)) {
// Dit zou moeten checken of er een waarde in $_POST[$key zoveel] zit, zo nee gooi hem dan weg.
                    unset($this->model[$key]);
                } else {
                    $this->model[$key] = $value;
                }
            }
        } else {
            unset($this->model[$key]);
        }
    }
}

function hasChilds($array, $hasChilds = false)
{
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $this->hasChilds($value, true);
        } else {
            $hasChilds = false;
            break;
        }
    }
    return $hasChilds;
}

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Ok fijn. Zou je dan ook kunnen aangeven wat er precies fout gaat? Je code is zo (onnodig?) complex dat we er weinig mee kunnen.

Even een paar gerichte vraagjes (mischien dat dat helpt):
-Wat is model en wat wil je er in opslaan?
-Wat is de taak van processModelData?
-Wat controleer je in de eerste if statement in die functie? (regel 3 tot 6)

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
-model (een array in m'n sessie) bevat allerlei informatie over een nieuw/bestaand model. Informatie als title, description, array van pros en cons, array van authors en nog meer. Ook nieuwe authors zullen hierin komen als [model][new][author][index]
-het aanvullen en eventueel verwijderen van data die door middel van een post verstuurd worden. Ik gebruik een sessie omdat er 4 pagina's zijn.
-een aantal velden van de formulieren hoeven niet de sessie in. Die wilde ik hiermee skippen.

Wat gaat er fout:
Alle data uit standaard input velden komen wel in de sessie, maar arrays (pro[], con[] en new[author][]) komen niet (goed) in de sessie. $_POST heeft op zich dezelfde structuur als wat er in de sessie moet (vandaar dat ik eerst iteratePost gebruikte). Maar $_POST bevat eigenlijk teveel data. Als iemand besluit dat hij namelijk een veldje leeg wil laten, of een author weg te halen, dan maakt hij het veld leeg of kiest hij 'remove author' (dit is een waarde van een selectbox). Als de gebruiker eerder iets had opgeslagen, dan moet dit uit de sessie verwijderd worden.

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Defineer eens wat 'komen niet (goed) in de sessie' is. Wat gaat er precies fout, waar denk je dat de fout zit en wat heb je zelf al geprobeerd om het op te lossen? Overigens zou ik die controle niet zo hardcoded in die functie proppen. Ik zou eerder een array maken met waardes waarop gecontroleerd moet worden en een aparte functie die die controle uitvoert.

[ Voor 4% gewijzigd door Michali op 03-10-2005 14:03 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Op zich werkt hij nu wel aardig, maar de lege entries en de values met 'remove' erin worden nu niet verwijderd als de waarde zelf een array is. De root waarden - model_title = "" of met values 'remove' - gaan dus wel eruit, maar waardes als pros[0] = "" gaat er niet uit.
Het toevoegen van de $_POST waarden naar $this->model gaat goed.
Het verwijderen (of het niet toevoegen) van $_POST waarden gaat fout.

[ Voor 27% gewijzigd door nemesis_ op 03-10-2005 14:05 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
hasChilds klopt volgens mij niet.
PHP:
1
$this->hasChilds($value, true);

moet volgens mij
PHP:
1
$hasChilds =  $this->hasChilds($value, true);

zijn. Toch?

Weet je zeker dat die functie verder klopt? Als $hasChilds namelijk ergens true wordt, kan hij bij de volgende items gewoon weer false worden. Dat lijkt me niet helemaal de bedoeling. Loop hem eens een keertje door in je hoofd (en de rest van de code ook overigens).

[ Voor 45% gewijzigd door Michali op 03-10-2005 14:07 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:47

Creepy

Tactical Espionage Splatterer

nemesis_ schreef op maandag 03 oktober 2005 @ 14:04:
Op zich werkt hij nu wel aardig, maar de lege entries en de values met 'remove' erin worden nu niet verwijderd als de waarde zelf een array is. De root waarden - model_title = "" of met values 'remove' - gaan dus wel eruit, maar waardes als pros[0] = "" gaat er niet uit.
Het toevoegen van de $_POST waarden naar $this->model gaat goed.
Het verwijderen (of het niet toevoegen) van $_POST waarden gaat fout.
Ja? En dus? Wat heb je daar nu zelf al aan aangepast om dit op te lossen? En WAT gaat er dan precies fout? Wat is het verschil met de juiste situatie?

Het lijkt erop dat je redelijk bij de hand genomen moet worden om tot een oplossing te komen. Je eigen inzet met betrekking tot het oplossen van je vragen lijkt te missen. Als je dit soort dingen post voeg dan in elk geval de zaken toe die je zelf al hebt geprobeerd en wat daar niet mee lukte. Zie ook P&W FAQ - De "quickstart". Met een b eetje debug werk moet ook een heel eind komen. Zie ook P&W FAQ - Leer **** debuggen!!

[ Voor 6% gewijzigd door Creepy op 03-10-2005 14:15 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Volgens mij klopt-ie wel hoor. Als hij namelijk geen childs meer heeft, zit hij op z'n diepst. Dan pas moet hij $this->model aanvullen, eerder niet. Dus zolang hij true geeft (hij heeft dus childs) dan mag $this->model niet aangevuld worden, want anders wordt er data toegevoegd die eigenlijk een child dieper moet.
Of heb ik dit helemaal fout.

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
PHP:
1
2
3
4
5
if ($this->hasChilds($value)) {
    $this->processModelData($value);
} else {
    $this->model[$key] = $value;
}

Ik denk dat het hier fout gaat. Want als ik bij:
PHP:
1
2
3
4
5
6
if ($value == "" || strstr($value, "« remove ") || empty($value)) {
    unset($value);
    unset($this->model[$key]);
} else {
    $this->model[$key] = $value;
}

check, dan komt daar als $key nooit het diepste child tevoorschijn. Wel als ik $key echo bij het eerste stuk. Maar op dat moment is $value in:
PHP:
1
$this->model[$key] = $value;

een array.

Hij komt dus één laag te kort eigenlijk.
edit:
Met die regel hierboven spreek ik m'n vorige post wel tegen zie ik nu

[ Voor 12% gewijzigd door nemesis_ op 03-10-2005 14:23 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
function hasChilds($array, $hasChilds = false)
{
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $this->hasChilds($value, true);
        } else {
            $hasChilds = false;
            break;
        }
    }
    return $hasChilds;
}

Het gaat me dus om regel 5. Wat gebeurt er dan? De uitkomst maakt niet uit iig. Of het nou true of false wordt, je doet er niets mee.
Volgens mij moet het dus zoiets worden:
PHP:
1
2
3
4
5
6
7
8
9
10
11
function hasChilds($array, $hasChilds = false)
{
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $hasChilds = $this->hasChilds($value, true);
        } else {
            return false;
        }
    }
    return $hasChilds;
}

Al lijkt me het zeer onwaarschijnlijk dat je dat er ook mee bedoelt.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Ok, wat heb ik nou ondertussen allemaal geprobeerd:
- Ik heb vanalles geprobeerd te debuggen. Echo-en van $values en $keys. Gecheckt of het een array is of niet.
- Op php.net en op google gezocht naar verschillende recursieve functies. Maar de recursieve functie zelf, was bij voorbaat al geen probleem.
- Functie gestript tot een minimum.
- Tips van Michali gebruikt.
- Me ongelovelijk geërgerd omdat ik er niet uitkom.

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Michali schreef op maandag 03 oktober 2005 @ 14:23:
[snip]
Het gaat me dus om regel 5. Wat gebeurt er dan? De uitkomst maakt niet uit iig. Of het nou true of false wordt, je doet er niets mee.
Ik doe er wel wat mee, want ik return de waarde true of false. Als hij true geeft, dan ik dieper de $_POST array in. Zo niet, dan set ik een waarde voor $this->model[$key]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
nemesis_ schreef op maandag 03 oktober 2005 @ 14:35:
[...]

Ik doe er wel wat mee, want ik return de waarde true of false. Als hij true geeft, dan ik dieper de $_POST array in. Zo niet, dan set ik een waarde voor $this->model[$key]
En wat doe je dan met de waarde uit de return? Idd, niets. In processModelData doe je er wel wat mee, maar bij de recursieve call niet. Vergelijk jou versie en mijn aanpassing er op nou eens goed.

En geef eens duidelijk aan wat je nou probeert te controleren in hasChilds. Ik weet vrijwel zeker dat die functie niet klopt. Ik weet echter niet wat je er mee probeert.

Ga eens flink refactoren. Probeer alles zo te coden dat direct je intentie uit de functie namen en variabel namen is af te lezen. Dat helpt al een behoorlijk stuk. Ik wil je er zelfs wel even bij helpen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?

function processModelData($modelData) {
    foreach ( $modelData as $key => $value ) {
        if ( isValidModelDataKey($key) ) {
            if (is_array($value)) {
                if ($this->hasChilds($value)) {
                    $this->processModelData($value);
                } else {
                    $this->model[$key] = $value;
                }
            } else {
                if ( isValidModelDataValue($value) ) {
                    $this->model[$key] = $value;
                } else {
                    unset($this->model[$key]);
                }
            }
        } else {
            unset($this->model[$key]);
        }
    }
}

$INVALID_MODEL_DATA_KEYS = array(
    'page', 'editreference', 'editasset',
    'publication_', 'author_references',
    'publisher', 'rowCount', 'asset',
    'MAX_FILE_SIZE', 'delete', 'update'
);

function isValidModelDataKey($key)
{
    foreach ( $GLOBALS['INVALID_MODEL_DATA_KEYS'] as $invalidKey )
    {
        if ( stripos($key, $invalidKey) !== false ) return false;
    }
    return true;
}

function isValidModelDataValue($value)
{
    return !empty($value) && !strstr($value, "remove");
}

function hasChilds($modelDataValue, $hasChilds = false)
{
    foreach ($modelDataValue as $key => $value) {
        if (is_array($value)) {
            $this->hasChilds($value, true); // hier doe je dus niets met de return waarde
        } else {
            return false;
        }
    }
    return $hasChilds;
}

?>

[ Voor 75% gewijzigd door Michali op 03-10-2005 15:42 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • RwD
  • Registratie: Oktober 2000
  • Niet online

RwD

kloonikoon

Wat Michali duidelijk probeert te maken is dat als je aanroep in regel 5 zo staat hij "true", "false" of "velperplein" mag returnen; je slaat de return waarde niet op. Zodra de functie regel 5 voorbij is is hij de waarde van de functie alweer vergeten.

Ikzelf snap niet waarom die functie recursief is. Als je wilt weten of een node children heeft (waar children het correcte meervoud is van child) dan hoef je alleen maar te weten of hij er minimaal 1 heeft (tenzij je letterlijk wilt weten of hij children heeft, maar meestal wil je weten of hij er minimaal eentje heeft)

PHP:
1
2
3
4
5
6
7
8
9
10
<?php
function hasChildren($array) { 
    foreach ($array as $key => $value) { 
        if (is_array($value)) { 
            return true;
        }
    } 
    return false; 
} 
?>
Lijkt me dan sneller

(Overigens vindt ik het raar dat we een array testen om te zien of er mogelijk bij een van de rijen er eentje zelf een array is. Dat is alsof je op kleinkinderen test?)

[ Voor 72% gewijzigd door RwD op 03-10-2005 15:51 ]


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Ok, ik had één dingetje over het hoofd gezien bij jou (return false ipv $hasChilds = false);
Nu krijg ik idd alleen steeds de diepste child in $this->model.
Alleen, waarom doet hij nu niks bij
PHP:
1
if ($value == "" || strstr($value, "« remove ") || empty($value)) {

Hij komt hier helemaal niet in als er childs zijn.

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Dat komt omdat is_array($value) (in processModelData) dan true is. Hij komt nooit bij het else gedeelte uit.

[ Voor 12% gewijzigd door Michali op 03-10-2005 15:53 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Michali schreef op maandag 03 oktober 2005 @ 15:52:
Dat komt omdat is_array($value) (in processModelData) dan true is. Hij komt nooit bij het else gedeelte uit.
Dat had ik gemerkt.
Ik ga even proberen of ik met jouw voorbeeld nu iets kan.
Alvast bedankt voor de moeite!

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Ik heb je code nu geïmplementeerd. (Eigenlijk had ik net zoiets dat op hetzelfde uitkwam, maar toch bedankt.)
hasChilds heet nu hasChildren en ziet er nu zo uit, naar jouw voorbeeld:
PHP:
1
2
3
4
5
6
7
8
9
10
11
function hasChildren($modelDataValue, $hasChildren = false)
{
    foreach ($modelDataValue as $key => $value) {
        if (is_array($value)) {
            $hasChildren = $this->hasChildren($value, true);
        } else {
            return false;
        }
    }
    return $hasChildren;
}

De array wordt dus wel goed gevuld nu, maar de waarde met 'remove' of met een lege waarde worden nog niet verwijderd als er children zijn.
Op het moment dat ik check of er children zijn, dan kan ik daar niet meer checken wat $value is.

[ Voor 4% gewijzigd door nemesis_ op 03-10-2005 16:08 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
Goed...ik heb er net ook even naar gekeken en denk inderdaad dat er ergens een klein denkfoutje is ingeslopen met betrekking tot recursieve functies. Die hasChildren methode heeft helemaal geen recursie nodig, je processModelData methode daarentegen wel.

Daarnaast heb ik wat michali doet met $INVALID_MODEL_DATA_KEYS iets verfijnt aangezien ik zie dat je ook strstr() gebruikt voor de checks wat betekend dat je niet enkel op die string zoekt maar een deel van die string.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    class Model {
        var $model  = array();
        
        function processModelData(&$array) {
            $forbiddenkeys = array('page', 'editreference', 'editasset', 'author_references', 'publisher', 'MAX_FILE_SIZE');
            $forbiddenkeywords = array('publication_', 'rowCount', 'asset', 'delete', 'update');
            foreach ($array as $key => $value ) {
                if ($key && !in_array($key, $forbiddenkeys) && !in_array_values($key, $forbiddenkeywords)) {
                    if (is_array($value) && !empty($value)) {
                        $this->processModelData($array[$key]);
                    }
                    else if (empty($value) || strstr($value, 'remove')) {
                            unset($array[$key]);
                    }
                }
                else {
                    unset($array[$key]);
                }
            }
        }
    }
    
    function in_array_values($needle, $haystack) {
        foreach ($haystack as $straw) {
            if(false !== strstr($needle, $straw)) {
                return true;
            }
        }
        return false;
    }


Ik laat de processModelData direct doorwijzen naar de onderliggende array. Stel je nu dus voor dat je $model->processModelData($_SESSION['modeldata']); doet dan schrijft deze ook weer terug naar $_SESSION['modeldata'] (vergeet dus niet $_SESSION['modeldata'] weg te schrijven naar $model->model1).
Doordat ik processModelData direct laat doorwijzen naar je onderliggende array kan je deze methode recursen.

In het geval van het voorbeeld van michali (en daarmee in je eigen voorbeeld) zullen de volgende keys elkaar overschrijven:
PHP:
1
array('naam'=>'Piet', 'iets_anders'=>array('naam'=>'Henk');

Gehaald door jouw methode zal 'Henk' dus 'Piet' overschrijven terwijl dat (neem ik aan) helemaal niet de bedoeling is.

In ieder geval succes ermee, ik hoop dat je er wat aan hebt :Y)

edit:
"&& !empty($value)" toegevoegd op regel 9 (vergeten als vervanging voor de methode hasChildren()

[ Voor 11% gewijzigd door Huppie op 03-10-2005 18:39 ]

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Waarom zou je dat willen doen? Je kunt toch in hasChildren zelf ook gebruik maken van isValidModelDataValue? De check op $value uit processModelData kun je gewoon voor hasChildren doen. Dat is niet iets wat je in hasChildren moet verwerken (behalve $value uit hasChildren zelf dan).
Huppie schreef op maandag 03 oktober 2005 @ 16:11:
Daarnaast heb ik wat michali doet met $INVALID_MODEL_DATA_KEYS iets verfijnt aangezien ik zie dat je ook strstr() gebruikt voor de checks wat betekend dat je niet enkel op die string zoekt maar een deel van die string.
De php manual over stripos

Hij geeft dus de positie terug van de substring die je opgeeft binnen de ander. Als hij niet voorkomt geeft ie false terug. !== false is nodig omdat != false ook op 0 true wordt. De methode met strstr is dus een (waarschijnlijk iets langzamere) variant. stripos is case-insesitive. Als dat niet gewenst is moet je gewoon strpos gebruiken.

[ Voor 57% gewijzigd door Michali op 03-10-2005 16:24 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Dat was tegen mij neem ik aan.
Het zal wel een denkfoutje zijn, maar ook als ik voor dat ik check of er children zijn de $value check, dan lukt het nog niet. De "foute" waarden blijven er in staan. Hoe moet die functie (processModelData) dan worden?

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
en stripos is PHP 5, was ik vergeten te vermelden: ik gebruik PHP 4(.4.0).

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:47

Creepy

Tactical Espionage Splatterer

nemesis_ schreef op maandag 03 oktober 2005 @ 16:32:
[...]
Hoe moet die functie (processModelData) dan worden?
En ik vraag je nogmaals: wat heb je zelf al geprobeerd om deze functie aan te passen? Wat lukte daar niet mee? GoT is geen helpdesk waar je even snel een oplossing voor je probleem kan halen. Sterker nog: je directe vraag hoe de functie moet worden vat ik hier op als een scriptrequest.
Lees aub de P&W FAQ - De "quickstart" nog eens goed door zodat je weet wat we eigenlijk van je verwachten voordat je hier een vraag stelt.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
PHP:
1
2
3
4
5
if ($this->hasChildren($value)) {
    $this->processModelData($value);
} else {
    $this->model[$key] = $value;
}

Dit voert de hele funtie processModelData toch gewoon nog een keer uit, maar nu met een andere array als startwaarde?
Als dat zo is, dan wordt is_array vanzelf false en dan zou ik toch kunnen checken of $value de goede waarde heeft?

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Creepy schreef op maandag 03 oktober 2005 @ 16:39:
[...]

En ik vraag je nogmaals: wat heb je zelf al geprobeerd om deze functie aan te passen? Wat lukte daar niet mee? GoT is geen helpdesk waar je even snel een oplossing voor je probleem kan halen. Sterker nog: je directe vraag hoe de functie moet worden vat ik hier op als een scriptrequest.
Lees aub de P&W FAQ - De "quickstart" nog eens goed door zodat je weet wat we eigenlijk van je verwachten voordat je hier een vraag stelt.
Creepy, ik wil niet zeuren want ik weet dat daar een ander forum voor is, maar ik ben toch al een hele tijd bezig met Michali om er uit te komen. Hij heeft steeds geholpen en zegt iets wat ik niet volledig begrijp. Dan kan ik toch vragen hoe zoiets dan moet, of mag dat niet?

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Ik denk dat ik jou nog niet helemaal goed begrijp. Geef eens een voorbeeld (met var_dump bijvoorbeeld) van hoe $_POST er uit zou kunnen zien en hoe die verwerkt zou moeten worden (dus hoe $this->model en $_SESSION er achter af uit moeten zien). Mischien zie ik dan een veel simpelere oplossing (en weet sowieso beter wat je bedoelt).

Het is vooral dit stukje dat ik niet snap:
nemesis_ schreef op maandag 03 oktober 2005 @ 16:07:
De array wordt dus wel goed gevuld nu, maar de waarde met 'remove' of met een lege waarde worden nog niet verwijderd als er children zijn.
bedoel je dat dit niet verwijderd wordt:
PHP:
1
$_POST['remove'] = array( /* iets */ );

[ Voor 38% gewijzigd door Michali op 03-10-2005 16:50 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:47

Creepy

Tactical Espionage Splatterer

nemesis_ schreef op maandag 03 oktober 2005 @ 16:42:
[...]

Creepy, ik wil niet zeuren want ik weet dat daar een ander forum voor is, maar ik ben toch al een hele tijd bezig met Michaeli om er uit te komen. Hij heeft steeds geholpen en zegt iets wat ik niet volledig begrijp. Dan kan ik toch vragen hoe zoiets dan moet, of mag dat niet?
Je vraagt direct hoe een bepaalde functie eruit moet komen te zien. Je wilt dus de code van de functie hebben en dat is een scriptrequest.

Daarbij meld je steeds "dan lukt dat niet", "het werkt niet" zonder dat je verder achterwege laat wat er nu precies niet werkt en wat je dan wel had verwacht. Michaeli vraagt dan ook steeds om verduidelijking van je omdat je dit soort zaken niet precies aangeeft. Ook omdat je niet precies meld welke zaken je nu zelf steeds hebt gedaan (behalve letterlijk de oplossingen proberen die hier door anderen gegeven zijn) lijkt het erop dat je zelf geen initiatief toont om zelf tot een oplossing te komen.

Dus: bekijk AUB de quickstart eens goed en post nu eens helder en duidelijk de zaken die daarin vermeld staan zodat het voor mij, Michaeli en anderen duidelijk is wat je nu hebt, wat daar niet mee lukt, welke zaken je nu zelf al hebt geprobeerd en wat het moet gaan worden.

[ Voor 13% gewijzigd door Creepy op 03-10-2005 16:57 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
var_dump van $_POST
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
array(18) {
  ["model_title"]=>
  string(0) ""
  ["model_descr"]=>
  string(0) ""
  ["page"]=>
  string(19) "/model/add/metadata"
  ["publish"]=>
  string(0) ""
  ["country"]=>
  string(0) ""
  ["year"]=>
  string(0) ""
  ["period"]=>
  string(0) ""
  ["perspective"]=>
  string(0) ""
  ["abstraction_level"]=>
  string(0) ""
  ["model_type"]=>
  string(0) ""
  ["scope"]=>
  string(0) ""
  ["language"]=>
  string(2) "en"
  ["topic"]=>
  array(1) {
    [1]=>
    string(16) "« remove topic »"
  }
  ["co_topic"]=>
  array(1) {
    [0]=>
    string(16) "« remove topic »"
  }
  ["related_model"]=>
  array(1) {
    [0]=>
    string(24) "« remove related model »"
  }
  ["author"]=>
  array(1) {
    [1]=>
    string(17) "« remove author »"
  }
  ["newauthor"]=>
  array(1) {
    [0]=>
    string(35) "Author last name, Author first name"
  }
  ["new"]=>
  array(1) {
    ["author"]=>
    array(5) {
      [0]=>
      array(1) {
        [0]=>
        string(17) "Author first name"
      }
      [1]=>
      array(1) {
        [0]=>
        string(16) "Author last name"
      }
      [2]=>
      array(1) {
        [0]=>
        string(19) "Author organisation"
      }
      [3]=>
      array(1) {
        [0]=>
        string(0) ""
      }
      [4]=>
      array(1) {
        [0]=>
        string(0) ""
      }
    }
  }
}

var_dump van $this->model
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
array(7) {
  ["language"]=>
  string(2) "en"
  ["topic"]=>
  array(1) {
    [1]=>
    string(16) "« remove topic »"
  }
  ["co_topic"]=>
  array(1) {
    [0]=>
    string(16) "« remove topic »"
  }
  ["related_model"]=>
  array(1) {
    [0]=>
    string(24) "« remove related model »"
  }
  ["author"]=>
  array(1) {
    [1]=>
    string(17) "« remove author »"
  }
  ["newauthor"]=>
  array(1) {
    [0]=>
    string(35) "Author last name, Author first name"
  }
  ["new"]=>
  array(1) {
    ["author"]=>
    array(5) {
      [0]=>
      array(1) {
        [0]=>
        string(17) "Author first name"
      }
      [1]=>
      array(1) {
        [0]=>
        string(16) "Author last name"
      }
      [2]=>
      array(1) {
        [0]=>
        string(19) "Author organisation"
      }
      [3]=>
      array(1) {
        [0]=>
        string(0) ""
      }
      [4]=>
      array(1) {
        [0]=>
        string(0) ""
      }
    }
  }
}
Casus:
De gebruiker kiest uit een drop-down twee bestaande authors. Die slaat hij op, maar bedenkt zich en kiest om de 2e te verwijderen. Hiervoor kiest hij de waarde "« remove author »" uit de desbetreffende drop-down.
Deze waarde moet hierna dus uit $this->model verdwijnen. Dat zou met de volgende check moeten gaan:
PHP:
1
2
3
4
5
if ($this->isValidModelDataValue($value)) {
    $this->model[$key] = $value;
} else {
    unset($this->model[$key]);
}

Bij $_POST['model_title'] gaat dit goed, zoals in de var_dumps te zien is. Bij bijvoorbeeld $_POST['author'][1] blijft de waarde "« remove author »" staan.
Ik gebruik niet unset($value) o.i.d. om iets te verwijderen, maar unset($this->model). Ik verwacht dan dat hij weggaat.
De functie ziet er nu zo uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function processModelData($array) {
    foreach ($array as $key => $value) { // we lopen door de array heen. in eerste instantie $_POST
        if ($this->isValidModelDataKey($key)) { // check of de $key wel valide is
            if (is_array($value)) { // zodra het een array is, dan moeten we checken of de waardes binnen die array ook valide zijn
                if ($this->hasChildren($value)) { // check of er children zijn (dit werkt volgens mij goed)
                    $this->processModelData($value); // doe hetzelfde proces nogmaals, maar nu met de array een laag dieper
                } else {
                    $this->model[$key] = $value; // geen kinderen, dus de data klopt?! Volgens mij zit het probleem hier, want met een var_dump($value) geeft array's terug. Mist hasChildren soms een laag?
                }
            } else {
                if ($this->isValidModelDataValue($value)) { // check of $value valide is, hier geen probleem
                    $this->model[$key] = $value; // set de waarde
                } else {
                    unset($this->model[$key]); // foute waarde, waarde eruit (geen probleem)
                }
            }
        } else {
            unset($this->model[$key]); // gooi de foute key uit de array
        }
    }
}

Zie het commentaar.
Als hasChildren false teruggeeft, dan kan $value toch geen array meer zijn (of hooguit een lege array)?

[ Voor 13% gewijzigd door nemesis_ op 03-10-2005 17:16 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
hasChildren gaat dus helemaal niet goed.
Ik kijk hier nog even naar.
Hij ziet er nu zo uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
function hasChildren($array, $hasChildren = false)
{
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $hasChildren = $this->hasChildren($value, true);
        } else {
            return false;
        }
    }
    return $hasChildren;
}

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Als ik het zo doe:
PHP:
1
2
3
4
5
6
function hasChildren($array, $hasChildren = false)
{
    foreach ($array as $key => $value) {
        return (is_array($value)) ? true : false;
    }
}

Dus zoals RwD zei, dan krijg ik idd true als er children zijn. Maar ik wil weten dat er children zijn totdat er geen children meer zijn. (hopelijk begrijp je de zin hiervoor) Ik moet dus steeds dieper de array in totdat ik één laag boven het diepste punt zit. Dus zou ik in de hasChildren een nieuwe foreach moeten maken waarin ik check of de waarde een array is? Ik ga dit even proberen (nou, morgen ga ik het proberen)

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
nemesis_ schreef op maandag 03 oktober 2005 @ 17:32:
Als ik het zo doe:
PHP:
1
2
3
4
5
6
function hasChildren($array, $hasChildren = false)
{
    foreach ($array as $key => $value) {
        return (is_array($value)) ? true : false;
    }
}

Dus zoals RwD zei, dan krijg ik idd true als er children zijn. Maar ik wil weten dat er children zijn totdat er geen children meer zijn. (hopelijk begrijp je de zin hiervoor) Ik moet dus steeds dieper de array in totdat ik één laag boven het diepste punt zit. Dus zou ik in de hasChildren een nieuwe foreach moeten maken waarin ik check of de waarde een array is? Ik ga dit even proberen (nou, morgen ga ik het proberen)
Je maakt in je functie nu wel een fout. Je bepaald nu aan de hand van het eerste item in de array of hij children heeft of niet. Stel dat het eerste item geen array is, maar het tweede wel, dan return je dus false terwijl het dus true hoort te zijn.

Zo hoort ie dus:
PHP:
1
2
3
4
5
6
7
8
9
<?
function hasChildren($array, $hasChildren = false)
{
    foreach ($array as $key => $value) {
        if ( is_array($value) ) return true;
    }
    return false;
}
?>


Kijk daarvoor uit.

Ik geloof dat ik al een betere oplossing zie.

Probeer dit eens:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?

function processModelData($array)
{
    $this->model = $this->filterModelData($array);
}

function filterModelData($rawModelData)
{
    $filteredModelData = array();
    foreach ( $rawModelData as $key => $value )
    {
        if ( !isValidModelDataKey($key) ) continue;
        if ( is_array($value) ) $value = $this->filterModelData($value);
        if ( isValidModelDataValue($value) ) $filteredModelData[$key] = $value;
    }
    return $filteredModelData;
}

?>

Als ik geen grove denk fout maak, dan is moet dit redelijk werken.

[ Voor 27% gewijzigd door Michali op 03-10-2005 18:20 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
1) Kijk nog eens naar mijn post een stukje terug.

2) Nu snap ik nogsteeds niet waar nu die hasChildren() methode voor is aangezien je dat gewoon kan afvangen met:
PHP:
1
2
3
if(is_array($value) && !empty($value)){
...
}
empty
Returns FALSE if var has a non-empty and non-zero value.

The following things are considered to be empty:
...
array() (an empty array)

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
@Michali: ik zal het morgen uittesten
@Huppie: volgens mij lukt dit niet, maar ook dit zal ik morgen uittesten

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
@Michali: thanks mate!
Dit werkt uitstekend, is simpel te lezen en is ook lekker snel.
Ik probeerde het op zich zo, maar maakte het te complex voor mezelf.

@Huppie: dit werkt toch wel, maar ik heb het opgesplitst zoals bij Michali.

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
hmm, het werkt toch niet.
Nu wordt $this->model overschreven door wat er in $_POST zit. Ik parse niet steeds alles naar m'n formulieren naar bijvoorbeeld hidden velden, dus moet $this->model aangevuld worden.
  1. Zou ik 1 array kunnen maken voor wat er uit $_POST komt en deze vergelijken met wat ik reeds heb in $this->model? Ik weet dat array_diff bestaat, maar die ziet (of ik maakte een fout) dat er iets verwijderd is uit een array.
  2. array_merge heb ik geprobeerd en die voegt weliswaar waardes toe aan de array, maar lege velden (oftewel !$this->isValidModelDataValue($value)) worden niet weggehaald.

[ Voor 21% gewijzigd door nemesis_ op 04-10-2005 10:40 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
Volgens je script wordt $this->model netjes aangevuld. Hoe voer je het precies uit?

[ Voor 159% gewijzigd door Huppie op 04-10-2005 11:10 ]

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Niet met dat script van Michali, maar daar zeg je wel $this->model = $this->filterModelData($array);
Dus ja, het is logisch, maar niet wat ik wil.

edit:
je wijzigde je post, vandaar deze edit


Met array_merge, in_array en array_diff kom ik er ook nog niet helemaal uit.
Ik heb een nieuwe variabele aangemaakt (var $modelViaPost = array();) en $this->model = $this->filterModelData($array); aangepast tot ($this->modelViaPost = $this->filterModelData($array);
Nu had ik snel dit even gemaakt, wat wel lijkt te werken als ik dieper de array in ga, terwijl hij het op de eerste laag niet doet. Ik ben hier nog in aan het debuggen:
PHP:
1
2
3
4
5
6
7
8
function checkModelDifferences($model1, $model2, $level = -1) {
    if (is_array($model1) || is_array($model2)) {
        if (!in_array($model2, $model1)) unset($model1);
        if (!in_array($model1, $model2)) unset($model2);
        $level + 1;
        $this->checkModelDifferences($model1[$level], $model2[$level]);
    }
}

Dit roep ik eerst aan:
PHP:
1
2
3
4
5
6
7
8
if (isset($_SESSION['model'])) {
    $this->model    = $_SESSION['model'];
}
$this->processModelData($_POST);
# hieronder is dus net gemaakt #
$this->checkModelDifferences($this->modelViaPost, $this->model);
$this->model = array_merge($this->model, $this->modelViaPost);
# ---- #

[ Voor 20% gewijzigd door nemesis_ op 04-10-2005 11:18 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Huppie schreef op dinsdag 04 oktober 2005 @ 10:57:
Volgens je script wordt $this->model netjes aangevuld.
Dat dacht ik dus ook.
Zie mijn vorige post (helemaal onderaan in de post) hoe ik het aanroep. Hier gebruik ik nog $this->model = $this->filterModelData($array); en niet $this->modelViaPost...

[ Voor 17% gewijzigd door nemesis_ op 04-10-2005 11:16 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
Ik denk dat je je oplossing kan vinden in array_merge_recursive :)

Daarnaast zal ik nog maar een keer zeggen dat het met mijn eerder gegeven script wel werkt (mijn testscenario):
PHP:
1
2
3
4
5
$this->model = array( 'key1' => 'henk', 'key2' => array( 'key1'=>'1', 'key2' => '2') );
$this->modelViaPost = array( 'key2' => array( 'key1' => '3' ) );
$this->processModelData($this->modelViaPost);
$this->model = array_merge_recursive( $this->model, $this->modelViaPost );
print_r( $this->model );

geeft als resultaat:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Array
(
    [key1] => henk
    [key2] => Array
        (
            [key1] => Array
                (
                    [0] => 1
                    [1] => 3
                )

            [key2] => 2
        )

)

edit:
$x-> naar $this->

[ Voor 61% gewijzigd door Huppie op 04-10-2005 12:31 ]

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
en $y is?

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Nog een poging :P

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function processModelData($array)
{
    $this->model = $this->mergeModelData($this->model, $this->filterModelData($array));
} 

function mergeModelData($currentModelData, $modelDataToMerge)
{
    $newModelData = $currentModelData;
    foreach ( $newModelData as $key => $value )
    {
        if ( !isset($modelDataToMerge[$key]) )
        {
            unset($newModelData[$key]);
        }
        elseif ( is_array($value) )
        {
            $newModelData[$key] = $this->mergeModelData($value, $modelDataToMerge[$key]);
        }
    }
    foreach ( $modelDataToMerge as $key => $value )
    {
        if ( is_array($value) && is_array($newModelData[$key]) )
        {
            $newModelData[$key] = $this->mergeModelData($newModelData[$key], $value);
        }
        else
        {
            $newModelData[$key] = $value;
        }
    }
    return $newModelData;
}

Die filter functie blijft dan wel onaangepast.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
Ow sorry dat moet natuurlijk $this->modelViaPost zijn :X

Zal het meteen aanpassen :)

@Michali, waarom heel je functie aanpassen als PHP er een standaard array_merge_recursive() voor heeft :?

[ Voor 40% gewijzigd door Huppie op 04-10-2005 12:33 ]

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Huppie schreef op dinsdag 04 oktober 2005 @ 12:30:
@Michali, waarom heel je functie aanpassen als PHP er een standaard array_merge_recursive() voor heeft :?
Ik heb geen functie aangepast (behalve processModelData dan). Heb alleen eentje toegevoegt. Ben verder niet bekend met array_merge_recursive. Ik zal er even naar kijken :)

Edit: Die functie werkt toch anders. Ik haal namelijk uit de originele array waardes weg die niet in de nieuwe voorkomen. Dat doet array_merge_recursive niet.

[ Voor 18% gewijzigd door Michali op 04-10-2005 12:51 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Michali schreef op dinsdag 04 oktober 2005 @ 12:30:
Nog een poging :P
[snip]
Die filter functie blijft dan wel onaangepast.
Ik heb echt geen idee hoe het kan, maar er gebeurt nog steeds hetzelfde. Ik post iets naar m'n sessie. Gaat goed, ik ga naar een andere pagina. Voor zover is mijn sessie nog gevuld. Maar als ik vanaf die andere pagina (waar natuurlijk andere form-elementen in staan) post, dan verdwijnen de gegevens van de vorige pagina('s) uit de sessie. Oftewel, hij overschrijft ipv aanvullen.

[ Voor 6% gewijzigd door nemesis_ op 04-10-2005 12:51 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
nemesis_ schreef op dinsdag 04 oktober 2005 @ 12:50:
[...]

Ik heb echt geen idee hoe het kan, maar er gebeurt nog steeds hetzelfde. Ik post iets naar m'n sessie. Gaat goed, ik ga naar een andere pagina. Voor zover is mijn sessie nog gevuld. Maar als ik vanaf die andere pagina (waar natuurlijk andere form-elementen in staan) post, dan verdwijnen de gegevens van de vorige pagina('s) uit de sessie. Oftewel, hij overschrijft ipv aanvullen.
En als je var_dumps doet op $_SESSION (voor en na het processen) en in het begin van die andere pagina, klopt het dan wel of niet? Roep je session_start wel goed aan? En maak je niet ergens perongeluk de sessie leeg ergens?

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Situatie nu:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class Model {
    var $model;
    var $modelViaPost;
    
    function addModelData()
    {
        global $db;
        
        if (isset($_SESSION['model'])) {
            $this->model    = $_SESSION['model'];
        }
        $this->processModelData($_POST);
        $_SESSION['model'] = $this->model; /* Ik had hem zelf er wel in gezet,
        maar deze code was ik bij het compacter maken vergeten. Op dit moment
        staat er alleen commentaar tussen $this->processModelData($_POST); en
        $_SESSION['model']=$this->model; Dus daar kan niks fout gaan.*/
    }

    function filterModelData($rawModelData)
    {
        $filteredModelData = array();
        foreach ($rawModelData as $key => $value) {
            if (!isValidModelDataKey($key)) continue;
            if (is_array($value)) $value = $this->filterModelData($value);
            if (isValidModelDataValue($value)) $filteredModelData[$key] = $value;
        }
        return $filteredModelData;
    }
    
    function processModelData($array)
    {
        $this->model = $this->mergeModelData($this->model, $this->filterModelData($array));
    }
    
    function mergeModelData($currentModelData, $modelDataToMerge)
    {
        $newModelData = $currentModelData;
        foreach ( $newModelData as $key => $value )
        {
            if ( !isset($modelDataToMerge[$key]) )
            {
                unset($newModelData[$key]);
            }
            elseif ( is_array($value) )
            {
                $newModelData[$key] = $this->mergeModelData($value, $modelDataToMerge[$key]);
            }
        }
        foreach ( $modelDataToMerge as $key => $value )
        {
            if ( is_array($value) && is_array($newModelData[$key]) )
            {
                $newModelData[$key] = $this->mergeModelData($newModelData[$key], $value);
            }
            else
            {
                $newModelData[$key] = $value;
            }
        }
        return $newModelData;
    }
...
}

[ Voor 17% gewijzigd door nemesis_ op 04-10-2005 13:25 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Je moet na het processen $this->model wel weer naar de sessie schrijven natuurlijk.

Dus na $this->processModelData($_POST); de regel $_SESSION['model'] = $this->model; zetten.

[ Voor 38% gewijzigd door Michali op 04-10-2005 12:59 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Pagina 1 heb ik iets gepost:
var_dump van $_SESSION geeft:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
array(1) {
  ["model"]=>
  array(3) {
    ["model_title"]=>
    string(5) "title"
    ["model_descr"]=>
    string(11) "description"
    ["model_pro"]=>
    array(2) {
      [1]=>
      string(5) "pro 1"
      [2]=>
      string(5) "pro 2"
    }
  }
}

Vanaf pagina 2 iet gepost (waar mijn sessie nog steeds gevuld is, want dit dumpt hij):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
array(1) { // Dit zat er in de sessie
  ["model"]=>
  array(3) {
    ["model_title"]=>
    string(5) "title"
    ["model_descr"]=>
    string(11) "description"
    ["model_pro"]=>
    array(2) {
      [1]=>
      string(5) "pro 1"
      [2]=>
      string(5) "pro 2"
    }
  }
}
Array // Dit wordt er gepost
(
    [model_title] => title
    [model_descr] => description
    [language] => en
)
array(1) { // Dit is een var_dump van $_SESSION na het hele proces
  ["model"]=>
  array(3) {
    ["model_title"]=>
    string(5) "title"
    ["model_descr"]=>
    string(11) "description"
    ["language"]=>
    string(2) "en"
  }
}

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Michali schreef op dinsdag 04 oktober 2005 @ 12:59:
Je moet na het processen $this->model wel weer naar de sessie schrijven natuurlijk.

Dus na $this->processModelData($_POST); de regel $_SESSION['model'] = $this->model; zetten.
Die staat er.

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
En dat klopt niet? (reactie op je vorige post)

[ Voor 44% gewijzigd door Michali op 04-10-2005 13:30 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Nee, dat klopt niet, want het moet zo zijn:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
array(1) {// Na het posten
  ["model"]=>
  array(4) {
    ["model_title"]=>
    string(5) "title"
    ["model_descr"]=>
    string(11) "description"
    ["model_pro"]=>
    array(2) {
      [1]=>
      string(5) "pro 1"
      [2]=>
      string(5) "pro 2"
    }
    ["language"]=>
    string(2) "en"
  }
}

"model_pro" moet er dus wel in blijven

[ Voor 24% gewijzigd door nemesis_ op 04-10-2005 13:38 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Ah ok, dan heb ik het weet verkeerd begrepen :P

Dan zou ik toch gewoon array_merge_recursive gebruiken.

Dus
PHP:
1
$this->model = array_merge_recursive($this->model, $filteredModelData);

[ Voor 3% gewijzigd door Michali op 04-10-2005 13:45 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Ik heb gekeken naar array_merge_recursive, maar volgens mij worden numerieke indexen aangevuld (ipv overschreven), als dezelfde key wordt gebruikt, en wordt lege data niet verwijderd.

[ Voor 6% gewijzigd door nemesis_ op 04-10-2005 13:53 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
PHP:
1
2
$this->model = array_merge_recursive($this->model, $filteredModelData);
// werkt niet want $filteredModelData is niet gevuld. Moet dit niet $this->filterModelData($array) zijn?

Maar hoe dan ook, met array_merge_recursive blijft hij steeds data aanvullen, alleen nu weer teveel.
Dit is na 2 keer posten:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Array (
    [model] =>
    Array (
        [model_title] =>
        Array (
            [0] => title
            [1] => title
        )
        [model_descr] =>
        Array (
            [0] => description
            [1] => description
        )
        [model_pro] =>
        Array (
            [1] => pro 1
            [2] => pro 2
            [3] => pro 1
            [4] => pro 2
        )
    )
)

ipv
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
Array (
    [model] =>
    Array (
        [model_title] => title
        [model_descr] => description
        [model_pro] =>
        Array (
            [1] => pro 1
            [2] => pro 2
        )
    )
)

[ Voor 35% gewijzigd door nemesis_ op 04-10-2005 13:54 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Dan pas je die merge functie van mij aan. Gaat dat lukken denk je?

Zo moet ie wel werken denk ik:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function mergeModelData($currentModelData, $modelDataToMerge)
{
    $newModelData = $currentModelData;
    foreach ( $modelDataToMerge as $key => $value )
    {
        if ( is_array($value) && is_array($newModelData[$key]) )
        {
            $newModelData[$key] = $this->mergeModelData($newModelData[$key], $value);
        }
        else
        {
            $newModelData[$key] = $value;
        }
    }
    return $newModelData;
}

[ Voor 77% gewijzigd door Michali op 04-10-2005 14:45 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Ook dat werkt niet helemaal, maar nu wel:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Model {
    var $model;
    
    function addModelData()
    {
        global $db;
        $this->model    = $_SESSION['model'];
        $this->processModelData($_POST);
        $_SESSION['model'] = $this->model;
    }
    
    function filterModelData($rawModelData)
    {
        $filteredModelData = array();
        foreach ($rawModelData as $key => $value) {
            if (!isValidModelDataKey($key)) continue;
            if (is_array($value)) $value = $this->filterModelData($value);
            if (isValidModelDataValue($value)) $filteredModelData[$key] = $value;
        }
        return $filteredModelData;
    }
    
    function processModelData($array)
    {
        $this->model = $this->mergeModelData($this->model, $array); // niet direct gefilterd, maar is gemerged
        $this->model = $this->filterModelData($this->model); // nu pas filteren
    }
    
    function mergeModelData($currentModelData, $modelDataToMerge)
    {
        $newModelData = $currentModelData;
        foreach ($modelDataToMerge as $key => $value) {
            if (is_array($value) && is_array($newModelData[(string)$key])) {
                $newModelData[(string)$key] = $this->mergeModelData($newModelData[(string)$key], $value);
            } else {
                $newModelData[(string)$key] = $value;
            }
        }
        return $newModelData;
    }
}

Ik filter de data pas achteraf, omdat bij het mergen data in m'n array bleef staan. Dat kwam doordat als het element uit de $_POST array verwijderd werd, hij niet meer werd verwijderd uit $this->model. Maar als het element wel nog bestaat in de $_POST array, maar wel leeg is, overschrijft hij $this->model wel.

Ik zoek nu alleen een goede manier om te checken of m'n checkboxes wel of niet aangevinkt zijn.
Ik probeer nu dit:
PHP:
1
2
3
4
5
6
7
if (isset($_POST['ur'])) {
    foreach ($this->model['ur'] as $key => $value) {
        if (!isset($_POST['ur'][$key])) {
            unset($this->model['ur'][$key]);
        }
    }
}

Dit gaat goed als er een checkbox is aangevinkt, maar fout als er helemaal geen aangevinkt zijn. $_POST['ur'] bestaat dan gewoonweg niet.
Ik kan niet altijd checken of er iets in $this->model['ur'] zit, want ook dit wordt niet op elke pagina gepost.
Ik kan ook niet zeggen if (pagina == "degene waar de $_POST['ur'] op staan"), want je kan ook vanuit deze pagina naar een andere pagina posten.
Ik kan namelijk kiezen naar welke pagina ik post: naar dezelfde pagina, maar ook een willekeurige. Het formulier is over 4 verschillende pagina's verspreid.
Dus ik moet alleen als ik vanaf de pagina met de checkboxes kom, checken of er iets aangecheckt is. 8)7 (check check check, hellup!)
Is het verstandig om dit via $_SERVER te achterhalen? Volgens mij niet.

[ Voor 34% gewijzigd door nemesis_ op 04-10-2005 17:03 ]

Ook een cookie?


Acties:
  • 0 Henk 'm!

  • nemesis_
  • Registratie: Mei 2003
  • Laatst online: 15-05-2024

nemesis_

I'm your enemy!

Topicstarter
Ik kan natuurlijk gewoon checken of ik op de pagina zit waar deze checkboxes staan, want pas nadat alles in m'n sessie is opgeslagen redirect ik hem.
Checkboxes werken nu dus ook. Volgens mij werkt alles nu!

Thanks nogmaals!

Ook een cookie?

Pagina: 1