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?

+2


source to share


4 answers


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.



+3


source


FYI: In PHP, objects are always passed by reference, no matter what. Also, if you have an array with objects and scalar values ​​in it, scalar values ​​are passed by value, but objects by reference.



0


source


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.)

0


source


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;
    }
  }
}

      

0


source







All Articles