PHP 5: const vs tĩnh


Câu trả lời:


187

Trong ngữ cảnh của một lớp, các biến tĩnh nằm trong phạm vi phạm vi lớp (không phải đối tượng), nhưng không giống như một const, các giá trị của chúng có thể được thay đổi.

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.

Công khai, được bảo vệ và riêng tư là không liên quan về các hằng số (luôn luôn công khai); chúng chỉ hữu ích cho các biến lớp, bao gồm cả biến tĩnh.

  • các biến tĩnh công khai có thể được truy cập ở bất cứ đâu thông qua ClassName :: $ biến.
  • các biến tĩnh được bảo vệ có thể được truy cập bởi lớp định nghĩa hoặc mở rộng các lớp thông qua biến ClassName :: $.
  • các biến tĩnh riêng chỉ có thể được truy cập bởi lớp định nghĩa thông qua biến ClassName :: $.

Chỉnh sửa: Điều quan trọng cần lưu ý là PHP 7.1.0 đã giới thiệu hỗ trợ để chỉ định mức độ hiển thị của các hằng lớp .


27
Tôi thích sử dụng self::$variablecho các biến tĩnh tĩnh và riêng tư được bảo vệ vì tôi thích giữ tên lớp chỉ được đề cập một lần trong chính nó, ở đầu của lớp.
Lukman

3
Vâng, điểm tốt, tôi đã bỏ qua đề cập rằng từ khóa tự có thể được sử dụng nếu tham chiếu từ trong chính lớp. Các ví dụ tôi cung cấp ở trên được thực hiện bên ngoài định nghĩa lớp, trong trường hợp đó, tên lớp phải được sử dụng.
Matt Huggins

Câu trả lời tuyệt vời, rất gần với việc chấp nhận. Bạn có thể vui lòng làm rõ một điểm: "Công khai, được bảo vệ và riêng tư là không liên quan về các hằng số" - Tại sao? Là mặc định tất cả công khai? Tất cả đều riêng tư?
Chris Jacob

1
một var tĩnh không cần a $? static $my_var = 10;trong định nghĩa
Daniel W.

Chủ đề cũ, nhưng tôi muốn thêm một cái gì đó: kiểm tra php.net/manual/en/ , giải thích staticcác biến rất hữu ích trong singletons và các hàm đệ quy. Bởi vì bạn CÓ THỂ thay đổi giá trị nhưng biến sẽ chỉ được khởi tạo một lần. Xem stackoverflow.com/questions/203336/ trên để được giải thích thêm về cách tạo một singleton. Đối với tôi đó là một số tình huống trong đó tôi thích các biến tĩnh.
Erik van de Ven

20

Một điểm cuối cùng nên được thực hiện là một const luôn tĩnh và công khai. Điều này có nghĩa là bạn có thể truy cập const từ trong lớp như vậy:

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

Từ bên ngoài lớp bạn sẽ truy cập nó như thế này:

echo MyClass::MYCONST;

1
tuyên bố đó có đúng không? rằng "const luôn luôn tĩnh và công khai"?
apil.tamang

7
Điều này không còn đúng nữa. Kể từ các hằng lớp lớp PHP 7.1 có thể được khai báo là riêng tư hoặc được bảo vệ. Xem RFC
DisgruntledGoat

11

Hằng số chỉ là một hằng số, tức là bạn không thể thay đổi giá trị của nó sau khi khai báo.

Biến tĩnh có thể truy cập mà không cần tạo một thể hiện của một lớp và do đó được chia sẻ giữa tất cả các thể hiện của một lớp.

Ngoài ra, có thể có một biến cục bộ tĩnh trong một hàm chỉ được khai báo một lần (trong lần thực hiện đầu tiên của hàm) và có thể lưu giá trị của nó giữa các lệnh gọi hàm, ví dụ:

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

7

Khi nói về kế thừa lớp, bạn có thể phân biệt giữa hằng hoặc biến trong các phạm vi khác nhau bằng cách sử dụng selfstaticcác từ khóa. Kiểm tra ví dụ này minh họa cách truy cập cái gì:

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';
}

Và sau đó làm:

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

hoặc là:

Pirate::getType();

Đầu ra:

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

Nói cách khác, self::đề cập đến thuộc tính tĩnh và hằng số từ cùng một phạm vi nơi nó được gọi (trong trường hợp này là Personsiêu lớp), trong khi static::sẽ truy cập thuộc tính và hằng số từ phạm vi trong thời gian chạy (vì vậy trong trường hợp này là trong Piratelớp con).

Đọc thêm về liên kết tĩnh muộn ở đây trên php.net .
Ngoài ra kiểm tra câu trả lời cho một câu hỏi khác ở đâyở đây .


4

Khai báo một phương thức hoặc thuộc tính lớp là tĩnh làm cho chúng có thể truy cập được mà không cần khởi tạo lớp.

Một hằng số lớp giống như một hằng số bình thường, nó không thể thay đổi khi chạy. Đây cũng là lý do duy nhất bạn sẽ sử dụng const cho.

