De associative array is de belangrijkste datastructuur in PHP. Standaard zijn er zo al een paar geïnitieerd, $_GET, $_POST,$_SESSION, ..php_superglobals
Maar array's zijn nogal... foutgevoelig. Voor eigen datastructuren kan je uitwijken naar objecten (zoals stdClass, ArrayObject) Maar standaard kan je ook hier nog steeds keys toevoegen of overschrijven zonder weten. Dit kan je enkel tegengaan door volledige dataclassen maken waarin je dergelijke regels kan opleggen. Dat is wel omslachtig, en je mist anderzijds veel handige array-functies. (tenzij je telkens cast)
In onderstaande klasse heb ik het idee uitgewerkt om een array te mappen "by reference" naar een nieuwe object.
De keys kan ik op voorhand makkelijk definieren. Hierdoor kan ik de bestaande array blijven gebruiken, terwijl ik op het object op elegante wijze value's kan getten, of setten, met fout controle.
In bestaande frameworks heb ik dergelijke oplossing nog niet voorbij zien komen.
Is het een goed idee? Zouden jullie dingen anders doen?
Maar array's zijn nogal... foutgevoelig. Voor eigen datastructuren kan je uitwijken naar objecten (zoals stdClass, ArrayObject) Maar standaard kan je ook hier nog steeds keys toevoegen of overschrijven zonder weten. Dit kan je enkel tegengaan door volledige dataclassen maken waarin je dergelijke regels kan opleggen. Dat is wel omslachtig, en je mist anderzijds veel handige array-functies. (tenzij je telkens cast)
In onderstaande klasse heb ik het idee uitgewerkt om een array te mappen "by reference" naar een nieuwe object.
De keys kan ik op voorhand makkelijk definieren. Hierdoor kan ik de bestaande array blijven gebruiken, terwijl ik op het object op elegante wijze value's kan getten, of setten, met fout controle.
In bestaande frameworks heb ik dergelijke oplossing nog niet voorbij zien komen.
Is het een goed idee? Zouden jullie dingen anders doen?
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
| <?php // generic data_referenceClass class ErrorType { // bits *000(0) const none = 0; // bits *001(1) const on_create = 1; // bits *010(2) const on_overwrite = 2; // bits: *111(7) (because bits *011(3) is confusing) const all = 7; } class ArrayMapper { static function test(){ // datastructure as array $data_array = array(); // map array to object with arrayMapper $data_mapper = new ArrayMapper($data_array, ErrorType::on_create); // dataMirror is coherrent with reference $data_array['greet'] = 'hello world'; echo $data_mapper->greet; // reference is coherent with ArrayMirror $data_mapper->greet = 'hello php'; echo $data_array['greet']; // if somehow you lost access to the original array, get new reference $data_array2 = &$data_mapper->getArray(); // the old one will keep up to date $data_array2['salute'] = 'New salute'; echo $data_array['salute']; // other solutions see eg arrayObject //$arrayObject = new ArrayObject(); //$arrayObject->setFlags(ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); } // static $sdata_reference; private $data_reference; private $error_type; // bind data_refernce on init public function __construct(&$data_reference,$error_type=ErrorType::none){ if(!is_array($data_reference)) throw new \exception('Data_reference is not an array'); $this->data_reference = &$data_reference; $this->setErrorType($error_type); } // error_type public function setErrorType($error_type){ $this->error_type = $error_type; } // Magic set public function __set($property, $value) { $this->set($property, $value,$this->error_type); } // Magic get public function __get($property) { return $this->get($property); } // Has key public function has($key){ return isset($this->data_reference[$key]); } // get new reference public function &getArray(){ return $this->data_reference; } // data_reference setter public function set($key=NULL,$value=NULL,$error_type=NULL){ if(is_null($error_type)) $error_type = $this->error_type; // binary compare '111'(7) with error_type: 1 & 0 = 0 only 1 & 1 = 1 if(!isset($this->data_reference[$key]) && 0<(ErrorType::on_create & $error_type) ) throw new Exception(sprintf('Key already exist: %s old value: %s',$key,$this->data_reference[$key] )); if(isset($this->data_reference[$key]) && 0<(ErrorType::on_overwrite & $error_type) ) throw new Exception(sprintf('Key does not exist',$key,$this->data_reference[$key] )); $this->data_reference[$key] = $value; //get value: $value = $object->set('key','value',false); return $value; } // data_reference getter public function get($key=null,$default_value=null,$Exception_on_null=NULL){ if( is_null($key) ) throw new Exception('Key is invalid (NULL)'); // set $Exception_on_null if defaultvalue is null if( !isset($this->data_reference[$key])){ if( is_null($default_value) && (is_null($Exception_on_null) || $Exception_on_null == true)){ throw new Exception('Key does not exist: '.$key); } } else{ $default_value = $this->data_reference[$key]; } return $default_value; } } ArrayMapper::test(); |
[Voor 13% gewijzigd door g4wx3 op 10-10-2018 20:20]