【问题标题】:PHP returning static variable by referencePHP通过引用返回静态变量
【发布时间】:2012-10-10 19:27:51
【问题描述】:

忽略命名空间等任何人都可以解释为什么我不能返回对我的静态数组的引用吗?实际上,该类是一个 getter 和 setter。我想使用静态方法,因为在整个应用程序生命周期中永远不需要再次实例化该类。

我知道我正在做的事情可能只是“不好的做法”——如果有更多关于这个问题的知识将不胜感激。

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

}

像这样使用它

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

你会认为我会回来

array("notmy","array");

但我只是拿回原件。

【问题讨论】:

  • 可以通过registry::add($key, $store)访问
  • 你用对了吗?见php.net reference
  • @AlvinWong 用我的使用方式更新了我的问题。
  • @JonathanTizard 也许你没有以正确的方式制作addPassing by reference

标签: php reference static return


【解决方案1】:

你可以通过deferencing返回你的静态数组:

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

您需要像这样访问它:

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

【讨论】:

    【解决方案2】:

    执行摘要:

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

    一旦你了解了它的工作原理,这真的很简单:

    • 首先,add函数必须pass by reference,否则函数中看到的值甚至不是你传入的值。

    • 其次,$global_registry中存储值时,我们必须assign by reference。否则,存储的值甚至不是函数中看到的值。

    • 第三,我们必须 return by reference 在函数声明中放置一个 & 符号。你已经这样做了,除了这段代码:

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

    和这段代码是一样的:

    return self::$global_registry[$key];
    

    因为在public static function &get这一行,我们已经声明了返回值是一个引用。

    • 最后,我们需要按引用分配返回的引用,您也这样做了:
    $test2 =& Registry::Get("config");
    

    如您所见,整个链必须是通过引用。如果任何一个步骤不是由裁判完成的,它就不会起作用。

    【讨论】:

      【解决方案3】:

      您可以使用以下代码来锻炼参考

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

      【讨论】:

        猜你喜欢
        • 2019-05-06
        • 2014-04-06
        • 1970-01-01
        • 2012-11-05
        • 1970-01-01
        • 2022-08-14
        • 2018-09-30
        • 2017-06-03
        • 1970-01-01
        相关资源
        最近更新 更多