# Static Properties

## Static Properties in PHP

การประกาศ Properties ของคลาสเป็นแบบ **“static”** จะทำให้สามารถเข้าถึงได้โดยไม่ต้องสร้าง instance ของคลาส นอกจากนี้ยังสามารถเข้าถึงได้จากภายใน object ของคลาสที่ถูกสร้างขึ้นแล้ว

Static Properties คือ  คุณสมบัติของคลาส (Class Properties) ที่สามารถเข้าถึงได้โดยตรงจากตัวคลาสเอง โดยไม่จำเป็นต้องสร้าง instance (object) ของคลาสนั้นก่อน โดยทั่วไปเมื่อเราต้องการเข้าถึงคุณสมบัติหรือเมธอดของคลาส เราต้องสร้างวัตถุขึ้นมาก่อน แล้วจึงใช้ `$object->property` แต่สำหรับ Static Properties เราสามารถเข้าถึงได้ทันทีโดยใช้ `class_name::$property` ผ่าน Scope Resolution Operator (`::`) ซึ่งมีประโยชน์ในกรณีที่ต้องการเก็บข้อมูลหรือค่าที่ใช้ร่วมกันระหว่างวัตถุทั้งหมดของคลาส

### การเข้าถึง Static Properties

* `class_name::$property` เป็นการเรียกใช้งานภายนอก Class
* `self::$property` เป็นการเรียกใช้งานภายใน Class
* `parent::$property` เป็นการเรียกใช้งานภายใน Child Class หรือ Class Inheritance

### ข้อดี

* เหมาะกับการเก็บข้อมูลที่ต้องการแชร์ระหว่างทุก object ของคลาส เช่น *การนับจำนวนครั้งที่มีการสร้างวัตถุ*
* สามารถเข้าถึงค่าหรือเมธอดบางอย่างได้ทันทีจากคลาส โดยไม่ต้องสร้างวัตถุ เช่น *การเข้าถึงค่า configuration ของระบบ*
* ช่วยลดการเก็บข้อมูลซ้ำในแต่ละ object เมื่อไม่จำเป็นต้องสร้างวัตถุหลายตัว&#x20;

### ข้อเสีย

* ถ้าแก้ไขค่าในที่ใดที่หนึ่ง จะมีผลกระทบต่อทุกวัตถุที่ใช้งานคลาสนั้น
* ไม่สามารถใช้ `$this` เนื่องจาก `$this` หมายถึง object แต่ Static Properties เป็นของคลาสโดยตรง

## ตัวอย่าง Code PHP

{% code lineNumbers="true" %}

```php
<?php
class Foo
{
    public static $my_static = 'foo';    //Static Property

    public function staticValue() {
        return self::$my_static;
    }
}

class Bar extends Foo
{
    public function fooStatic() {
        return parent::$my_static;
    }
}


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

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

{% endcode %}

<details>

<summary>คำอธิาย Code</summary>

* **Class Foo**: ประกาศคลาสชื่อ `Foo` เป็นที่เก็บข้อมูลและฟังก์ชันที่เกี่ยวข้อง
* **Static Property**: `public static $my_static` เป็น Static Property สามารถเข้าถึงได้โดยตรงจากคลาส โดยมีค่าเริ่มต้นเป็น `'foo'`
* **Method staticValue()**: เมธอดนี้ใช้เพื่อเข้าถึง Static Property โดยใช้ `self::$my_static` หมายถึงการเข้าถึง Static Property จากภายในคลาสตัวเอง
* **Class Bar**: ประกาศคลาสชื่อ `Bar` สืบทอดมาจากคลาส `Foo`
* **Method fooStatic()**: เมธอดนี้ใช้ `parent::$my_static` เพื่อเข้าถึง Static Property จากคลาสแม่ (Foo) ทำให้คลาสลูกสามารถใช้ Static Property ของคลาสแม่ได้
* ใช้ `Foo::$my_static` เพื่อแสดงค่า Static Property โดยตรงจากคลาส `Foo`
* สร้าง instance ของ `Foo` และเรียกเมธอด `staticValue()` เพื่อแสดงค่า Static Property
* แสดงค่า Static Property จากคลาส `Bar` และเรียกเมธอด `fooStatic()` เพื่อคืนค่าจากคลาสแม่

</details>

### Output

```php
foo
foo

