[PHP] Multidimensionele arrays met variabele namen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hi,

Ik heb een PHP applicatie waarbij ik een aantal arrays gevuld krijg met gestructureerde data in verschillende lengtes, bijvoorbeeld:

PHP:
1
2
3
4
5
6
$array1[0]["persname"] = "Karel";
$array1[0]["nummer"] = "1645746764";
$array1[1]["persname"] = "Truus";
$array1[1]["nummer"] = "0374563";
$array2[0]["persname"] = "Piet";
$array2[0]["nummer"] = "82429886";


..er kunnen dus ook lege arrays tussen zitten (=geen return-data).

Nu heb ik ook een master array (of meta-array) met daarin de namen van de arrays en een kleine beschrijvende text:

PHP:
1
2
3
4
$master[0]["name"] = "array1";
$master[0]["desc"] = "Afdeling verkoop";
$master[1]["name"] = "array2";
$master[1]["desc"] = "Afdeling administratie";


Nu wil ik in mijn code alle data-arrays doorlopen door de master-array als sturing te gebruiken. Op dit moment heb ik zoiets:

PHP:
1
2
3
4
5
6
7
8
for ($i=0; $i<count($master); $i++) {
    if (count($$master[$i]["name"] <> 0) {
        echo $master[$i]["desc"];
        for ($j=0; $j<count($$master[$i]["name"]); $j++) {
            echo $$master[$i]["name"][$j]["persname"];
        }
    }
}


...echter; ik krijg de data uit de data-arrays er niet uit. Het script ziet wel goed dat er bepaalde arrays met data zijn (hij laat de
PHP:
1
echo $master[$i]["desc"];
netjes zien voor de gevulde arrays) maar de onderliggende data wordt niet getoond.

Iemand een idee hoe ik die data wel naar boven kan halen?
Alvast bedankt!

Mark.

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Eerst wil ik zeggen dat wat je nu doet structureel gezien en van een onderhoudbaarheidsperspectief niet handig is, en dat je ook goed na moet gaan wat de gevolgen zijn van het gebruiken van $$ (stel je voor dat bij $$a, b.v. $a beinvloed kan worden door de user.)

Je probleem is nu concreet dat de parser niet goed kan associeren wat bij wat hoort.
Dit kan je oplossen door met braces expliciet aan te duiden wat bij wat hoort:
PHP:
1
2
3
4
5
6
7
8
    for ($i=0; $i<count($master); $i++) {
        if (count(${$master[$i]["name"]}) > 0) {
            echo $master[$i]["desc"];
            for ($j=0; $j<count(${$master[$i]["name"]}); $j++) {
                echo ${$master[$i]["name"]}[$j]["persname"];
            }
        }
    }


Geeft als resultaat:
code:
1
Afdeling verkoopKarelTruusAfdeling administratiePiet


Ik weet niet of je hier blij mee moet zijn,ik zou al gauw met betere alternatieven kunnen komen iig, maar daar is het nu nogal laat voor en die hou je evt van me te goed als gotters hier al niet eerder op reageren.

Acties:
  • 0 Henk 'm!

Verwijderd

Is het zowiezo niet makkelijker om "for each" te gebruiken? Lijkt me overzichtelijkere code opleveren.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Idd.

Wat dacht je hier van:
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
<?php

$master = array();

$master[0] = array();
$master[0]["desc"] = "Afdeling verkoop";
$master[0]["items"] = array();
$master[0]["items"][0]["persname"] = "Karel";
$master[0]["items"][0]["nummer"] = "1645746764";
$master[0]["items"][1]["persname"] = "Piet";
$master[0]["items"][1]["nummer"] = "82429886";

$master[1] = array();
$master[1]["desc"] = "Afdeling administratie";
$master[1]["items"] = array();
$master[1]["items"][0]["persname"] = "Truus";
$master[1]["items"][0]["nummer"] = "0374563";

foreach ( $master as $masterItem )
{
    print "<h1>" . $masterItem['desc'] . "</h1>";
    print "<ul>";
    foreach ( $masterItem['items'] as $item )
    {
        print "<li>" . $item['persname'] . ", " . $item['nummer'] . "</li>";
    }
    print "</ul>";
}

?>

[ Voor 4% gewijzigd door Michali op 02-11-2006 09:49 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

Verwijderd

@Michali, dat bedoelde ik.... daar had ik alleen nog niet zo'n zin in op de vroege morgen O-)

Acties:
  • 0 Henk 'm!

Verwijderd

Kun je aangeven wat de voordelen zijn van deze structuur
PHP:
1
2
3
4
5
6
7
8
9
10
11
$array1[0]["persname"] = "Karel";
$array1[0]["nummer"] = "1645746764";
$array1[1]["persname"] = "Truus";
$array1[1]["nummer"] = "0374563";
$array2[0]["persname"] = "Piet";
$array2[0]["nummer"] = "82429886";

$master[0]["name"] = "array1";
$master[0]["desc"] = "Afdeling verkoop";
$master[1]["name"] = "array2";
$master[1]["desc"] = "Afdeling administratie";

ten opzichte van deze
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$master = array();

$master[0] = array();
$master[0]["desc"] = "Afdeling verkoop";
$master[0]["items"] = array();
$master[0]["items"][0]["persname"] = "Karel";
$master[0]["items"][0]["nummer"] = "1645746764";
$master[0]["items"][1]["persname"] = "Piet";
$master[0]["items"][1]["nummer"] = "82429886";

$master[1] = array();
$master[1]["desc"] = "Afdeling administratie";
$master[1]["items"] = array();
$master[1]["items"][0]["persname"] = "Truus";
$master[1]["items"][0]["nummer"] = "0374563";

Ik kan namelijk geen voorbeeld bedenken waarin dit voordelig zou zijn. Maar misschien dat je aan kunt geven waarom je voor deze oplossing kiest :)

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Omdat het een logische structuur is. Je kunt een item in een array nu meer als een object zien. Alle gegevens met betrekking een item in de master array zitten nu bij elkaar. Kijk maar eens hoe logisch het loopje er nu ineens uitziet. Het is veel gemakkelijker te begrijpen wat er gebeurt.

Dit heeft ook het voordeel dat je de taak van het printen van een master item nu gemakkelijk kunt delegeren naar een aparte functie.

Daarnaast zijn variabele variabelen smerig, zeker als je ze op deze manier gebruikt. Naar mijn idee is de voorgestelde structuur zoals ik die gaf de enige juiste.

Als je variabelen tegenkomt met de naamgeving varnameN, waarbij N dan een oplopend nummer is, dan kun je er bijna altijd zeker van zijn dat er iets op een hele omslachtige manier wordt opgelost, waar arrays veel beter voor zouden dienen.

[ Voor 16% gewijzigd door Michali op 02-11-2006 10:11 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

Verwijderd

@djingelz... als je nou een print_r doet van die $master, binnen <pre> </pre> tags ofzo ("mooie" opmaak) kan je zien waaron Michali ervoor kiest, het is namelijk een erg mooien opzet voor dit doel!

Acties:
  • 0 Henk 'm!

Verwijderd

Ter verduidelijking, ik bedoelde ook dat ik de structuur van kathmann onduidelijk vond en niet de nieuw voorgestelde structuur van Michali :)

Ik begrijp het en ik ben het helemaal met je eens. Ik vroeg me dan ook af hoe iemand een dergelijke oplossing bedenkt (wat dat betreft erg creatief :9 ) en of een dergelijke oplossing wel ooit ergens goed voor is. Zo ja, dan zie ik graag een voorbeeld :)

