假设我有一个包含变量Bla
的课程$x
。
我希望这个变量$x
在第一个创建的对象设置后保留其他对象的值。
例如:
$object1 = new bla(.....);
$object1->setx();
$object1->getx();
$object2 = new bla(.....);
$object2->getx();
所以我想:
$object2->getx()
...给我object1
已经设定的值。
我尝试在类中使用$x
作为全局变量,事实证明这是不可能的。
我可以在课外使用它,然后在类中访问这个变量吗?
其他方法有哪些?
答案 0 :(得分:5)
如果您希望静态变量具有一个相同的值,则可以使用静态变量,无论其类实例如何都可用(tutorial):
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
答案 1 :(得分: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
,后续电话会使用该值。
答案 2 :(得分: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建议的静态。
您还应该看一下 registry pattern 。注册表模式使您能够访问整个php应用程序中的变量。
注册表的想法很简单:为发现协作者对象提供动态可能性,这样我们就不会将静态调用硬编码到全局对象中,例如每个对象中的单例。在测试环境中,我们可以使用模拟填充注册表。
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
答案 3 :(得分: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
答案 4 :(得分:0)
是的,你可以使用这个功能。 从这里“全局变量”意味着在问题中提到的一些变量。
您可以使用类的静态变量来存储全局变量的值。
class Bla {
static private $x;
}
要访问此变量,我们可以使用以下几种方法:
制作特殊的制定者和吸气者,我建议这是最简单明了的方式:
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');
当然,如果合适,您可以使用静态访问语法(公共变量或静态设置器和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. */
我们可以使用魔术设置器和getter,它结合了一个phpDoc可以“模拟”真实对象变量的行为(我的意思是在运行时它将获取并设置变量,在IDE中,它支持phpDoc,你甚至可以看到变量在自动完成)。这个解决方案违反了封装原则,因此我不建议使用它。
/**
* @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设置为private并添加特殊的访问方法,只有在您讨厌使用静态语法(self ::)时才有意义。