class met array van subclass

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jan R

Jan R

26/12/2020 19:30:08
Quote Anchor link
Gewone gegevens in een class zoals bool en int forceren als type kan sinds php 7.4
zoals hier
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?
class cSpeler{
    public string $Name='';
    public string $Remarq='';
    //public $Adres;
}
class cAdres {
    public string straat='';
    public string huisnummer='';
}

?>

Hoe kan ik echter adres forceren als type cAdres?
Hoe kan ik een array van type Bool of int forceren?

Jan
Gewijzigd op 26/12/2020 19:36:58 door Jan R
 
PHP hulp

PHP hulp

23/12/2024 19:17:53
 
Ward van der Put
Moderator

Ward van der Put

26/12/2020 20:29:29
Quote Anchor link
Gewoon de naam van de class gebruiken:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class cSpeler
{
    public string $Name = '';
    public string $Remarq = '';
    public cAdres $Adres;
}


class cAdres
{
    public string $straat = '';
    public string $huisnummer = '';
}

?>


Ik ben alleen niet zo gecharmeerd van lege strings '' als geldige waarde voor vereiste data. Maak die liever nullable als ze mogen ontbreken.

Voor een parameter die null mag zijn zet je een vraagteken voor het datatype:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class cSpeler
{
    public ?string $Name = null;
    public ?string $Remarq = null;
    public ?cAdres $Adres = null;
}


class cAdres
{
    public ?string $straat = null;
    public ?string $huisnummer = null;
}

?>
Gewijzigd op 26/12/2020 20:40:09 door Ward van der Put
 
Jan R

Jan R

27/12/2020 18:26:46
Quote Anchor link
Bedankt Ward. Ik had dat geprobeerd maar zal ergens een andere fout gemaakt hebben waardoor het niet werkte.
Wat met array of type? (2° vraag)

Jan
 
Ward van der Put
Moderator

Ward van der Put

28/12/2020 14:39:01
Quote Anchor link
Jan R op 27/12/2020 18:26:46:
Wat met array of type? (2° vraag)

Als een array een vaste structuur heeft, dan zou ik er een value object van maken of, afhankelijk van het gewenste gedrag. bijvoorbeeld een stack, heap of queue.
 
Jan R

Jan R

29/12/2020 01:44:07
Quote Anchor link
in mijn class heb ik meerdere X van Y voorbeeld in de classe spelers heb ik meerdere spelers;
Voor spelers heb ik al een subclasse. ik wil dus in mijn bestaande classe een array invoeren van classe spelers.
voorbeeld
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
    class clsxmt{
        public float $version=3.2;
        public int $AantalSpelers;
        public string $Name;
        public array $Speler;
        public array $MarkedGames;
    }

    class CMarkedGame {
        public int $x;
        public int $y;
        public int $color;
    }

    class cSpeler{
        public string $Name='';
        public clsAdvantage $Advantage;
        public string $StamNummer='';
        public string $Elo='';
        public string $Remarq='';
        public $Punten = array();
        public $Remarqs = array();
        public function __construct(){
            $this->Advantage = new clsAdvantage;
        }

        public int $UniekNR;        
    }

    class clsAdvantage{
        public float $Punten=0;
        public float $WeerstandsPunten=0;
        public float $WinstPunten=0;
    }

?>

Speler = array van type cSpeler
MarkedGames = array van CMarkedGame

Punten = array van string lengte 1
Remarqs = array van string lengte onbekend

Jan
 
Ward van der Put
Moderator

Ward van der Put

29/12/2020 09:54:41
Quote Anchor link
Een PHP-array heeft een relatief vrije vorm: de sleutel is altijd een integer of een string, en de waarde kan van elk datatype zijn.

Wil je een array een striktere vorm geven, dan doe je dat niet in de array zelf, maar in de methode die de array opbouwt of vult. Daartoe kun je een klasse definiëren die zich als een array gedraagt door ArrayObject te extenden of ArrayAccess te implementeren.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

04/01/2021 09:10:43
Quote Anchor link
Klein voorbeeldje van een een array property:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php

class Child
{
    protected $name; /* string */
    
    function getName() {
        return $this->name;
    }

    function
setName($name) {
        $this->name = $name;
        
        return $this;
    }
}


class Master
{
    protected $children; /* array */
    
    public function addChild(Child $child) {
        $this->children[] = $child;
        
        return $this;
    }

    
    public function getChildren() {
        return $this->children;
    }
}



$master = new Master();

