PHP 中的静态变量

问题描述 投票:0回答:6

我发现了有关 PHP 中静态变量的不同信息,但没有任何信息能够真正解释它是什么以及它是如何工作的。

我读过,当在类中使用时,静态属性不能被该类实例化的任何对象使用,而静态方法可以被该类实例化的对象使用?

但是,我一直在尝试研究静态变量在不在类中的函数中的作用。另外,函数中的静态变量的工作方式是否有点像 javascript 中的闭包,还是我完全不同意这个假设?

php variables static
6个回答
72
投票

我读到,当在类中使用静态属性时,该类实例化的任何对象都不能使用静态属性

这取决于你的意思。例如:

class Foo {
    static $my_var = 'Foo';
}

$x = new Foo();

echo $x::$my_var;  // works fine
echo $x->my_var;   // doesn't work - Notice: Undefined property: Foo::$my_var

并且静态方法可以由类实例化的对象使用???

是的,属于该类的实例化对象可以访问静态方法。

类上下文中的关键字

static
的行为有点像其他语言中的静态类变量。声明为
static
的成员(方法或变量)与类相关联,而不是与该类的实例相关联。因此,您可以在没有类实例的情况下访问它(例如:在上面的示例中,我可以使用
Foo::$my_var


但是,我一直在尝试研究静态变量在不在类中的函数中的作用。

另外,函数中的静态变量的工作方式是否有点像 javascript 中的闭包,或者我完全不同意这个假设。

在类之外(即:在函数中),

static
变量是当函数退出时不会丢失其值的变量。所以从某种意义上说,是的,它们的工作方式就像 JavaScript 中的闭包。

但与 JS 闭包不同的是,同一函数的不同调用中只维护一个变量值。来自 PHP 手册的示例:

function test()
{
    static $a = 0;
    echo $a;
    $a++;
}

test();  // prints 0
test();  // prints 1
test();  // prints 2

参考:
static
关键字(在类中)(在函数中)


39
投票

static
在 PHP 中有两个用途:

首先,也是最常见的,它可用于定义“类”变量/函数(与实例变量/函数相对),无需实例化类即可访问:

class A {
  public static $var = 'val'; // $var is static (in class context)
  public $other_var = 'other_val'; // non-static
}

echo A::$var; // val
echo A::$other_var // doesn't work (fatal error, undefined static variable)

$a = new A;
echo $a->var // won't work (strict standards)
echo $a->other_var // other_val

其次,它可用于维护函数调用之间的状态:

function a() {
  static $i = 0;
  $j = 0;
  return array($i++, $j++);
}
print_r(a()); // array(0, 0)
print_r(a()); // array(1, 0)
print_r(a()); // array(2, 0)
//...

请注意,无论函数是否在类中定义,在函数中声明变量 static 的效果都是相同的,重要的是声明 variable 的位置(类成员或函数中)。


11
投票

函数中的静态变量仅在其运行脚本中第一次调用该函数时初始化。


11
投票

首先我会解释一下如果不使用静态变量会发生什么

<?php
function somename() {
    $var = 1;
    echo $var . "<br />";
    $var++;
}
somename();
somename();
somename();
?>

如果运行上面的代码,您得到的输出将是 1 1 1 。因为每次调用该函数变量都会赋值为 1,然后打印它。


现在让我们看看如果使用静态变量会怎样

<?php
function somename() {
    static $var = 1;
    echo $var . "<br />";
    $var++;
}
somename();
somename();
somename();
?>

现在,如果运行此代码片段,输出将为 1 2 3。

注意: Static 会在每次调用函数时保持其值并保留。当函数被调用时它不会丢失它的值。


3
投票
class Student {
static $total_student = 0;
static  function add_student(){
    return Student::$total_student++;
}
}

第一:对于add_student函数,最佳实践是使用static而不是public。 第二:在add_student函数中,我们使用的是Student::$total_student,而不是使用$this->total_student。这与普通变量有很大不同。 第三:静态变量在整个继承树中共享。

使用下面的代码看看结果是什么:

class One {
static $foo ;
}
class Two extends One{}
class Three extends One{}
One::$foo = 1;
Two::$foo = 2;
Three::$foo = 3;
echo One::$foo;
echo Two::$foo;
echo Three::$foo;`

0
投票

静态类属性也可用于在该类的所有实例之间共享值。

<?php

class Foo {
    public static array $static = [];
    public array $nonStatic = [];

    public function add(string $text): void
    {
        self::$static[] = $text;
        $this->nonStatic[] = $text;
    }
}

$first = new Foo();
$first->add('Lorem ipsum');

$second = new Foo();
$second->add('Dolor sit amet');

var_dump($first::$static); // ['Lorem ipsum', 'Dolor sit amet']
var_dump($first->nonStatic); // ['Lorem ipsum']
var_dump($second::$static); // ['Lorem ipsum', 'Dolor sit amet']
var_dump($second->nonStatic); // ['Dolor sit amet']

例如,我最近在基于 Symfony 的项目中使用这种方法向 AMQP(一种在功能测试中运行时覆盖常规服务的虚假服务)发送消息的虚假服务,以检查在多个 HTTP 期间应该发送的内容请求。

© www.soinside.com 2019 - 2024. All rights reserved.