Biến Static trong lập trình PHP (03/07/2010

Một vấn đề thường gặp trong lập trình khi có dùng nhiều Class, lập trình OOP, đòi hỏi đôi khi một số thuộc tính là duy nhất trong các sub-Class cũng như tầm vực khi gọi. Ngoài ra đôi khi bạn cần gọi hàm trực tiếp không thông qua việc tạo đối tượng cho nhanh. Trong những trường hợp như vậy PHP5 trở đi hỗ trợ cho bạn 1 từ khóa Static rất mạnh mẽ. Ta hãy xem xét những ví dụ sau để hiểu rõ hơn cách sử dụng nó:

 

Example 1: Phương thức ma thuật _callStatic()

Trong PHP V5.3 có một phương thức ma thuật mới được thêm vào: __callStatic(). Nó làm việc tương tự như phương thức ma thuật __call() được thiết kế để xử lý các cuộc gọi ra phương thức cho các phương thức mà không được xác định hoặc nhìn thấy được trong lớp. Tuy nhiên, __callStatic() được thiết kế để xử lý các cuộc gọi ra phương thức tĩnh, chúng cho chúng ta khả năng thiết kế tốt hơn sự quá tải về phương thức của chúng ta. Một ví dụ về cách sử dụng phương thức này như dưới đây.

Ví dụ về việc sử dụng __callStatic() đối với __call()

class Foo 
{ 
    public static function __callStatic( 
        $name, 
        $args 
        ) 
    { 
        echo "Called method $name statically"; 
    } 

    public function __call( 
        $name, 
        $args 
        ) 
    { 
        echo "Called method $name"; 
    } 
} 

Foo::dog();       // outputs "Called method dog statically" 
$foo = new Foo; 
$foo->dog();      // outputs "Called method dog" 

Example 2: với từ khóa Static, ta có thể gọi hàm trực tiếp sử dụng toán tử " :: " thay cho tạo 1 đối tượng mới 

class Dog 
{ 
    public static function bark() 
    { 
         echo "Woof!"; 
    } 
} 

$class = 'Dog'; 
$action = 'bark';
$class::$action();  //outputs "Woof!"  

Quan trọng: Gọi hàm bằng phương pháp trực tiếp như trên nếu có từ khóa Static sẽ giúp bạn không bị lỗi E_STRICT trong lập trình PHP.

Example 3: các biến Static được chia sẽ trong cùng các sub Class 

class MyParent {
    
    protected static 
$variable;
}

class 
Child1 extends MyParent {
    
    function 
set() {
        
        
self::$variable 2;
    }
}

class 
Child2 extends MyParent {
    
    function 
show() {
        
        echo(
self::$variable);
    }
}

$c1 = new Child1();
$c1->set();
$c2 = new Child2();
$c2->show(); // prints 2
?>

Example 4: tầm vực khi dùng Static:  

// experiments with static
// tested on PHP 5.2.6  on 1-21-09

class User{
    const 
GIVEN 1;  // class constants can't be labeled static nor assigned visibility
    
public $a=2;
    public static 
$b=3;
    
    public function 
me(){ 
        echo 
"print me";
    }
     public static function 
you() {
        echo 
"print you";
    }
}

class 
myUser extends User {
}

// Are properties and methods instantiated to an object of a class, & are they accessible?
//$object1= new User();        // uncomment this line with each of the following lines individually
//echo $object1->GIVEN . "";        // yields nothing
//echo $object1->GIVE . "";        //  deliberately misnamed, still yields nothing
//echo $object1->User::GIVEN . "";    // yields nothing
//echo $object1->a . "";        // yields 2
//echo $object1->b . "";        // yields nothing
//echo $object1->me() . "";        // yields print me
//echo $object1->you() . "";        // yields print you

// Are  properties and methods instantiated to an object of a child class,  & are accessible?
//$object2= new myUser();        // uncomment this line with each of the following lines individually
//echo $object2->GIVEN . "";        // yields nothing
//echo $object2->a . "";        // yields 2
//echo $object2->b . "";        // yields nothing
//echo $object2->me() . "";        // yields print me
//echo $object2->you() . "";        // yields print you

// Are the properties and methods accessible directly in the class?
//echo User::GIVEN . "";        // yields 1
//echo User::$a . "";            // yields fatal error since it is not static
//echo User::$b . "";            // yields 3
//echo User::me() . "";        // yields print me
//echo User::you() . "";        // yields print you

// Are the properties and methods copied to the child class and are they accessible?
//echo myUser::GIVEN . "";        // yields 1
//echo myUser::$a . "";        // yields fatal error since it is not static
//echo myUser::$b . "";        // yields 3
//echo myUser::me() . "";        // yields print me
//echo myUser::you() . "";        // yields print you
?>

Example 5: Liên kết tĩnh muôn:

Một trong những điều phiền phức nhất về PHP trước V5.3 là cách phương thức và thành viên tĩnh được xử lý. Cho đến nay, các tham chiếu tĩnh (static references), chẳng hạn như các tham chiếu được làm bản thân nó hoặc __CLASS__, được giải quyết trong phạm vi lớp, trong đó hàm được định nghĩa. Vấn đề là ở chỗ tham chiếu sẽ không đúng nếu lớp được mở rộng và cuộc gọi được thực hiện từ lớp con (child class) mới. Liên kết tĩnh muộn đã được thêm vào PHP V5.3 để giảm bớt vấn đề này. Để minh hoạ rõ hơn, chúng ta hãy tạo ra một lớp với một phương thức tĩnh dưới đây

Lớp Foo với phương thức tĩnh test()

class Foo 
{ 
    protected static $name = 'Foo'; 

    public static function test() 
    { 
        return self::$name; 
    } 
}  

Chúng ta hãy mở rộng lớp này. Chúng ta sẽ định nghĩa lại thành viên $name trong lớp con này.

Lớp con Bar mở rộng lớp cha Foo

    class Bar extends Foo
    {
       protected static $name = 'Bar';
    }

echo Bar::test();

Kết quả từ cuộc gọi đó sẽ là chuỗi Foo. Đây là do tham chiếu self::$name thực hiện trong phương thức test() được thực hiện bằng lớp Foo. Liên kết xuất hiện bằng cách này vì đây là nơi hàm được định nghĩa.

PHP V5.3 đã thêm từ khoá static để cho phép bạn thực hiện một tham chiếu đối với lớp hiện tại. Do đó bạn sẽ thay đổi lớp Footrên để sử dụng từ khoá này trong Liệt kê 8, và chúng ta sẽ thấy rằng Bar sẽ thay vào kết quả.

Sử dụng từ khoá static

class Foo 
{ 
    protected static $name = 'Foo'; 

    public static function test() 
    { 
        return static::$name; 
    } 
} 

class Bar 
{ 
    protected static $name = 'Bar'; 
} 

echo Bar::test(); // outputs 'Bar'

Một điều cần lưu ý về từ khoá static là nó không làm việc như cách làm trong ngữ cảnh không tĩnh. Điều này có nghĩa là các nguyên tắc kế thừa bình thường không áp dụng với các cuộc gọi tĩnh. Từ khoá static sẽ chỉ cần cố gắng giải quyết cuộc gọi trong lớp hiện tại thay cho lớp mà hàm được định nghĩa. Đây là một điều quan trọng cần lưu ý. 

Hiểu được các ví dụ trên sẽ giúp bạn rất nhiều trong lập trình Class và OOP. 

 

Theo Hoàng Long @ www.ytuongsangtaovn.com

 
Khách hàng mới nhất
Đăng ký nhận khuyến mãi
Tư vấn trực tuyến
Dịch vụ Tin học
Y!M:  
Skype:  Skype Me!
Mobile:  0903028978 (a.Long)
Dịch vụ Kế toán
Y!M:  
Skype:  Skype Me!
Mobile:  0983068614 (c.Uyên)
hoặc sử dụng trang liên hệ
CSS Font-Size: em vs. px vs. pt vs. percent (27/08/2012

One of the most confusing aspects of CSS styling is the application of the font-size attribute for text scaling. In CSS, you’re given four different units by which you can measure the size of text as it’s displayed in the web browser. Which of these four units is best suited for the web? It’s a question that’s spawned a diverse variety of debate and criticism. Finding a definitive answer can be difficult, most likely because the question, itself, is so difficult to answer.

CSS Arrows and Shapes Without Markup (22/08/2012

Often it’s useful to show an arrow or some sort of contextual indication of what element something is related to. We see this frequently with tooltips that use arrows to point to the item that is triggering them.

The IE border-spacing workaround (19/07/2012

Everyone knows these two HTML table tag attributes: cellpadding and cellspacing. And everyone hates the annoying necessity of these attributes in the CSS era. Well, developers, who has looked after what's up now about this issue, have learned that fortunately the cellpadding attribute is safely substitutable with the padding value of the table cells.

But what about cellspacing?

The differences between the GPL, LGPL and the BSD (22/08/2011

There are a lot of different open source licences out there, and it can sometimes be a bit confusing if you're not intimate with the details of each one. So here's a quick roundup of three of the most popular licenses and the difference between them.

Just a quick disclaimer - I'm not a lawyer, so don't depend on my explanations on the licences here. All the usual disclaimers apply.

Trang: 1 2 3 ››