Acties:
  • 0 Henk 'm!

Verwijderd

Is dit niet een wat efficientere opbouw van die array?
PHP:
1
2
3
4
5
6
$master["Afdeling verkoop"] = array();
$master["Afdeling verkoop"][1645746764] = "Karel";
$master["Afdeling verkoop"][82429886] = "Piet";

$master["Afdeling administratie"] = array();
$master["Afdeling administratie"][0374563] = "Truus";

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op donderdag 02 november 2006 @ 10:35:
Is dit niet een wat efficientere opbouw van die array?
[...]
Zolang een key uniek is, ja. Maar het is de vraag of dit altijd het geval is. Van een beschrijving zou ik die garantie niet altijd willen geven.

Verder gebruik je dan data als key en dit is mijn inziens ook niet wenselijk dus ik zou voor de oplossing van Michali gaan.

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op donderdag 02 november 2006 @ 10:33:
Ter verduidelijking, ik bedoelde ook dat ik de structuur van kathmann onduidelijk vond en niet de nieuw voorgestelde structuur van Michali :)

Ik begrijp het en ik ben het helemaal met je eens. Ik vroeg me dan ook af hoe iemand een dergelijke oplossing bedenkt (wat dat betreft erg creatief :9 ) en of een dergelijke oplossing wel ooit ergens goed voor is. Zo ja, dan zie ik graag een voorbeeld :)
sorry dacht dat jij de TS was 8)7

Acties:
  • 0 Henk 'm!

Verwijderd

