3

假设我有一个Bla包含变量的类$x

我希望此变量$x在由第一个创建的对象设置后保留其对其他对象的值。

例如:

$object1 = new bla(.....);
$object1->setx();
$object1->getx();

$object2 = new bla(.....);
$object2->getx();

所以我想要:

 $object2->getx()

...给我已经设定的价值object1

我尝试$x在类中使用全局变量,结果证明这是不可能的。我可以在课堂外使用它,然后在课堂内访问这个变量吗?

其他方法是什么?

4

5 回答 5

5

如果您希望它们具有相同的值,请使用静态变量,无论它们的类实例如何(教程)都可用:

class bla
{
    private static $x;

    public function setx($x) {
        self::$x = $x;
    }

    public function getx() {
        return self::$x;
    }
}

$object1 = new bla();
$object1->setx(5);
echo $object1->getx();
echo '<br>';

$object2 = new bla();
echo $object2->getx();

输出:

5
5
于 2013-07-05T10:47:03.647 回答
0
class Bla {
    static private $x = "X!";
}

如果您知道x初始化时应该做什么,那么只需使用上述内容。如果x计算,那么您可以确保它只设置一次:

class Bla {
    static private $x = null;
    public function getX(){
        if($this->x === null){
            $this->x = theLogicToGetX();
        }
        return $this->x;
    }
}

只有第一个调用会设置x,后续调用将使用该值。

于 2013-07-05T10:50:57.807 回答
0

有参考是可能的

class A
{
  private $a;

  public function &getA(){return $this->a;}
  public function setA($a) { $this->a = $a;}  
}

class B
{
  public function useA(&$a) { $a+=5 ;}
}

$objA = new A();
$objB = new B();
$objA->setA(5); //seting value of a in A class to 5
$objB->useA($objA->getA()); //modify the reference of A class $a variable in B class object

echo $objA->getA(); //echo the value from A class object

输出: 10

我的解决方案没有静态限制。因此它可以用于同一类的多个对象。如果您想通过相同的类对象访问类变量,请使用 Lukas 上面建议的静态。

您还应该查看注册表模式。注册表模式使您能够访问整个 php 应用程序中的变量。

Registry 的想法很简单:为发现合作者对象提供动态可能性,这样我们就不会在每个对象中硬编码对全局对象(如 Singleton)的静态调用。在测试环境中,我们可以用 mocks 填充 Registry。

 class Registry
 {
    private static $instance;
    private $registry = array();
    private function __construct()
    {

    }

    public function  getInstance()
    {
         if(self::$instance == null) self::$instance = new Registry();
            return self::$instance;
    }

    public function __set($var,$val)
    {
       $this->registry[$var] = $val;
    }

    public function __get($var)
    {
       if(isset($this->registry[$var]))
            return $this->registry[$var];
       else throw new Exception("Value $var doesn't exists in registry");
    }



 }


 class A
 {
   public function useVar()
   {
     Registry::getInstance()->myVar += 10;
   }

   public function echoVar()
   {
     echo Registry::getInstance()->myVar;
   }
 }

 Registry::getInstance()->myVar = 5;
 $obj1 = new A();
 $obj2 = new A();

 $obj1->useVar();
 $obj2->echoVar();

输出:15

于 2013-07-05T10:56:21.343 回答
0

看例子:

<?php
class Foo {
    private static $my_static = 'foo';
    /**
     * Set static class property
     * 
     * @param string $v
     */
    public function setStaticValue($v) {
        self::$my_static = $v;
    }
    /**
     * Get static class property value
     * 
     * @return string
     */
    public function getStaticValue() {
        return self::$my_static;
    }
}
// show class static property value
echo foo::getStaticValue(); // foo
// now set new value in static property
foo::setStaticValue(' zoo ');
// show value
echo foo::getStaticValue(); // zoo
// make an object of class
$f = new Foo();
// show value
echo $f->getStaticValue(); // zoo
// make new object of class
$f2 = new Foo();
// show value
echo $f2->getStaticValue(); // zoo
于 2013-07-05T11:07:57.980 回答
0

是的,你可以做这个功能。从这里开始,“全局变量”是指问题中提到的某种变量。

您可以使用类的静态变量来存储全局变量的值。

class Bla {
    static private $x;
}

要访问此变量,我们可以使用几种方法:

制作特殊的 setter 和 getter,我建议这是最简单明了的方法:

class Bla {
    static private $x = 'init value';

    public function getX() {
        return self::$x;
    }

    public function setX($value) {
        self::$x = $value;
    }
}

// Usage:
$obj1 = new Bla();
echo $obj1->getX();// init value
$obj1->setX('changed value');

当然,如果合适的话,您可以只使用静态访问语法(公共变量或静态 setter 和 getter),这比第一种方法更简单明了。例如:

class Bla {
    static public $x = 'init value';
}

// Usage:
echo Bla::$x;
Bla::$x = 3;

还要记住,对象在 PHP5 中是通过引用传递的。

class Bla {
    private $date;

    public function __construct(DateTime $x) {
        $this->date = $x;
    }

    public function getDate() {
        return $this->date;
    }
}

$date = new DateTime();

// Usage:
$obj1 = new Bla($date);
$obj2 = new Bla($date);
/* now play with $objN->getDate()->.. and $date->.. 
 * to see, that $x in both objects are referring to same variable. */

现在让我们看看一些不太好的方法。

我们可以使用魔法 setter 和 getter,结合 phpDoc 可以“模拟”真实对象变量的行为(我的意思是在运行时它将获取和设置变量,在支持 phpDoc 的 IDE 中,您甚至可以在 auto-完成)。这种解决方案违反了封装原则,所以我不推荐它的常用用法。

/**
 * @property mixed $x My global var.
 */
class Bla {
    static private $x = 'init value';

    public function __set($name, $value) {
        if ($name == 'x') {
            self::$x = $value;
        }
    }

    public function __get($name) {
        if ($name == 'x') {
            return self::$x;
        }
    }
}
// Usage:
$obj1 = new Bla();
echo $obj1->x;// init value
$obj1->x = 'changed value';

没有魔法我们可以使用引用获得相同的行为:

class Bla {
    static $storage = 'init value';
    public $x;

    public function __construct() {
        $this->x = &self::$storage;
    }
}

我们也可以在这里将 $x 设为私有并添加特殊的访问方法,这只有在您讨厌使用静态语法 (self::) 时才有意义。

于 2013-07-05T13:56:49.473 回答