태그 보관물: php

php

함수 호출의 다중 인수 대 단일 배열 변수 집합을

매개 변수 집합을 가져 와서 SQL 쿼리의 조건으로 적용하는 함수가 있습니다. 그러나 조건 자체를 포함하는 단일 인수 배열을 선호했습니다.

function searchQuery($params = array()) {
    foreach($params as $param => $value) {
        switch ($param) {
            case 'name':
                $query->where('name', $value);
                break;
            case 'phone':
                $query->join('phone');
                $query->where('phone', $value);
                break;
        }
    }
}

제 동료는 대신 모든 인수를 명시 적으로 나열하는 것을 선호했습니다.

function searchQuery($name = '', $phone = '') {
    if ($name) {
        $query->where('name', $value);
    }

    if ($phone) {
        $query->join('phone');
        $query->where('phone', $value);
    }
}

그의 주장은 인수를 명시 적으로 나열함으로써 신비한 주장 $param이 무엇인지 알아 내기 위해 코드를 탐구 해야하는 것과는 달리 함수의 동작이 더 분명해진다 는 것입니다.

내 문제는 10 +와 같은 많은 논쟁을 다룰 때 이것이 매우 장황하다는 것입니다. 선호하는 관행이 있습니까? 최악의 시나리오는 다음과 같습니다.

searchQuery('', '', '', '', '', '', '', '', '', '', '', '', 'search_query')



답변

IMHO 동료는 위의 예에 맞습니다. 선호도는 간결 할 수 있지만 읽기 어렵고 유지 관리하기가 쉽지 않습니다. 처음에 함수를 작성하는 것이 왜 귀찮은 지, 함수가 무엇을 ‘테이블에 가져다 놓는’지 질문하십시오. 어떻게 무엇을하는지, 어떻게 사용하는지 이해해야합니다. 그의 예제를 사용하면 PHP 프로그래머는 아니지만 함수 선언에서 구현에 대해 신경 쓸 필요가없는 세부 사항을 충분히 볼 수 있습니다.

더 많은 수의 인수는 일반적으로 코드 냄새로 간주됩니다. 일반적으로 함수가 너무 많은 것을 시도하고 있습니까? 많은 수의 인수가 실제로 필요한 경우 인수가 어떤 방식으로 관련되어 있고 하나 또는 몇 개의 구조 또는 클래스 (주소의 행과 같은 관련 항목의 배열 일 수도 있음)에 함께 속해있을 수 있습니다. 그러나 구조화되지 않은 배열을 전달하면 코드 냄새를 해결하는 데 아무런 도움이되지 않습니다.


답변

내 대답은 다소 언어에 구애받지 않습니다.

복잡한 데이터 구조 (테이블, 레코드, 사전, 객체 …)에서 인수를 그룹화하는 유일한 목적이 함수 전체에 인수를 전달하는 것이라면 피하는 것이 좋습니다. 이것은 쓸모없는 복잡성의 계층을 추가하고 의도를 모호하게 만듭니다.

그룹화 된 인수가 그 자체로 의미가있는 경우 해당 복잡성 계층은 전체 디자인을 이해하는 데 도움이됩니다. 대신 추상화 계층이라는 이름을 지정하십시오.

수십 개의 개별 인수 또는 하나의 큰 배열 대신 최상의 설계는 각각 관련 데이터를 그룹화하는 두 세 개의 인수를 사용하는 것입니다.


답변

귀하의 경우 동료의 방법을 선호합니다. 당신이 모델을 작성하고 있고 모델을 개발하기 위해 모델을 사용하고 있다면. 동료의 방법의 서명을보고 즉시 사용할 수 있습니다.

그러나 searchQuery함수에서 예상되는 매개 변수를 확인하려면 함수 구현을 거쳐야 합니다.

searchQuery단일 테이블 내에서만 검색하도록 제한된 경우 에만 조인이 없으므로 접근 방식을 선호합니다 . 이 경우 내 기능은 다음과 같습니다.

function searchQuery($params = array()) {
    foreach($params as $param => $value) {
        $query->where($param, $value);
    }
} 

따라서 배열의 요소는 실제로이 메서드를 사용하는 클래스가 코드에서 나타내는 특정 테이블 의 열 이름이라는 것을 즉시 알고 있습니다.


답변

둘 다하세요. array_merge동료가 좋아하는대로 함수의 맨 위에 명시 적 목록을 허용하면서 원하는대로 매개 변수가 다루기 어려워지지 않도록합니다.

또한 질문 의견에서 @chiborg의 제안을 사용하는 것이 좋습니다. 원하는 것이 훨씬 명확합니다.

function searchQuery($params = array()) {
    $defaults = array(
        'name' => '',
        'phone' => '',
        ....
    );
    $params = array_merge($defaults, $params);

    if(!empty($params['name'])) {
        $query->where('name', $params['name']);
    }
    if (!empty($params['phone'])) {
        $query->join('phone');
        $query->where('phone', $params['phone']);
    }
    ....
}

답변

또한 쿼리 문자열과 유사한 문자열을 전달하고 parse_str(PHP를 사용하는 것처럼 보이지만 다른 솔루션에서 다른 언어로 사용 가능하기 때문에) 메소드 내부의 배열로 처리하는 데 사용할 수 있습니다.

/**
 * Executes a search in the DB with the constraints specified in the $queryString
 * @var $queryString string The search parameters in a query string format (ie
 *      "foo=abc&bar=hello"
 * @return ResultSet the result set of performing the query
 */
function searchQuery($queryString) {
  $params = parse_str($queryString);
  if (isset($params['name'])) {
    $query->where('name', $params['name']);
  }
  if (isset($params['phone'])) {
    $query->join('phone');
    $query->where('phone', $params['phone']);
  }
  ...

  return ...;
}

그리고 그것을 이렇게 부르십시오

$result = searchQuery('name=foo&phone=555-123-456');

http_build_query연관 배열을 문자열 (역순 parse_str) 로 변환 하는 데 사용할 수 있습니다 .


답변