【问题标题】:Why a variable can be static but can not be global in class为什么变量可以是静态的但不能在类中是全局的
【发布时间】:2015-09-14 20:38:16
【问题描述】:

我想知道为什么我不能在class 中将变量定义为global。像这样:

class MyClass {
  global $var1 = 'anything'; // syntax error
  static $var2 = 'anything'; // but it is ok
}

如果我想在不创建类实例的情况下使用 static,我知道我应该使用它。正确的 ?只有那个,没有别的吗? global 也是一样的工作吗?

其实我无法理解 phpglobal 的概念,也无法与static 比较。我知道它们都保留了这些值,但我认为区别在于 lifetime (存储持续时间)scope。那么什么时候应该使用global,什么时候应该使用static

【问题讨论】:

  • 全局变量与类无关。它将存在于全局名称空间中。结果,您将“仅”通过其名称来称呼它,它将随处可用,因此命名为“全局”。与静态成员仅在类的上下文中可用相反,您必须使用类限定符来解决它。这使得事情更加精确,更不容易出错,这就是为什么“全局变量”不受欢迎并且不应该使用的一般原因。
  • 好吧,如果你问我,我会查看规范:php.net/manual/en/language.variables.scope.php - 我没有看到任何提及在类中定义全局变量的内容,为什么要这样做?
  • 你总是把一些东西混在一起。我强烈建议您阅读以下内容:stackoverflow.com/q/16959576/3933332

标签: php oop


【解决方案1】:

staticglobal 都用于不同的目的。

  • 如果您希望您的值在您的项目或代码中保持不变,那么您需要静态。

  • 但是如果你想要一些来自函数外部的变量并直接使用它们而不将它们作为参数传递,那么你需要全局变量。它获取全局可用变量的值,并且可以更改或修改其值。

    $suv = "uvre";
    
    function global_access_tes()
    {
        //want to use suv inside this function 
       global $suv;
       $suv = "changed";
    }
    global_access_tes();
    
    echo $suv;
    // output - changed
    

【讨论】:

  • 但我认为static 并没有改变。看这个:function foo() {static $i=1; echo $i; $i++; } foo(); foo(); foo();,输出将是:123
  • @stack 声明 static 在类内部和函数内部有不同的用法。在函数中,它将在函数调用之间保留其值。在一个类中,所有值都在对象的持续时间内保留。在上面给出的函数中,$i 递增,因为static 导致它只定义一次。
  • @MarkusAO 你的评论对我来说几乎是最好的答案,谢谢。就在我们在课堂上使用static 时?无论类的任何实例是否存在,物质都存在吗?就这样?!
  • @stack,请看我在下面写的答案。我在static 上更详细地阐述了它。
【解决方案2】:

您需要在class 属性中声明global 做什么?我们在这里处理的不是普通的functions$this->var1 将从类内的任何method 或从类外的实例化对象(变量为public)中获取$var1但让我们彻底...

说明“全球”

全局对于类属性没有意义;尽管您可以将它与类方法中的变量一起使用,就像您可以使用常规函数一样。 (但有更优雅的方法可以实现;最好避免在全局范围内产生潜在危险的混乱。)让我们首先定义一个变量:

$globby = 123; // Globby is a friend living outside a function.

不使用global 声明的函数既不能从其范围之外访问变量,也不能更改该变量的值。故事是这样的:

function foo() {
    echo $globby; // Here we have no clue who globby is?
    $globby = 321; // Here we define globby, but then he's totally forgotten. :(
}
foo(); // => 'Notice: Undefined variable: globby'

echo $globby; // => '123' ... still the same old globby.

但是,将变量声明为global 的函数既可以访问它,也可以在函数范围之外修改它。此外,在函数内部新定义为全局的变量可以在函数外部访问。

function foot() {
    global $globby; // Hey globby, won't you come on in! *Globby UFO Lands*
    echo $globby; // - Who are you? - I'm globby that says 123.
    $globby = 321; // - But I'm gonna tell you to say 321 everywhere.
}

foot(); // => '123' ... this here is the good old globby from the start.
echo $globby; // => '321' ... see, globby can change outside the function scope!

说明类中的“静态”

请注意,类属性static不像函数变量static那样工作。手册:“静态变量仅存在于局部函数范围内,但当程序执行离开此范围时,它不会失去其值。”再次:“将类属性或方法声明为静态使它们无需实例化类即可访问。”OOP Static Keyword; 和 Using Static Variables)在任何情况下,类属性在对象的生命周期内都保留其值。

现在,来说明静态和非静态方法(又名“类函数”)和属性(又名“类变量”)的用法(和非用法)。让我们开一个小班:

class foo {

    static $one = 1; // This is a static variable aka. class property.
    var $two = 2; // But this is non-static.

    static function say_one() { // This is a static method.
        echo self::$one; // Uses self:: to statically access the property.
    }

    function say_two() { // This is a non-static method.
        echo $this->two; // Uses $this-> to dynamically access the property.
    }

}

那么让我们看看哪些有效,哪些无效。不可用的选项被注释掉。

/* Static Variables and Methods */

echo foo::$one; // => '1'
echo foo::say_one(); // => '1'

// echo foo::$two; 
// => "Fatal error: Access to undeclared static property: foo::$two"

// echo foo::say_two(); 
// => "Strict: Non-static method foo::say_two() should not be called statically. 
// & Fatal error: Using $this when not in object context."


/* Non-Static Variables and Methods */

$f = new foo(); // This here is a real effin' instantiated dynamite object. *BOOM*

echo $f->two; // => '2' 
echo $f->say_two(); // => '2'

// echo $f->one; 
// => "Strict: Accessing static property foo::$one as non static. 
// & Notice: Undefined property: foo::$one."

echo $f->say_one(); // => '1'

希望澄清。请注意,您可以通过实例化对象访问静态方法,并使用它来访问静态变量;但是您不能在没有警告的情况下直接访问静态变量作为非静态变量。

让我添加一个关于良好做法的说明。如果您发现需要在函数中重复声明 global 变量,或将配置参数等作为函数参数传递,则表明您可能应该将代码分解为类,将这些全局变量作为其属性访问. OOP 使用起来非常干净。你会更快乐地编码。 $OOP->nirvana();.

【讨论】:

  • 感谢您的回答,您的解释几乎是全面的,请添加更多global 应用程序的示例。并告诉我global 在类和函数方面有什么区别吗?
  • @stack:好的,现在这是一个关于所有相关事物的快乐小童话。如果缺少重要的东西,请告诉我。
  • 你能告诉我当我创建一个 myclass 的object 时会发生什么吗? static 的唯一用途是为我们提供可用性变量,而无需定义其classobject。现在我想知道当我创建一个mytable的实例时,过程是非常多的?还是公羊会满?还是什么?
  • 使用静态类和对象或“实例化类”之间的性能差异很小。在某些情况下,静态类实际上可能最终会变得更昂贵。您的 CPU 和 RAM 使用主要取决于您对课程的处理方式,而不是您访问它的方式。这是关于静态类与实例化类的好读物:stackoverflow.com/questions/1185605/…
猜你喜欢
  • 1970-01-01
  • 2020-09-29
  • 2013-10-04
  • 2011-05-13
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多