Riêng tư, công khai và được bảo vệ là các công cụ sửa đổi truy cập mô tả ai có thể truy cập tham số / phương thức nào.

Công cộng có nghĩa là tất cả các đối tượng khác được truy cập. Riêng tư có nghĩa là chỉ có lớp khởi tạo được truy cập. Được bảo vệ có nghĩa là lớp khởi tạo và các lớp dẫn xuất được truy cập.


2

Đây là những điều tôi đã học được cho đến nay về các thành viên tĩnh, các biến liên tục và các sửa đổi truy cập (riêng tư, công khai và được bảo vệ). Không thay đổi

Định nghĩa

Giống như tên cho biết các giá trị của biến không đổi không thể thay đổi. Các yếu tố khác với các biến thông thường ở chỗ bạn không sử dụng ký hiệu $ để khai báo hoặc sử dụng chúng.

Giá trị phải là biểu thức hằng, không (ví dụ) một biến, thuộc tính, kết quả của phép toán hoặc lệnh gọi hàm.

Lưu ý: Giá trị của biến không thể là từ khóa (ví dụ: self, Parent và static).

Khai báo một hằng trong php

<?php
class constantExample{

   const CONSTANT = 'constant value'; //constant

 }
?>

Phạm vi của Constant là toàn cầu và có thể được truy cập bằng từ khóa tự

<?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

?>

Tĩnh

Định nghĩa

Từ khóa tĩnh có thể được sử dụng để khai báo một lớp, hàm thành viên hoặc một biến. Các thành viên ổn định trong một lớp là toàn cầu có thể được truy cập bằng cách sử dụng từ khóa tự. Cũng như các thuộc tính hoặc phương thức của lớp là tĩnh giúp chúng có thể truy cập mà không cần phải khởi tạo lớp . Một thuộc tính được khai báo là tĩnh không thể được truy cập bằng một đối tượng lớp khởi tạo (mặc dù một phương thức tĩnh có thể). Nếu không có khai báo khả năng hiển thị (công khai, riêng tư, được bảo vệ), thì thuộc tính hoặc phương thức sẽ được xử lý như thể nó được khai báo là công khai. Bởi vì các phương thức tĩnh có thể gọi được mà không cần phiên bản của đối tượng được tạo.

Lưu ý: biến giả $ $ này không có sẵn bên trong phương thức được khai báo là static.Static có thể được truy cập thông qua đối tượng bằng toán tử mũi tên ->

Kể từ phiên bản PHP 5.3.0, có thể tham chiếu lớp bằng một biến. Giá trị của biến> không thể là một từ khóa (ví dụ: self, Parent và static).

Ví dụ về thuộc tính tĩnh

<?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
    }
}

?>

Truy cập các thuộc tính và ví dụ chức năng tĩnh

 <?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";

 ?>

Công khai, riêng tư, được bảo vệ (công cụ sửa đổi truy cập AKA)

Trước khi đọc định nghĩa dưới đây, hãy đọc Điều này về Đóng gói. Nó sẽ giúp bạn hiểu sâu hơn về khái niệm này.

Liên kết 1 wikipedia

Hướng dẫn liên kết điểm về đóng gói

Định nghĩa

Sử dụng các từ khóa riêng tư, công khai, được bảo vệ, bạn có thể kiểm soát quyền truy cập vào các thành viên trong một lớp. Các thành viên lớp tuyên bố công khai có thể được truy cập ở khắp mọi nơi. Các thành viên được tuyên bố bảo vệ chỉ có thể được truy cập trong chính lớp đó và bởi các lớp cha và lớp kế thừa. Các thành viên được khai báo là riêng tư chỉ có thể được truy cập bởi lớp xác định thành viên.

Thí dụ

 <?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
   }

} 
 ?> 

Truy cập ví dụ thành viên công cộng, tư nhân và được bảo vệ

Biến công khai có thể được truy cập và sửa đổi từ bên ngoài lớp hoặc bên trong lớp. Nhưng Bạn chỉ có thể truy cập các biến và hàm riêng tư và được bảo vệ từ bên trong lớp, Bạn không thể sửa đổi giá trị của các thành viên được bảo vệ hoặc Công khai bên ngoài lớp.

  <?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)

  ?>

Để biết thêm thông tin hãy đọc tài liệu php này về khả năng hiển thị Php Doc

Tài liệu tham khảo: php.net

Tôi hy vọng bạn hiểu khái niệm. Cảm ơn đã đọc :) :) Có một cái tốt


2

Vì vậy, để tóm tắt về @Matt câu trả lời tuyệt vời:

  • nếu tài sản bạn cần không nên thay đổi, thì hằng số là lựa chọn thích hợp

  • nếu thuộc tính bạn cần được phép thay đổi, hãy sử dụng tĩnh thay thế

Thí dụ:

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

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

Chỉnh sửa: Điều quan trọng cần lưu ý là PHP 7.1.0 đã giới thiệu hỗ trợ để chỉ định mức độ hiển thị của các hằng lớp .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.