Php 非静态方法中的静态在实例之间共享
我遇到了一些意外的行为,对象方法中定义的静态变量在实例之间共享。这可能是已知的行为,但当我浏览PHP文档时,在对象方法中找不到静态定义变量的实例 以下是我遇到的行为的简化:Php 非静态方法中的静态在实例之间共享,php,Php,我遇到了一些意外的行为,对象方法中定义的静态变量在实例之间共享。这可能是已知的行为,但当我浏览PHP文档时,在对象方法中找不到静态定义变量的实例 以下是我遇到的行为的简化: <?php class Foo { public function dofoo() { static $i = 0; echo $i++ . '<br>'; } } $f = new Foo; $g = new Foo; $f->dofoo(); // expected
<?php
class Foo {
public function dofoo() {
static $i = 0;
echo $i++ . '<br>';
}
}
$f = new Foo;
$g = new Foo;
$f->dofoo(); // expected 0, got 0
$f->dofoo(); // expected 1, got 1
$f->dofoo(); // expected 2, got 2
$g->dofoo(); // expected 0, got 3
$g->dofoo(); // expected 1, got 4
$g->dofoo(); // expected 2, got 5
这是静态的
如果希望成员特定于对象的实例,则可以使用
e、 g
这就是static,它在类的所有实例中都是相同的变量
class Foo {
private $i = 0;
public function dofoo() {
echo $this->i++ . '<br>';
}
}
您希望编写此代码,使变量成为类实例的私有成员
class Foo {
private $i = 0;
public function dofoo() {
echo $this->i++ . '<br>';
}
}
class-Foo{
私人$i=0;
公共函数dofoo(){
echo$this->i++.
;
}
}
静态关键字可以使用,也可以使用。静态变量是在PHP4中引入的(我想,它可能更早)。PHP5中引入了静态类成员/方法
因此,根据手册,一个静态变量
变量作用域的另一个重要特征是静态
变量静态变量仅存在于局部函数中
作用域,但在程序执行时它不会丢失其值
离开这个范围
这与你描述的行为一致。如果需要每个实例变量,请使用常规类成员 我同意当前的PHP文档对于非静态方法中静态变量的“作用域”的确切含义不够清楚
当然,正如hobodave所指出的,“静态”通常意味着“每个类”,但静态类属性与(非静态)方法中的静态变量并不完全相同,因为后者由方法“限定范围”(类中的每个方法都可以有自己的静态$foo变量,但最多可以有一个名为$foo的静态类成员)
我认为,尽管PHP5的行为是一致的(“静态”总是意味着“每个类一个共享实例”),但这并不是PHP的唯一行为方式
例如,大多数人使用静态函数变量在函数调用中保持状态,而对于全局函数,PHP行为正是大多数人所期望的。因此,可以想象一个PHP解释器在方法调用中维护某些方法变量的状态,并且“每个实例”都这样做,这实际上也是我第一次声明局部方法变量为静态时所期望的情况。Ups 7年了,时间很长,但不管怎样,还是这样
所有的类都有一个默认构造函数,我为什么这么说?!?
因为如果在构造函数中定义默认行为,则类的每个实例都将受到影响
例如:
namespace Statics;
class Foo
{
protected static $_count;
public function Bar()
{
return self::$_count++;
}
public function __construct()
{
self::$_count = 0;
}
}
namespace Statics;
class Foo
{
//default value
protected static $_count = 0;
public function Bar()
{
return self::$_count++;
}
public function __construct()
{
//do something else
}
}
导致:
require 'Foo.php';
use Statics\Foo;
$bar = new Foo();
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
$barcode = new Foo();
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
0
1
2
0
1
2
require 'Foo.php';
use Statics\Foo;
$bar = new Foo();
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
$barcode = new Foo();
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
0
1
2
3
4
5
导致:
require 'Foo.php';
use Statics\Foo;
$bar = new Foo();
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
$barcode = new Foo();
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
0
1
2
0
1
2
require 'Foo.php';
use Statics\Foo;
$bar = new Foo();
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
echo $bar->bar().'<br>';
$barcode = new Foo();
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
echo $barcode->bar().'<br>';
0
1
2
3
4
5
需要'Foo.php';
使用Statics\Foo;
$bar=新的Foo();
echo$bar->bar()。
;
echo$bar->bar()。
;
echo$bar->bar()。
;
$barcode=新的Foo();
echo$barcode->bar()。
;
echo$barcode->bar()。
;
echo$barcode->bar()。
;
0
1.
2.
3.
4.
5.
正如您所看到的,结果是完全不同的,类实例之间的内存空间分配是相同的,但它可以根据您定义默认值的方式产生不同的结果
我希望这有帮助,不是因为上面的答案是错误的,而是我觉得从这个角度理解all概念很重要
来自葡萄牙的尊敬!文档是针对静态类属性和方法的,而不是方法中的静态变量。亚当:在PHP5中,它们是一个相同的。静态是静态的。在我看来,$f->dofoo()
与$g->dofoo()不同。显然,PHP开发人员的想法不一样。:)你是对的,它们不一样,但它们都作用于同一个变量,因为您将其标记为静态。感谢Dave,这与我所寻找的更为接近:静态引用(在某种程度上)绑定到代码行,而不是执行期间定义的任何实例。