$child = new Child();
$child->setName('Jan');
$master->addChild($child);

$child = new Child();
$child->setName('Miep');
$master->addChild($child);

foreach($master->getChildren() as $child)
{

    echo $child->getName() . "\n";
}

?>



Toevoeging op 04/01/2021 09:30:38:

p.s. Waar het pas interessant gaat worden is als je een functie removeChild() wilt toevoegen.
$children is in bovengenoemd voorbeeld een numerieke array. Je kan dan removeChild($key) doen maar dat is helemaal niet gebruiksvriendelijk. Als je immers de key van de array niet weet moet je dat als "gebruiker" van de class zelf gaan uitvogelen. In C++ kun je operators van de class overschrijven zodat je invloed kunt uitoefenen op het vergelijken van objecten of kopiëren van objecten. Dat kan in php helaas niet. Wel kun je aan de Child class een vergelijk functie toevoegen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
    public static function compare(&$child1, &$child2)
    {

        if ($child1->name != $child2->name)
            return 0;

        return 1;
    }

?>


Bovenstaande zou je nog beter doen door een abstracte class te schrijven met een naam als Comparable maar dat gaat misschien op dit moment wat ver..

Realiseer je ook dat je voor een goede vergelijking een unieke identifier nodig hebt. Het voorbeeld van mij voorziet hier niet in want als twee Children dezelfde $name hebben dan gaat het mis. Een unique identifier (of unique id) kan ook uit meerdere properties van de class bestaan.
Gewijzigd op 04/01/2021 09:47:03 door Frank Nietbelangrijk
 
Ward van der Put
Moderator

Ward van der Put

04/01/2021 12:27:20
Quote Anchor link
Als je met zo'n externe identifier via de interne structuur van parent directe toegang nodig hebt tot één individueel child, deugt je ontwerp waarschijnlijk niet. Vermoedelijk heb je dan functionaliteit met een eigen verantwoordelijkheid die je moet afsplitsen naar een aparte class; de parent is dan meer een container die je als traversable met een foreach doorloopt.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

04/01/2021 13:49:57
Quote Anchor link
Hoi Ward ik weet niet of ik je helemaal kan volgen of dat we op één lijn zitten maar Als je een numerieke array hebt met meerdere elementen en je wilt er één element uithalen dan zul je op een of andere manier moeten bepalen welke dat gaat worden. (Tenzij je weet welke key het is van de array maar dat laat ik even buiten beschouwing). Dat iedere class zijn eigen verantwoordelijkheid moet hebben is mij duidelijk.

Waar ik aan dacht is:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
    // masterclass
    public function removeChild(Child $child)
    {

        foreach ($this->children as $k => $c) {
            if(Child::compare($child, $c)) {
                unset($this->children[$k]);
                return true;
            }
        }

        
        return false;
    }

?>


De verantwoordelijkheid of twee Childs hetzelfde zijn of niet ligt bij de Child class. Er is ook een manier zonder compare functie middels Reflection maar dat is omslachtig en heeft ook nadelen.

Opbouwende kritiek is welkom Ward :-)
Gewijzigd op 04/01/2021 13:51:21 door Frank Nietbelangrijk
 
Ward van der Put
Moderator

Ward van der Put

04/01/2021 21:09:41
Quote Anchor link
Het was meer een algemene observatie Frank: nooit een operatie uitvoeren met iets binnen een class dat niet vanzelfsprekend tot de taak van die class hoort.

Bij een numerieke array zou ik in plaats van een interne oplopende integer de globaal unieke spl_object_id() gebruiken:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

class MasterClass
{
    private array $children = [];
    
    public function addChild(Child $child): void
    {
        $this->children[spl_object_id($child)] = $child;
    }


    public function removeChild(Child $child): bool
    {
        $key = spl_object_id($child);
        if (array_key_exists($key, $this->children)) {
            unset($this->children[$key]);
            return true;
        }

        return false;
    }
}


?>


Bestaat het gevaar dat je array letterlijk of figuurlijk een dubbele Jan Jansen bevat, voor vader en zoon bijvoorbeeld? Dan heb je dat probleem ook al buiten de array en vervolgens bij het opbouwen van de array voor de class: het is daarom geen probleem dat je in/met de class moet oplossen, want dan ben je te laat.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

05/01/2021 13:49:10
Quote Anchor link
Thanks Ward. Ja zo kan het ook al zou ik meestal voor het unique id uit de database kiezen welke je in 99% van de gevallen ook binnen handbereik hebt.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.