PHP 5:const与静态


Answers:


187

在类的上下文中,静态变量在类范围(而不是对象)的范围内,但是与const不同,它们的值可以更改。

class ClassName {
    static $my_var = 10;  /* defaults to public unless otherwise specified */
    const MY_CONST = 5;
}
echo ClassName::$my_var;   // returns 10
echo ClassName::MY_CONST;  // returns 5
ClassName::$my_var = 20;   // now equals 20
ClassName::MY_CONST = 20;  // error! won't work.

公共,受保护和私有与const无关(它们始终是公共的);它们仅对类变量(包括静态变量)有用。

  • 可以通过ClassName :: $ variable在任何地方访问公共静态变量。
  • 定义类或扩展类可以通过ClassName :: $ variable访问受保护的静态变量。
  • 私有静态变量只能由定义类通过ClassName :: $ variable访问。

编辑:必须注意,PHP 7.1.0引入了对指定类常量的可见性的支持


27
我更喜欢将其self::$variable用于受保护的静态和私有静态变量,因为我更愿意在类的内部(在类的开始处)只提及一次类名。
卢克曼

3
是的,很好,我忽略了提及,如果从类本身内部进行引用,则可以使用self关键字。我上面提供的示例是在类定义之外执行的,在这种情况下,必须使用类名。
马特·哈金斯

很好的答案,非常接近接受。您能否澄清一点:“就consts而言,公共,受保护和私有无关”-为什么?const默认是全部公开的吗?全部私人?
克里斯·雅各布

1
静态变量不需要$吗?static $my_var = 10;在定义中
Daniel W.

旧线程,但我想添加一些内容:请查看 php.net/manual/en/…,它说明了static变量在单例和递归函数中也非常有用。因为您可以更改值,但是变量将仅初始化一次。有关如何创建单例的更多说明,请参见stackoverflow.com/questions/203336/…。对我来说,在某些情况下我更喜欢静态变量。
Erik van de Ven

20

最后一点是,const始终是静态的且是公共的。这意味着您可以从类中访问const,如下所示:

class MyClass
{
     const MYCONST = true;
     public function test()
     {
          echo self::MYCONST;
     }
}

从班级外部,您可以像这样访问它:

echo MyClass::MYCONST;

1
那个声明是真的吗?那“ const永远是静态的和公共的”?
apil.tamang 2015年

7
这不再是事实。从PHP 7.1开始,类常量可以声明为私有或受保护。参见RFC
DisgruntledGoat

11

常量只是一个常量,即声明后不能更改其值。

可以访问静态变量而无需创建类的实例,因此可以在类的所有实例之间共享静态变量。

另外,在函数中可以有一个静态局部变量,该变量只能声明一次(在函数的首次执行时),并且可以在函数调用之间存储其值,例如:

function foo()
{
   static $numOfCalls = 0;
   $numOfCalls++;
   print("this function has been executed " . $numOfCalls . " times");
}

7

在谈论类继承时,您可以使用selfstatic关键字来区分不同作用域中的常量或变量。检查此示例,该示例说明了如何访问内容:

class Person
{
    static $type = 'person';

    const TYPE = 'person';

    static public function getType(){
        var_dump(self::TYPE);
        var_dump(static::TYPE);

        var_dump(self::$type);
        var_dump(static::$type);
    }
}

class Pirate extends Person
{
    static $type = 'pirate';

    const TYPE = 'pirate';
}

然后执行:

$pirate = new Pirate();
$pirate::getType();

要么:

Pirate::getType();

输出:

string(6) "person" 
string(6) "pirate" 
string(6) "person" 
string(6) "pirate"

换句话说,self::是指静态属性和常量(在这种情况下,它来自被调用的同一个作用域)(在本例中为Person超类),而static::它将在运行时从该范围中访问该属性和常量(因此,在这种情况下,Pirate子类)。

在php.net上阅读有关后期静态绑定的更多信息
还要在这里这里检查另一个问题的答案。


4

将类方法或属性声明为静态使其可以访问,而无需实例化该类。

类常量就像普通常量一样,无法在运行时更改。这也是您将const用于其中的唯一原因。

私有,公共和受保护的访问修饰符描述了谁可以访问哪个参数/方法。

公共意味着所有其他对象都可以访问。私有意味着只有实例化的类才能访问。受保护意味着实例化的类和派生的类都可以访问。


2

这是到目前为止我学到的有关静态成员,常量变量和访问修饰符(私有,公共和受保护)的知识。 不变

定义

顾名思义,常量是无法更改的。常量与普通变量的不同之处在于,您无需使用$符号来声明或使用它们。

