2

PHPアーキテクトからの提案を求めています!

私はPHPにあまり精通していませんが、その言語で書かれた大規模な分析パッケージの保守を引き継いでいます。このアーキテクチャは、レポートされたデータを大きなキー/値配列に読み込むように設計されています。これらの配列は、さまざまな解析モジュールを通過して、各モジュールに認識されているレポートパラメータを抽出します。既知のパラメーターはマスターアレイから削除され、どのモジュールでも認識されなかった残りは、「不明な」データポイントを示す一種のキャッチオールレポートにダンプされます。

これらのパーサーモジュールを呼び出すために使用されているいくつかの異なるメソッドがあり、どれが「適切な」PHP構造であると見なされるかを知りたいと思います。参照渡し、値渡し、関数、オブジェクトを使用しているものもあります。それらはすべて、何らかの方法で入力パラメータを変更します。

非常に単純化された例は次のとおりです。

#!/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);

?>

出力は次のようになります。

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
)

非常に多くの異なる呼び出しメソッドを使用しているのは本当に不快です。その中には、「&pointer」スタイルの関数を使用する呼び出し関数パラメーターに隠れた影響を与えるもの、本体に出力を書き込む必要があるもの、独立して出力を書き込むものがあります。

私は単一の方法論を選択し、それを堅持したいと思います。そうするために、私はまた、どれが最も効率的であるかを知りたいです。PHPのドキュメントを読んだところ、コピーオンライトを使用しているため、オブジェクトへのポインタを使用する場合と、オブジェクトを直接渡す場合と戻り値を再読み取りする場合との間にパフォーマンスの違いはあまりないはずです。また、オブジェクト指向の構造を使用したいのですが、コンストラクターの入力パラメーターに隠された変更が加えられていることに不快感を覚えます。

3つの呼び出しメソッド、ParserA()、parse_b()、およびparse_c()のうち、最も適切なスタイルはどれですか。

4

4 に答える 4

3

私は実際にはPHPの専門家ではありませんが、私の経験から、価値を渡す方が優れています。このようにすると、コードに副作用がなくなり、map関数のコールバックとして使用するなど、コードの理解と保守が容易になり、あらゆる種類のクレイジーなことを実行できるようになります。だから私はparse_b物事を行う方法がすべてです。

于 2009-09-08T09:48:01.707 に答える
0

私は一般的に提案されている方法に反対票を投じますが、そのうち、parse_bが最良のアイデアだと思います。

「データ」配列をクラスにラップして、キーを簡単に「ポップ」できるようにする方がよいと思います。したがって、パーサーは次のようになります。

class ParserA {
  private $a = null;
  public function __construct(My_Data_Class $data) {
    $this->a = $data->popValue("a");
  }
  public function toString() { return $this->a; }
}

そしてサンプル実装

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;
    }
  }
}
于 2009-09-08T10:08:56.237 に答える
0

参考:PHPでは、オブジェクトは常に参照によって渡されます。また、オブジェクトとスカラー値を含む配列がある場合、スカラー値は値によって渡されますが、オブジェクトは参照によって渡されます。

于 2009-09-08T09:59:10.730 に答える
0

PHPの原則として、本当に必要な場合を除いて、参照は使用しないでください。PHPでの参照も、ほとんどの人が期待しているものではありません。

「PHPの参照は、異なる名前で同じ変数コンテンツにアクセスするための手段です。Cポインターのようなものではなく、シンボルテーブルのエイリアスです。」

参照:php.net:参照とは

つまり、
このPHPを適切に処理する方法は、値によって変数を渡すオブジェクトを作成するか、array_mapを使用して配列を操作することです( array_mapを使用すると、配列の要素にコールバック関数を適用できます)。

于 2009-09-08T10:05:47.643 に答える