Notice: Accessing static property Foo::$my_static as non static in /in/V0Rvv on line 23

Warning: Undefined property: Foo::$my_static in /in/V0Rvv on line 23

foo
foo
foo
foo
```

การเรียกใช้งาน `static` จะทำผ่าน `Foo::$my_static` ตามที่กล่าวไปข้างต้น

## เปรียบเทียบกับภาษา Java/C/Python

### เปรียบเทียบกับภาษา Java

Static Properties ใน Java จะเรียกว่า Static Fields หรือ Static Variable โดยใช้ Keyword คำว่า "static" เช่นเดียวกับ PHP ซึ่งเป็นคุณสมบัติของคลาสที่แชร์โดยทุก instance (object) ของคลาสนั้น มักใช้สำหรับค่าคงที่หรือตัวนับที่ทุก instance (object) ต้องใช้ร่วมกัน

#### ตัวอย่าง Code Java

{% code lineNumbers="true" %}

```java
public class Bicycle {
        
    private int cadence;
    private int gear;
    private int speed;
    private int id;
    private static int numberOfBicycles = 0; // Static Variable
        
    public Bicycle(int startCadence, int startSpeed, int startGear){
        gear = startGear;
        cadence = startCadence;
        speed = startSpeed;

        // increment number of Bicycles
        // and assign ID number
        id = ++numberOfBicycles;
    }

    // new method to return the ID instance variable
    public int getID() {
        return id;
    }

    public static void main(String[] args) {
        Bicycle bike1 = new Bicycle(10, 20, 1);

        System.out.println("Number of bicycles: " + Bicycle.numberOfBicycles);
    }
}
```

{% endcode %}

<details>

<summary>คำอธิาย Code</summary>

* **Class Bicycle**: ประกาศคลาสชื่อ `Bicycle` ที่เก็บข้อมูลเกี่ยวกับจักรยาน
* **Static Variable**: `private static int numberOfBicycles` ใช้เพื่อเก็บจำนวนจักรยานที่สร้างขึ้น โดยมีค่าเริ่มต้นเป็น 0
* **Constructor**: เมื่อมีการสร้าง instance ของ `Bicycle` ตัวนับจำนวนจักรยานจะเพิ่มขึ้น และ ID จะถูกกำหนดให้กับจักรยานใหม่
* **Method getID()**: คืนค่า ID ของจักรยาน
* **Main Method**: สร้างจักรยานหนึ่งคันและแสดงจำนวนจักรยานทั้งหมดที่ถูกสร้าง

</details>

#### Output

```java
Number of bicycles: 1
```

การเรียกใช้งาน `static` จะทำผ่าน `class_name.staticVariable` ซึ่งเป็นเรื่องปกติในการใช้งานสำหรับสิ่งที่ต้องการแชร์ข้อมูลระหว่าง object

* **ความเหมือน**: ทั้ง PHP และ Java สามารถเข้าถึง Static Properties หรือ Static Fields ได้ผ่านคลาสโดยตรงโดยไม่ต้องสร้าง object
* **ความแตกต่าง**: Java อาจมีกฎและความเข้มงวดมากกว่าในการจัดการเรื่อง encapsulation และการใช้งาน static ในระดับโปรแกรมที่ซับซ้อน

### เปรียบเทียบกับภาษา C

Static Properties ในเชิง OOP <mark style="color:red;">ไม่มี</mark>ใน C เนื่องจาก C เป็นภาษาเชิงโครงสร้าง แต่ใน C มี Static Variables ที่ใช้งานในระดับฟังก์ชันหรือไฟล์ โดยจะเริ่มต้นค่าเพียงครั้งเดียวและเก็บรักษาค่าไว้จนกว่าจะสิ้นสุดโปรแกรม ใช้ Keyword คำว่า "static" ในการประกาศตัวแปรคงที่

#### ตัวอย่าง Code C

<pre class="language-c" data-line-numbers><code class="lang-c"><strong>// C Program to illustrate the static variable lifetime
</strong>#include &#x3C;stdio.h>
 
// function with static variable
int fun()
{
    static int count = 0;
    count++;
    return count;
}
 
int main()
{
    printf("%d ", fun());
    printf("%d ", fun());
    return 0;
}
</code></pre>

<details>

<summary>คำอธิาย Code</summary>

* **Function fun()**: มีตัวแปร `static int count` ที่จะคงค่าระหว่างการเรียกใช้งานของฟังก์ชัน
* **Static Variable**: ตัวแปรนี้จะไม่ถูกรีเซ็ตทุกครั้งที่ฟังก์ชันถูกเรียก ใช้เพื่อเก็บค่าที่ต้องการคงอยู่
* **Main Function**: เมื่อเรียกใช้ `fun()` จะคืนค่าจำนวนครั้งที่ถูกเรียก (1 ครั้งแรก และ 2 ครั้งที่สอง)

</details>

#### Output

```c
1 2
```

ตัวแปรที่ใช้ Keyword `static` สามารถคงค่าไว้ได้ระหว่างการเรียกใช้ฟังก์ชันหลายครั้งในโปรแกรม ไม่เหมือนตัวแปรทั่วไปที่จะถูกรีเซ็ตทุกครั้งที่เรียกฟังก์ชัน

* **ความเหมือน**: C มี Static Variables ที่คงค่าระหว่างการเรียกฟังก์ชัน เหมือนกับการคงค่าของ Static Properties ใน PHP
* **ความแตกต่าง**: C จะเน้นที่การควบคุมขอบเขตการมองเห็นของตัวแปร ไม่มีการใช้งาน Static Properties ในเชิง OOP เพราะมันไม่ใช่ภาษา OOP&#x20;

### เปรียบเทียบกับภาษา Python

Static Properties <mark style="color:red;">ไม่มี</mark>ใน Python แต่มีสิ่งที่คล้ายคลึงกันคือ Class Variables ซึ่งเป็นตัวแปรที่แชร์ระหว่าง object ทั้งหมดในคลาสเดียวกัน <mark style="color:red;">โดยไม่ใช้ Keyword คำว่า "static"</mark>

#### ตัวอย่าง Code Python

{% code lineNumbers="true" %}

```python
class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self, name):
        self.name = name    # instance variable unique to each instance