Het zij U vergeven :)

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Verwijderd schreef op donderdag 02 november 2006 @ 10:35:
Is dit niet een wat efficientere opbouw van die array?
PHP:
1
2
3
4
5
6
$master["Afdeling verkoop"] = array();
$master["Afdeling verkoop"][1645746764] = "Karel";
$master["Afdeling verkoop"][82429886] = "Piet";

$master["Afdeling administratie"] = array();
$master["Afdeling administratie"][0374563] = "Truus";
Dat zou niet voldoen om meerdere redenen. Ten eerste kunnen 2 personen hetzelfde nummer hebben. Misschien komt het bijna nooit voor, maar het kan wel. Kijk bijvoorbeeld naar Extreme Programming, waarbij ze aan pair programming doen, dat betekent 2 mensen achter 1 PC. Stel dat het nummer verwijst naar het bureau waar ze achter zitten, dan heb je een probleem.

Verder is het nummer mutable (wijzigbaar), terwijl de key dat niet direct is. Als het nummer dan gewijzigd wordt, moet je gaan kloten met de key, wat af te raden is.

Nog een derde reden is dat je nu niet gemakkelijk nieuwe velden kan toevoegen. Stel dat je persnaam in voornaam, tussenvoegsel en achternaam wilt veranderen, dan is dat met deze constructie niet mogelijk. Althans, niet makkelijk, omdat je code die gebruikt maakt van deze data dan ook moet gaan wijzigen, iets wat je altijd moet proberen te voorkomen.

[ Voor 15% gewijzigd door Michali op 02-11-2006 14:15 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Waarom zit iedereen toch eigenlijk toch altijd met van die array magic te kloten. Php ondersteund al sinds de vorige versie objecten. Als je dan iets gaat misbruiken, misbruik dan die objecten en gebruik ze als structs. Blijft je code een stuk duidelijker en krijg je gewoon syntax foutmeldingen als je een typefout in je code maakt.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Janoz schreef op donderdag 02 november 2006 @ 14:26:
Waarom zit iedereen toch eigenlijk toch altijd met van die array magic te kloten. Php ondersteund al sinds de vorige versie objecten. Als je dan iets gaat misbruiken, misbruik dan die objecten en gebruik ze als structs. Blijft je code een stuk duidelijker en krijg je gewoon syntax foutmeldingen als je een typefout in je code maakt.
Dat valt tegen hoor:
PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php
error_reporting(E_ALL | E_STRICT);

class foo {
    var $bar;
}
$foo =new foo;
$foo->bar = 1;
$foo->baz++;
print_r($foo);
?>

baz is een 'typefout', maar daar wordt ik niet voor gewaarschuwd...

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Als je je warnings wat hoger zet zul je daar vast wel een notice op krijgen lijkt me.


edit: Shit, ik moet toch echt afleren ongecontroleerd dingen over php te gaan roepen. Het is natuurlijk redelijk inherent aan een taal waarbij variabelen bij het eerste gebruik worden gedeclareerd. Met getters en setters daarintegen heb je dat probleem niet en zal er wel een foutmelding gegeven worden.

[ Voor 64% gewijzigd door Janoz op 02-11-2006 20:12 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Janoz schreef op donderdag 02 november 2006 @ 17:38:
Als je je warnings wat hoger zet zul je daar vast wel een notice op krijgen lijkt me.
nee, of doe ik iets verkeerd?
PHP:
1
error_reporting(E_ALL | E_STRICT | E_NOTICE);

Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
Wanneer je verwijst naar een attribuut in een klasse die niet bestaat maakt php die idd zelf aan. Ik geloof dat ze dit in PHP 6 opgelost hebben en een warning / notice laten zien.

Probeer maar eens uit :

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
error_reporting ( E_ALL | E_STRICT );

class foo 
{   
    public function check()
    {
        var_dump ( isset ( $this->foo ) );
    }
}

$foo = new foo();
$foo->check(); // false
$foo->foo = 2;
$foo->check(); // true


Statisch kan het niet:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
error_reporting ( E_ALL | E_STRICT );

class foo 
{   
    //public static $foo

    public static function check()
    {
        var_dump ( isset ( self::$foo ) );
    }
}

foo::check();
foo::$foo = 2; // fatal error
foo::check();

[ Voor 71% gewijzigd door XWB op 02-11-2006 18:12 ]

March of the Eagles


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
E_ALL | E_STRICT is idd. het hoogste (in PHP5). E_NOTICE zit bij E_ALL inbegrepen.

Noushka's Magnificent Dream | Unity

Pagina: 1