2009-09-08 3 views
2

PHP 아키텍트의 제안을 구하십시오!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 
) 

내가 사용에 너무 많은 다른 호출 방법을 가지고 정말 불편 해요 일부의 숨겨진 효과가 "& 포인터"스타일 함수를 사용하는 호출 함수 매개 변수에서, 일부는 본체에 출력을 쓰고, 일부는 출력을 독립적으로 작성해야합니다.

나는 하나의 방법론을 선택하고 그것을 고집하는 것을 선호합니다. 그렇게하기 위해서 가장 효율적인 방법을 알고 싶습니다. 필자가 PHP 문서를 읽었을 때 copy-on-write를 사용하기 때문에 객체를 직접 전달하고 반환 값을 다시 읽는 것에 비해 포인터를 사용하는 것이 성능 차이가 없어야 함을 나타냅니다. 또한 객체 지향 구조를 사용하는 것을 선호하지만 생성자의 입력 매개 변수에 숨겨진 변경 사항을 적용하는 것이 불편합니다.

세 가지 호출 방법 중 ParserA(), parse_b() 및 parse_c()가 가장 적합한 스타일 인 경우?

+0

그래서 무슨 문제? – cletus

답변

3

저는 PHP의 전문가는 아니지만, 가치에 의해 전달되는 경험이 더 낫습니다. 이 방법은 코드에 부작용이 없으므로 이해하고 유지 관리하기가 쉬워지고 map 함수의 콜백으로 사용하는 것과 같은 모든 종류의 미친 짓을합니다. 그래서 나는 parse_b 일을하는 방법입니다.

0

FYI : PHP에서 객체는 참조에 의해 항상 전달됩니다. 또한 객체와 스칼라 값이 포함 된 배열이있는 경우 스칼라 값은 값으로 전달되지만 객체는 참조로 전달됩니다.

+0

나는 그들이 항상 참조로 전달된다는 것이 확실하지 않다. 매개 변수 값의 내용 'unset ($ myvalues ​​[ "a"]) "에"unset "을 사용하면 함수의 $ myvalues ​​배열에서만 부모 범위의 $ values ​​배열에서"a "값이 제거되지 않습니다 범위. 즉, 참조로 전달 된 것이 아니라 값으로 전달 된 것입니다. 내 검사가 틀렸나? – ryandenki

+0

값이 변경 될 때 참조가 깨졌습니다 (원래 변수의 사본이 만들어 짐). 그래서 unset ($ myvalues ​​[ "a"])은 다음과 같은 단계를 밟습니다 : '$ myvalues'의 복사본 생성, '$ myvalues'에서 키 'a'를 가진 요소 제거 – Jacco

+0

'$ myvalues'는 그 예에서는 객체가 아닙니다. 배열 ("copy on write"값으로 전달됨) – gnarf

0

PHP에서는 일반적으로 참조가 사용되지 않는 한 사용하지 마십시오. PHP에서 참조는 대부분의 사람들은 그들이 기대하지 어떤 또한 : PHP에서

"참조 다른 이름으로 같은 변수 콘텐츠에 액세스 할 수있는 수단 그들은 C 포인터처럼되지 않으며 대신 상징입니다. 테이블 별칭.""

참조 : php.net: What References Are 그래서

짧은 :
이 값 주변의 변수를 전달 객체를 만들거나 array_map으로 배열 조작 사용이 PHP 처리의 적절한 방법 (array_map 허용 배열에 요소에 콜백 함수를 적용해야합니다.)

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