2012-10-20 5 views
4

이름 공간 등을 무시하면 정적 배열에 대한 참조를 반환 할 수없는 이유를 설명 할 수 있습니까? 효과적으로 클래스는 getter와 setter입니다. 클래스를 응용 프로그램 수명주기 전체에 걸쳐 다시 인스턴스화 할 필요가 없기 때문에 정적 메서드를 사용하려고했습니다. 이 문제에 더 이상 지식을 감상 할 수있다 -PHP는 참조로 정적 변수를 반환합니다.

는 난 그냥 "나쁜 연습"이 될 수도 뭘하는지 이해합니다.

namespace xtend\core\classes; 
use xtend\core\classes\exceptions; 

class registry { 

private static $global_registry = array(); 

private function __construct() {} 

public static function add($key, $store) { 
    if (!isset(self::$global_registry[$key])) { 
     self::$global_registry[$key] = $store; 
    } else { 
     throw new exceptions\invalidParameterException(
      "Failed to add the registry. The key $key already exists." 
     ); 
    } 
} 

public static function remove($key) { 
    if (isset(self::$global_registry[$key])) { 
     unset(self::$global_registry[$key]); 
    } else { 
     throw new exceptions\invalidParameterException(
      "Cannot remove key $key does not exist in the registry" 
     ); 
    } 
} 

public static function &get($key) { 
    if (isset(self::$global_registry[$key])) { 
     $ref =& self::$global_registry[$key]; 
     return $ref; 
    } else { 
     throw new exceptions\invalidParameterException(
      "Cannot get key $key does not exist in the registry" 
     ); 
    } 
} 

} 

내가 다시

array("notmy","array"); 

을 얻을 귀하는 가정 것이

$test = array("my","array"); 
\xtend\core\classes\registry::add("config",&$test); 
$test2 =& \xtend\core\classes\registry::get("config"); 
$test2[0] = "notmy";  
print_r($test); 

처럼 것이다 사용하지만 난 그냥 원본을 다시 얻을.

+0

당신이 :: 레지스트리를 통해 액세스가 제대로을 사용하고 ($ 키 $ 저장소) –

+0

을 추가 할 수 있습니다위한 운동에 다음 코드를 사용할 수 있습니까? See [php.net reference] (http://php.net/manual/en/language.references.return.php) –

+0

@AlvinWong은 내 질문을 어떻게 사용하고 있는지 업데이트했습니다. –

답변

1

집행 요약 :

class Registry { 
    private static $global_registry = array(); 

    public static function Add($key, &$value){ 
     static::$global_registry[$key] =& $value; 
    } 
    public static function &Get($key){ 
     return static::$global_registry[$key]; 
    } 
    public static function Remove($key){ 
     unset(static::$global_registry[$key]); 
    } 
} 

$test = array("my", "array"); 
Registry::Add("config", $test); 
$test2 =& Registry::Get("config"); 
$test2[0] = "notmy";  
var_dump($test); 

그것은 정말 아주 일단 그것이 어떻게 작동하는지 이해하면 간단합니다 :

첫째 6,
  • ,add 기능해야 pass by reference 함수에서 볼 수있다 그렇지 않으면 값은 전달에도 값이 아닙니다.

  • 둘째 , 가치를 저장할 때 $global_registry, 우리는 assign by reference이어야합니다. 그렇지 않으면 저장된 값은 함수에 표시된 값조차도 아닙니다.

  • 세 번째로return by reference 함수 선언에 앰퍼샌드를 넣어야합니다.

$ref =& self::$global_registry[$key]; // redundant line 
return $ref; 

이 코드와 동일합니다 : 당신은 이미이 코드를 제외하고,이 작업을 수행 한 라인 public static function &get에, 우리가 이미 선언했기 때문에

return self::$global_registry[$key]; 

그 반환 값 참조입니다.

  • 그리고 마지막으로, 우리는 당신이 또한 한 한 기준에 의해 반환 된 참조를 할당해야합니다 :
$test2 =& Registry::Get("config"); 

당신이 볼 수있는 바와 같이, 전체 체인해야 참조하십시오.단계 중 하나라도 리퍼러가 수행하지 않으면 작동하지 않습니다.

0

당신은 deferencing하여 정적 배열을 반환 할 수 있습니다

$ref = &self::$global_registry[$key]; 

당신은 이런 식으로 접근해야합니다 :

$keyVal = &registry::get($key); 
-1

당신은 참조

class Apple { 

    public static $basket = [], $scripts =[]; 

    public static function addToBasket($grapes) { 
     self::$scripts =& self::AppStatic(__CLASS__ . __METHOD__, array()); 
     self::$scripts[$grapes] = ['type' => $grapes]; 
     return self::$scripts; 
    } 

    public static function &AppStatic($name, $default_value = NULL) { 
     if (isset(self::$basket[$name]) || array_key_exists($name, self::$basket)) { 
      return self::$basket[$name]; 
     } 

     if (isset($name)) { 
      return self::$basket[$name] = &$default_value; 
     } 

     $data = NULL; 
     foreach (self::$basket as $key => $value) { 
      $data[$key] = $value; 
     } 
     return $data; 
    } 
} 
관련 문제