PHP architecture as well as step-by-step links and bandwidth
Search for proposals from PHP architects!
I'm not very familiar with PHP, but I took over the maintenance of a large analytics package written in this language. The architecture is designed to read reported data into large arrays of keys / values ββthat are passed through various parsing modules to extract those report parameters known to each of these modules. Known parameters are removed from the main array, and any leftovers that were not recognized by any of the modules are dumped into a report showing "unknown" data points.
There are several different methods used to call these parser modules and I would like to know what if they are considered a "correct" PHP structure. Some use pass-by-reference, others pass-by-value, some are functions, some are objects. They all modify the input parameter in some way.
An example with simplified simplification:
#!/usr/bin/php
<?php
$values = Array("a"=>1, "b"=>2, "c"=>3, "d"=>4 );
class ParserA {
private $a = null;
public function __construct(&$myvalues) {
$this->a = $myvalues["a"];
unset($myvalues["a"]);
}
public function toString() { return $this->a; }
}
// pass-by-value
function parse_b($myvalues) {
$b = $myvalues["b"];
unset($myvalues["b"]);
return Array($b, $myvalues);
}
// pass-by-reference
function parse_c(&$myvalues) {
echo "c=".$myvalues["c"]."\n";
unset($myvalues["c"]);
}
// Show beginning state
print_r($values);
// will echo "1" and remove "a" from $values
$a = new ParserA($values);
echo "a=".$a->toString()."\n";
print_r($values);
// w ill echo "2" and remove "b" from $values
list($b, $values) = parse_b($values);
echo "b=".$b."\n";
print_r($values);
// will echo "3" and remove "c" from $values
parse_c($values);
print_r($values);
?>
The output will be:
Array
(
[a] => 1
[b] => 2
[c] => 3
[d] => 4
)
a=1
Array
(
[b] => 2
[c] => 3
[d] => 4
)
b=2
Array
(
[c] => 3
[d] => 4
)
c=3
Array
(
[d] => 4
)
I am really uncomfortable with so many different invocation methods, some of which have hidden effects on the parameters of the invocation function using "& pointer" types, some of which require the main body to write its output, and some require the main organ to write its output itself.
I'd rather pick one methodology and stick with it. For this I would also like to know which one is the most effective; my reading of the PHP documentation indicates that since it uses copy-on-write, there shouldn't be much performance difference between using pointers to vs directly accessing the object and re-reading the return value. I would also prefer to use an object oriented framework, but I am uncomfortable with the hidden changes made to the constructor input parameter.
Of the three calling methods, ParserA (), parse_b () and parse_c (), if any of these is the most appropriate style?
source to share
I am not an expert in PHP but from my experience going by value is better. This way, the code will have no side effects, which means it will be easier to understand and maintain and do all sorts of crazy things on it, like using it as a callback for a function map
. So I am all for the parse_b
way of doing things.
source to share
Generally, in PHP, don't use links unless you really need to. PHP references are also not what most people expect from them:
"PHP references are a means of accessing the same contents of a variable by different names. They are not like C pointers, they are instead symbol table aliases."
see also: php.net: What links are there
Long story short: The
correct way to handle this PHP is to create an object that passes variables around the value or manipulates the array using array_map (array_map allows you to apply a callback function to the elements of an array.)
source to share
I would vote against the suggested methods, but out of them I think parse_b has a better idea.
I think it would be better to construct a wrapper around the data array in a class that could easily "pull" the key out of it. So the parser looks like this:
class ParserA {
private $a = null;
public function __construct(My_Data_Class $data) {
$this->a = $data->popValue("a");
}
public function toString() { return $this->a; }
}
And an example implementation
class My_Data_Class {
protected $_data;
public function __construct(array $data) {
$this->_data = $data;
}
public function popValue($key) {
if (isset($this->_data[$key])) {
$value = $this->_data[$key];
unset($this->_data[$key]);
return $value;
}
}
}
source to share