该值必须是一个常量表达式,而不是(例如)变量,属性,数学运算结果或函数调用。

注意:变量的值不能是关键字(例如self,parent和static)。

在PHP中声明一个常量

<?php
class constantExample{

   const CONSTANT = 'constant value'; //constant

 }
?>

常量的范围是全局的,可以使用self关键字进行访问

<?php
class MyClass
{
    const CONSTANT = 'constant value';

    function showConstant() {
        echo  self::CONSTANT . "\n";
    }
}

echo MyClass::CONSTANT . "\n";

$classname = "MyClass";
echo $classname::CONSTANT . "\n"; // As of PHP 5.3.0

$class = new MyClass();
$class->showConstant();

echo $class::CONSTANT."\n"; // As of PHP 5.3.0

?>

静态的

定义

static关键字可用于声明类,成员函数或变量.class中的静态成员也可使用self关键字进行全局访问。将类属性或方法声明为static可使其无需实例化即可访问。实例化的类对象无法访问声明为静态的属性(尽管可以使用静态方法)。如果不使用可见性声明(public,private,protected),则该属性或方法将被视为声明为public。因为可以调用静态方法而无需创建对象的实例。

注意:伪变量$ this在声明为static的方法内不可用。静态属性无法使用箭头运算符->通过对象访问

从PHP 5.3.0开始,可以使用变量来引用类。>变量的值不能是关键字(例如self,parent和static)。

静态属性示例

<?php
class Foo
{
    public static $my_static = 'foo'; //static variable 

    public static function staticValue() { //static function example
        return self::$my_static;  //return the static variable declared globally
    }
}

?>

访问静态属性和函数示例

 <?php
     print Foo::$my_static . "\n";

    $foo = new Foo();
    print $foo->staticValue() . "\n";
    print $foo->my_static . "\n";      // Undefined "Property" my_static 

    print $foo::$my_static . "\n";
    $classname = 'Foo';
    print $classname::$my_static . "\n"; // As of PHP 5.3.0

    print Bar::$my_static . "\n";
    $bar = new Bar();
    print $bar->fooStatic() . "\n";

 ?>

公共,私有,受保护(又名访问修饰符)

在阅读下面的定义之前,请阅读有关封装的文章,它将帮助您更深入地理解概念。

链接1维基百科

教程指向有关封装的链接

定义

使用private,public,protected关键字,您可以控制对类中成员的访问。宣告为公开的班级成员可以在任何地方访问。声明为protected的成员只能在该类内部以及继承的和父类访问。声明为私有的成员只能由定义该成员的类访问。

 <?php 
class Example{
 public $variable = 'value'; // variable declared as public 
 protected $variable = 'value' //variable declared as protected
 private $variable = 'value'  //variable declared as private

 public function functionName() {  //public function
 //statements
 }

 protected function functionName() {  //protected function
 //statements
 }
  private function functionName() {  //private function
   //statements
   }

} 
 ?> 

访问公共,私人和受保护成员的示例

可以从类外部或类内部访问和修改公共变量。但是您只能在类内部访问私有和受保护的变量和函数,而不能在类外部修改protected或Public成员的值。

  <?php 
  class Example{
    public $pbVariable = 'value'; 
    protected $protVariable = 'value'; 
    private $privVariable = 'value';
    public function publicFun(){

     echo $this->$pbVariable;  //public variable 
     echo $this->$protVariable;  //protected variable
     echo $this->privVariable; //private variable
    }

   private function PrivateFun(){

 //some statements
  }
  protected function ProtectedFun(){

 //some statements
  }

  }


 $inst = new Example();
 $inst->pbVariable = 'AnotherVariable'; //public variable modifed from outside
 echo $inst->pbVariable;   //print the value of the public variable

 $inst->protVariable = 'var'; //you can't do this with protected variable
 echo $inst->privVariable; // This statement won't work , because variable is limited to private

 $inst->publicFun(); // this will print the values inside the function, Because the function is declared as a public function

 $inst->PrivateFun();   //this one won't work (private)
 $inst->ProtectedFun();  //this one won't work as well (protected)

  ?>

有关更多信息,请阅读此PHP文档中有关可见性Visibility Php Doc的信息。

参考:php.net

希望您能理解这个概念。感谢您的阅读:) :)


2

因此,回顾一下@Matt很棒的答案:

  • 如果您不应该更改需要的属性,则常量是正确的选择

  • 如果允许更改您需要的属性,请使用static代替

例:

class User{
    private static $PASSWORD_SALT = "ASD!@~#asd1";
    ...
}

class Product{
    const INTEREST = 0.10;
    ...
}

编辑:必须注意,PHP 7.1.0引入了对指定类常量的可见性的支持

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.