d = Dog('Fido')
e = Dog('Buddy')
print(d.kind)    # shared by all dogs
print(e.kind)    # shared by all dogs
print(d.name)    # unique to d
print(e.name)    # unique to e
```

{% endcode %}

<details>

<summary>คำอธิาย Code</summary>

* **Class Dog**: ประกาศคลาสชื่อ `Dog` ที่มี **Class Variable** ชื่อ `kind` ซึ่งแชร์ข้อมูลระหว่างทุก instance
* **Constructor**: ในเมธอด `__init__` จะมี `self.name` เป็น Instance Variable ที่เก็บชื่อของสุนัขแต่ละตัว
* **การเข้าถึง Class Variable**: `d.kind` และ `e.kind` จะคืนค่าเดียวกัน เพราะเป็น Class Variable
* **การเข้าถึง Instance Variable**: `d.name` และ `e.name` คืนค่าชื่อที่เฉพาะเจาะจงสำหรับแต่ละ instance

</details>

#### Output

```python
canine
canine
Fido
Buddy
```

การเข้าถึงทำได้ผ่าน `class_name.classVariable` ใน Python ซึ่งการทำงานคล้ายกับ PHP และ Java แต่มีความยืดหยุ่นมากกว่า เพราะ Python ไม่บังคับให้ประกาศชนิดของตัวแปรและ Syntax ของ Python ก็ดูเรียบง่ายกว่า

* **ความเหมือน**: Python ใช้ Class Variables แทน Static Properties เพื่อแชร์ข้อมูลระหว่าง object ของคลาส
* **ความแตกต่าง**: Python ยืดหยุ่นกว่ามากในเรื่องของการจัดการ Properties และไม่ต้องประกาศ Static Properties เหมือนภาษาที่เน้น OOP มากกว่า

### สรุปการเปรียบเทียบภาษา PHP กับภาษา Java/C/Python

<table><thead><tr><th width="125" align="center">คุณสมบัติ</th><th width="160" align="center">PHP</th><th width="162" align="center">Java</th><th width="161" align="center">C</th><th align="center">Python</th></tr></thead><tbody><tr><td align="center">ชื่อที่ใช้</td><td align="center">Static Properties</td><td align="center">Static Fields/Static Variables</td><td align="center">Static Variables</td><td align="center">Class Variables</td></tr><tr><td align="center">การเข้าถึง</td><td align="center"><code>class_name::$property</code></td><td align="center"><code>class_name.staticVariable</code></td><td align="center">ไม่มีการใช้งาน OOP</td><td align="center"><code>class_name.classVariable</code></td></tr><tr><td align="center">ความยืดหยุ่น</td><td align="center">จำกัด</td><td align="center">มีความเข้มงวดสูงในการใช้งาน</td><td align="center">ไม่มีการใช้งาน OOP</td><td align="center">ยืดหยุ่นมาก</td></tr><tr><td align="center">ตัวอย่างการใช้งาน</td><td align="center"><code>Foo::$my_static</code></td><td align="center"><code>Bicycle.numberOfBicycles</code></td><td align="center"><code>static int count</code> ในฟังก์ชัน</td><td align="center"><code>Dog.kind</code></td></tr><tr><td align="center">ข้อดี</td><td align="center">ใช้แชร์ข้อมูลระหว่างวัตถุ</td><td align="center">ใช้สำหรับค่าคงที่หรือการนับ</td><td align="center">เก็บค่าระหว่างการเรียกใช้ฟังก์ชัน</td><td align="center">แชร์ข้อมูลโดยไม่ต้องประกาศ Static</td></tr><tr><td align="center">ข้อเสีย</td><td align="center">แก้ไขค่าจะมีผลกระทบต่อวัตถุทั้งหมด</td><td align="center">ข้อกำหนดเข้มงวดในระดับโปรแกรม</td><td align="center">ไม่มี OOP</td><td align="center">ไม่มีการบังคับประเภทตัวแปร</td></tr></tbody></table>

## สรุป

Code ในแต่ละภาษาสามารถแสดงให้เห็นถึงการใช้ Static Properties, Static Variables และ Class Variables ที่ช่วยในการแชร์ข้อมูลระหว่าง instance ต่าง ๆ โดยไม่ต้องสร้าง instance ใหม่ทุกครั้ง ขึ้นอยู่กับการออกแบบของแต่ละภาษา แต่ละภาษาอาจมีวิธีการและแนวทางในการใช้ที่แตกต่างกัน แต่เป้าหมายหลักยังคงเหมือนเดิมคือการจัดการข้อมูลที่แชร์กันอย่างมีประสิทธิภาพ

## Slide

{% file src="<https://1214464066-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fkv9qaU0bnJC3YQ2tiEp2%2Fuploads%2FvRYYgcsdCw5rPDKPPKhp%2FPHP%20Static%20Properties%20640710583.pdf?alt=media&token=963ea235-6097-4402-a3b4-aee2b3684a13>" %}

## Video

{% embed url="<https://youtu.be/03MJzk_mMck>" %}

## Reference

> (n.d.) ย่อมาจาก *no date* ความหมายว่าไม่มีการระบุวันที่เผยแพร่หรือวันที่อ้างอิงที่ชัดเจนในแหล่งข้อมูล

<details>

<summary>PHP</summary>

#### เนื้อหา

* Static Properties in PHP: Tutorialspoint. (n.d.). *PHP static properties* \[Tutorialspoint]. [Tutorialspoint](https://www.tutorialspoint.com/php/php_static_properties.htm)
* Static Properties: pankaj\_gupta\_gfg. (2024, 19 February). *What is Static Keyword in PHP? (Static Properties)* \[geeksforgeeks]. [geeksforgeeks](https://www.geeksforgeeks.org/what-is-static-keyword-in-php/)
* Static Properties in PHP: PHP.net. (n.d.). *Static keyword (Static properties)* \[PHP.net]. [PHP.net](https://www.php.net/manual/en/language.oop5.static.php)
* การเข้าถึง Static Properties:  W3Schools. (n.d.). *PHP - Static Properties* \[W3Schools]. [W3Schools](https://www.w3schools.com/php/php_oop_static_properties.asp)

#### Code

* ตัวอย่าง Code PHP: PHP.net. (n.d.). *Static keyword (Example #2 Static property example)* \[PHP.net]. [PHP.net](https://www.php.net/manual/en/language.oop5.static.php)

</details>

<details>

<summary>Java</summary>

#### เนื้อหา

* เปรียบเทียบกับภาษา Java: Oracle. (n.d.). *Understanding Class Members (Class variables)* \[Oracle Docs]. [Oracle](https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html)
* เปรียบเทียบกับภาษา Java: Javatpoint. (n.d.). *Java static field initialization* \[Javatpoint]. [Javatpoint](https://www.javatpoint.com/java-static-field-initialization)
* เปรียบเทียบกับภาษา Java: Baeldung. (2024, January 8). *A Guide to the Static Keyword in Java (The static Fields (Or Class Variables))* \[Baeldung]. [baeldung](https://www.baeldung.com/java-static#static-fields)
* เปรียบเทียบกับภาษา Java: Gaurav Miglani. (2024, 04 October). *Static keyword in Java (Static variables)* \[geeksforgeeks]. [geeksforgeeks](https://www.geeksforgeeks.org/static-keyword-java/)

#### Code

* ตัวอย่าง Code Java: Oracle. (n.d.). *Understanding Class Members (Class variables)* \[Oracle Docs]. [Oracle](https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html)

</details>

<details>

<summary>C</summary>

#### เนื้อหา

* เปรียบเทียบกับภาษา C: GeeksforGeeks. (2024, 11 October). *Static Variables in C* \[geeksforgeeks]. [geeksforgeeks](https://www.geeksforgeeks.org/static-variables-in-c/)
* เปรียบเทียบกับภาษา C: cppreference. (2023, 06 March). *C keywords: static* \[cppreference]. [cppreference](https://en.cppreference.com/w/c/keyword/static)
* เปรียบเทียบกับภาษา C: Tutorialspoint. (n.d.). *Static Variables in C* \[Tutorialspoint]. [Tutorialspoint](https://www.tutorialspoint.com/cprogramming/c_static_variables.htm)

#### Code

* ตัวอย่าง Code C: GeeksforGeeks. (2024, 11 October). *Static Variables in C* \[geeksforgeeks]. [geeksforgeeks](https://www.geeksforgeeks.org/static-variables-in-c/)

</details>

<details>

<summary>Python</summary>

#### เนื้อหา

* เปรียบเทียบกับภาษา Python: GeeksforGeeks. (2024, 30 September). *Class or Static Variables in Python* \[geeksforgeeks]. [geeksforgeeks](https://www.geeksforgeeks.org/g-fact-34-class-or-static-variables-in-python/)
* เปรียบเทียบกับภาษา Python: Tutorialspoint. (n.d.). *Python - Class Attributes* \[Tutorialspoint]. [Tutorialspoint](https://www.tutorialspoint.com/python/python_class_attributes.htm)

#### Code

* ตัวอย่าง Code Python: Python.org. (2024, 12 October). *Class and instance variables* \[Python Docs]. [Python](https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables)

</details>

<details>

<summary>Slide</summary>

* เนื้อหา: Suparak Metthasat. (2024, 13 October). *PHP-Static Properties* \[Giftbook]. [Suparak Metthasat.gitbook](https://suparak-metthasat.gitbook.io/suparak-metthasat/php-static-properties)
* ตัวอย่าง Code PHP: PHP.net. (n.d.). *Static keyword (Example #2 Static property example)* \[PHP.net]. [PHP.net](https://www.php.net/manual/en/language.oop5.static.php)
* ตัวอย่าง Code Java: Suparak Metthasat. (2024, 13 October). *PHP-Static Properties (*[*ตัวอย่าง Code Java*](#code-java)*)* \[Giftbook]. [Suparak Metthasat.gitbook](https://suparak-metthasat.gitbook.io/suparak-metthasat/php-static-properties)
* ตัวอย่าง Code C: GeeksforGeeks. (2024, 11 October). *Static Variables in C* \[geeksforgeeks]. [geeksforgeeks](https://www.geeksforgeeks.org/static-variables-in-c/)
* ตัวอย่าง Code Python: Python.org. (2024, 12 October). *Class and instance variables* \[Python Docs]. [Python](https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables)
* สรุปการเปรียบเทียบกับภาษา Java/C/Python: Suparak Metthasat. (2024, 13 October). *PHP-Static Properties (*[สรุปการเปรียบเทียบภาษา PHP กับภาษา Java/C/Python](#php-java-c-python)) \[Giftbook]. [Suparak Metthasat.gitbook](https://suparak-metthasat.gitbook.io/suparak-metthasat/php-static-properties)

</details>
