http://www.joy24.net/33   에서 참조

 

serialize() 함수
형식 : string serialize(mixed value)
PHP4 스크립트부터 객체를 serialize() 함수를 이용하여 다른 매체에 저장할 수 있는 문자열로 직렬화(serialize)시킬 수 있습니다. PHP3에서도 객체의 멤버변수까지는 직렬화할 수 있었지만 메소드까지는 지원되지 않았는데 PHP4부터는 메소드까지 지원하기 시작한 것이지요. 여러분이 잘 알고 계시는 세션함수가 내부적으로 바로 serialize()를 이용하여 등록된 세션변수값을 파일로 저장할 수 있도록 직렬화하는 것입니다. 그런데 이 serialize() 함수가 객체를 다룰 때 멤버변수만 다루지 메소드는 무시해 버립니다. 정확하게 이야기 하면 메소드 정의를 포함하고 있는 클래스명만 기록하며 클래스에 포함된 메소드 정의 부분은 다루지 않습니다. 앞장 “클래스와 인스턴스"를 주의깊게 읽어 보셨다면 serialize() 함수가 왜 메소드 정의를 다루지 않는 지를 이해할 수 있을 것입니다. serialize() 함수는 객체를 다루는 함수이지 클래스를 다루는 함수는 아닙니다. 객체에는 메소드가 포함되어 있지 않습니다. 따라서 객체를 직렬화한다고 해도 클래스에 포함되어 있는 메소드 정의 부분을 직렬화한다는 것은 올바르지 않지요. 메소드는 같은 클래스에서 생성된 모든 객체가 공유해야 할 정보이지 특정 객체에만 편입된 정보가 아니기 때문에 특정 객체를 직렬화 한다고 해서 직렬화된 정보에 메소드 정의 정보가 포함될 수 없는 것입니다. 이젠 제가 왜 serialize()/unserialize() 함수를 설명하기 전에 "클래스와 인스턴스"라는 주제를 앞 장에 삽입하여 장황하게 설명했는지 이해하실 것 입니다. 클래스와 인스턴스 개념을 이해하고 있지 못하면 왜 serialize() 함수가 메소드 정의 부분을 포함하여 직렬화 시키지 않았는지를 이해할 수가 없습니다.
예를 들어 아래와 같이 session_register() 함수를 이용하여 객체 변수 $obj를 등록시키겠습니다.
[code php;gutter:true]<?php
// 파일명 : test1.php

class test {
  var $a = "1234ASDF”;
 
  function test() {}
 
  function output() {
    echo($this->a);
  }
}
 
session_register(“obj”);
$obj = new test();
$obj->output();
?>

<p><A href=test2.php>TEST2.PHP</A></p> [/code]

이와 같이 세션 등록을 하면 스크립트가 종료되는 순간에 객체를 serialize() 함수를 이용하여 직렬화한 후 서버의 /tmp 디렉토리에 sess_xxxxxxxxxxx 파일명으로 직렬화된 문자열을 저장하게 되는데 그 내용이 아래와 같습니다.
obj|O:4:“test”:1:{s:1:“a”;s:8:“1234ASDF”;}
여기서 obj는 객체변수명, “test"는 클래스명, "a"는 멤버변수명, "1234ASDF"는 멤버변수값을 나타냅니다. 메소드에 관한 정보는 모두 빠져 있는 것을 볼 수 있습니다. 만약 PHP3에서 serialize() 함수를 이용하여 객체를 직렬화 하였다면 멤버변수는 멤버변수명과 멤버변수값이 모두 정상적으로 기록되지만 메소드는 메소드명만 기록되지 메소드 정의 부분이 기록하지 않습니다. 이것이 PHP4에 와서는 메소드명까지 기록하지 않게 되었습니다. 대신에 클래스명이 기록되지요.
unserialize() 함수
형식 : mixed serialize(string str)
unserialize() 함수는 serialize() 함수를 이용하여 객체로부터 직렬화된 문자열을 다시 객체로 복원시켜 줍니다. serialize() 함수를 설명할 때 언급한 것처럼 직렬화할 때 객체의 메소드의 정보가 기록되지 않기 때문에 unserialize() 함수로 다시 객체화하더라도 우선 멤버변수만 접근할 수 있지 메소드는 접근할 수 없습니다.
[code php;gutter:true]<?php
// 파일명 : test2.php
 
session_register("obj”);
$obj->output();
?>
 
<p><A href=test1.php>TEST1.PHP</A></p> [/code]
위의 예제에서 5번째줄 $obj->output()는 객체의 메소드를 실행하여야 하는데 객체의 메소드는 복원할 수 없으므로 아래와 같은 에러가 발생합니다.
Fatal error: Call to undefined function: output()
in /서버의 디렉토리/test2.php on line 5
따라서 세션함수에 의해 복원된 객체를 가지고 메소드를 실행하기 위해서는 복원된 페이지 내에서 원래의 클래스의 정의를 아래와 같이 명시적으로 포함시켜야 합니다. 즉, 메소드 정의는 별도로 복원시켜주어야 하는 것이지요.
[code php;gutter:true]<?php
// 파일명 : test2.php
 
class test {
  function output() {
    echo($this->a);
  }
}
session_register(“obj”);
$obj->output();
?>
 
<p><A href=test1.php>TEST1.PHP</A></p> [/code]
PHP4 에서 객체의 serialize() 함수가 멤버변수와 메소드를 모두 지원한다 하더라도 메소드 정의 부분은 포함되지 않으므로 unserialize() 함수로 복원된 객체를 온전히 사용하기 위해서는 메소드 정의를 별도로 포함시켜야 한다는 것에 주의하여야 합니다

http://www.joy24.net/33   에서 참조

 

serialize() 함수
형식 : string serialize(mixed value)
PHP4 스크립트부터 객체를 serialize() 함수를 이용하여 다른 매체에 저장할 수 있는 문자열로 직렬화(serialize)시킬 수 있습니다. PHP3에서도 객체의 멤버변수까지는 직렬화할 수 있었지만 메소드까지는 지원되지 않았는데 PHP4부터는 메소드까지 지원하기 시작한 것이지요. 여러분이 잘 알고 계시는 세션함수가 내부적으로 바로 serialize()를 이용하여 등록된 세션변수값을 파일로 저장할 수 있도록 직렬화하는 것입니다. 그런데 이 serialize() 함수가 객체를 다룰 때 멤버변수만 다루지 메소드는 무시해 버립니다. 정확하게 이야기 하면 메소드 정의를 포함하고 있는 클래스명만 기록하며 클래스에 포함된 메소드 정의 부분은 다루지 않습니다. 앞장 “클래스와 인스턴스”를 주의깊게 읽어 보셨다면 serialize() 함수가 왜 메소드 정의를 다루지 않는 지를 이해할 수 있을 것입니다. serialize() 함수는 객체를 다루는 함수이지 클래스를 다루는 함수는 아닙니다. 객체에는 메소드가 포함되어 있지 않습니다. 따라서 객체를 직렬화한다고 해도 클래스에 포함되어 있는 메소드 정의 부분을 직렬화한다는 것은 올바르지 않지요. 메소드는 같은 클래스에서 생성된 모든 객체가 공유해야 할 정보이지 특정 객체에만 편입된 정보가 아니기 때문에 특정 객체를 직렬화 한다고 해서 직렬화된 정보에 메소드 정의 정보가 포함될 수 없는 것입니다. 이젠 제가 왜 serialize()/unserialize() 함수를 설명하기 전에 “클래스와 인스턴스”라는 주제를 앞 장에 삽입하여 장황하게 설명했는지 이해하실 것 입니다. 클래스와 인스턴스 개념을 이해하고 있지 못하면 왜 serialize() 함수가 메소드 정의 부분을 포함하여 직렬화 시키지 않았는지를 이해할 수가 없습니다.
예를 들어 아래와 같이 session_register() 함수를 이용하여 객체 변수 $obj를 등록시키겠습니다.
[code php;gutter:true]<?php
// 파일명 : test1.php

class test {
  var $a = “1234ASDF”;
 
  function test() {}
 
  function output() {
    echo($this->a);
  }
}
 
session_register(“obj”);
$obj = new test();
$obj->output();
?>

<p><A href=test2.php>TEST2.PHP</A></p> [/code]

이와 같이 세션 등록을 하면 스크립트가 종료되는 순간에 객체를 serialize() 함수를 이용하여 직렬화한 후 서버의 /tmp 디렉토리에 sess_xxxxxxxxxxx 파일명으로 직렬화된 문자열을 저장하게 되는데 그 내용이 아래와 같습니다.
obj|O:4:”test”:1:{s:1:”a”;s:8:”1234ASDF”;}
여기서 obj는 객체변수명, “test”는 클래스명, “a”는 멤버변수명, “1234ASDF”는 멤버변수값을 나타냅니다. 메소드에 관한 정보는 모두 빠져 있는 것을 볼 수 있습니다. 만약 PHP3에서 serialize() 함수를 이용하여 객체를 직렬화 하였다면 멤버변수는 멤버변수명과 멤버변수값이 모두 정상적으로 기록되지만 메소드는 메소드명만 기록되지 메소드 정의 부분이 기록하지 않습니다. 이것이 PHP4에 와서는 메소드명까지 기록하지 않게 되었습니다. 대신에 클래스명이 기록되지요.
unserialize() 함수
형식 : mixed serialize(string str)
unserialize() 함수는 serialize() 함수를 이용하여 객체로부터 직렬화된 문자열을 다시 객체로 복원시켜 줍니다. serialize() 함수를 설명할 때 언급한 것처럼 직렬화할 때 객체의 메소드의 정보가 기록되지 않기 때문에 unserialize() 함수로 다시 객체화하더라도 우선 멤버변수만 접근할 수 있지 메소드는 접근할 수 없습니다.
[code php;gutter:true]<?php
// 파일명 : test2.php
 
session_register(“obj”);
$obj->output();
?>
 
<p><A href=test1.php>TEST1.PHP</A></p> [/code]
위의 예제에서 5번째줄 $obj->output()는 객체의 메소드를 실행하여야 하는데 객체의 메소드는 복원할 수 없으므로 아래와 같은 에러가 발생합니다.
Fatal error: Call to undefined function: output()
in /서버의 디렉토리/test2.php on line 5
따라서 세션함수에 의해 복원된 객체를 가지고 메소드를 실행하기 위해서는 복원된 페이지 내에서 원래의 클래스의 정의를 아래와 같이 명시적으로 포함시켜야 합니다. 즉, 메소드 정의는 별도로 복원시켜주어야 하는 것이지요.
[code php;gutter:true]<?php
// 파일명 : test2.php
 
class test {
  function output() {
    echo($this->a);
  }
}
session_register(“obj”);
$obj->output();
?>
 
<p><A href=test1.php>TEST1.PHP</A></p> [/code]
PHP4 에서 객체의 serialize() 함수가 멤버변수와 메소드를 모두 지원한다 하더라도 메소드 정의 부분은 포함되지 않으므로 unserialize() 함수로 복원된 객체를 온전히 사용하기 위해서는 메소드 정의를 별도로 포함시켜야 한다는 것에 주의하여야 합니다

http://stackoverflow.com/questions/1180602/what-is-php-serialize-for 에서 참조

I just learned about serialize() and unserialize() functions today and I think it is really cool but I am wondering what are some good uses for this? I know people serialize things to put into a database. Could you give me some example uses where it is helpful?

Also I see serialized code in javascript often, is this the same, like a serialized string in javascript can be unserialized with php unserialize() ?

answer #1

PHP serialize allows you to keep an array or object in a text form. When assigning arrays to things like $_SESSION, it allows PHP to store it in a text file, and then recreate it later. Serialize is used like this for objects and variables. (Just make sure you have declared the class the object uses beforehand)

WordPress on the other hand uses it for a very similar method, by storing the serialized arrays directly in a database. If you keep a database of keys => values, this could be very beneficial because of the flexibility of arrays, you can store anything in the value parameter.

And heres the link (courtesy of first commentor): http://us3.php.net/serialize

answer #2

I often see seralized data store in Database, and I really don’t like this :

  • it’s really hard to work in SQL with that data : how do you write conditions on serialized data ? Even harder : how do you update it ? Do you really write a PHP script that fetches every lines, unserialize those, modifies them, re-serialize, and stores them back in DB ? 🙁
  • the day you will want to migrate your data to another software, it’ll require more work to migrate the data (and be even more work if the new software is not written in PHP, btw)

Still, I admit it is an easy way to store not-well-defined data… and I do sometimes use it for that…

Another use for serialization is to facilitate data exchange between two systems : sending objects through some kind of webservice, for instance, requires them to be serialized in some kind of way.

If the two systems are PHP, you could envisage using serialize/unserialize. But, here too, what if one of the system is not PHP anymore ? Using JSON or SOAP is probably a better choice : a bit harder at first, but probably a more long-term solution, as those formats are known in other languages too.

One thing I use PHP’s serialize function is to store data in cache (like APC’s user’s cache), in a PHP application : you cannot store objects as-is : you have to serialize them. As the cache is used only by one application, it is not necessary to use a format known by many languages ; so, serialize is OK… And, to store data in cache, you should use a really fast serialization function — and serialize is pretty fast ^^

http://www.developer.com/lang/php/article.php/10941_3604111_2/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm  에서 참조

 

PHP 5 OOP: Interfaces Abstract Classes and the Adapter Pattern

PHP 5 made significant improvements on the Object Orientated programming model of PHP 4 bringing it more in line with languages such as Visual Basic .NET and Java. The improved object model in PHP 5 makes developing applications using OOP much easier and gives you the programmer, greater flexibility.

In this series of articles I will demonstrate the new features of the PHP 5 object and show you how to create a database abstraction layer similar to PEAR DB. I will also introduce you to a few design patterns that can be applied to common OOP related problems.

In this article, I introduce you to some of the features of the PHP 5 object model. You will see how to create a database abstraction layer similar to the Pear DB abstraction layer. You’ll also learn how to adapt this abstraction layer for your own uses.

Introduction

One of PHP’s stronger areas is its support for database connectivity. It is able to connect to and talk to just about any database server or interface you can imagine. However, with this comes a few inherent problems; each database system has its own features, functions and in most cases they have their own versions of SQL. Although the functions used to access these databases are similar they do vary subtly meaning that if you were to want to port an application written for MySql to MS SQL server, the refactoring would require manually changing all calls to mysql_query() to mssql_query().

While we are not going to go as far as developing a database independent version of SQL, the new features of PHP 5 will be us build a consistent database API with support for stored procedures (where it is not already present). This will then make switching from one database system to another as painless as changing one line of code.

Interfaces Abstract Classes and the Adapter Pattern

The first features new to PHP 5 to be covered in this article are abstract classes and interfaces. These concepts are nothing more than features added to OOP, which help the programmer follow good coding standards.

Abstract Classes

An abstract class is a class that is only partially implemented by the programmer. It may contain one or more abstract methods. An abstract method is simply a function definition that serves to tell the programmer that the method must be implemented in a child class.

To create an abstract class we use the code shown in Listing 1:

Listing 1: An Abstract PHP class

<?php  







abstract class Weapon  







{  







    private $SerialNumber;  







    abstract public function fire();  























    public function __construct($SerialNumber)  







    {  







        $this->SerialNumber = $SerialNumber;  







    } 































    public function getSerialNumber()  







    {  







        return $this->SerialNumber;  







    }  







}  







?> 















The abstract class in Listing 1 contains someof the methods required for a weapon. The fire() method however, cannot be implemented because each different weapons use different firing different mechanisms. The method is therefore declared as abstract, meaning it will be implemented in a more specific child class.

Because the class is abstract, an instance of it can never be created (remember, it is only a partial implementation). Instead a child class must be created using inheritance and implement the fire method in itself. Failure to do so will result in a fatal error. Listing 2 shows a child class being created from the Abstract Weapon class.

Listing 2: Extending the Abstract Weapons class

<?php  







class Gun extends Weapon  







{  







    public function fire()  







    {  







        if($this->SafetyOff) {  







            return $this->CurrentBullet;  







        }  







    }  







}  























class Cannon extends Weapon  







{  







    public function fire()  







    {  







        $this->NeedsLoading = true;  







        return $this->CurrentCanon;  







    }  







?> 























An instance of the Cannon and Gun classes can now be created because they now fully implemented subclasses of weapon.

Interfaces

An interface is similar to an abstract class; indeed interfaces occupy the same namespace as classes and abstract classes. For that reason, you cannot define an interface with the same name as a class. An interface is a fully abstract class; none of its methods are implemented and instead of a class sub-classing from it, it is said to implementthat interface.

An interface will be used in the database abstraction layer you create. This ensures that every time you create a class for a particular database, the same API is exposed. When using an interface, you can then rely on the methods defined for the interface to be part of the class because, if they are not, PHP will not parse it.

The MySql functions will be used as an example because they are the most commonly used amongst PHP programmers. The most commonly used functions are:

  • mysql_connect()
  • mysql_error()
  • mysql_errno()
  • mysql_query()
  • mysql_fetch_array()
  • mysql_fetch_row()
  • mysql_fetch_assoc()
  • mysql_fetch_object()
  • mysql_num_rows()
  • mysql_close()

If all the database class APIs you create can expose the same methods with the same return types then you can be sure that changing from one database to another, such as from MySql to Postgre SQL, will be painless. As such, the interface in listing 3 can be determined for your API.

Listing 3: An Abstracted Database Interface

interface DB 







{ 







    public function connect(); 







    public function error(); 







    public function errno(); 







    public static function escape_string($string); 







    public function query($query); 







    public function fetch_array($result); 







    public function fetch_row($result); 







    public function fetch_assoc($result); 







    public function fetch_object($result); 







    public function num_rows($result); 







    public function close(); 







} 















Any class implementing the interface must define each method that is declared in the interface, and each method must have at least the parameters identified in their interface definitions. It may have more parameters as long as they are optional, but it cannot have less

PHP 5 OOP: Interfaces Abstract Classes and the Adapter Pattern, Page 2

Look at a class in Listing 4 that implements the database interface. You should recall that I mentioned the adapter pattern earlier. This is an example of the adapter pattern, which is used by programmers in order to adapt one API. The API you are adapting from could be another object-based API or as being done here, an adaptation from a modular API. If you want to read more about the adapter pattern, you can find a more detailed explanation and examples here.

Notice how the escape_string() method is included as a static method. This method does not require an active connection to a database and should not require and instance of any object which implements the DB interface. In my opinion, this is the single most important method of any database implementation; a poorly implemented escape string method could make your applications vulnerable SQL injection.

Listing 4: Implementing the database interface

class MySqlDB implements DB 

    { 

        private  $link; 

         

        public function connect($server='', $username='', $password='', $new_link=true, $client_flags=0) 

        { 

            $this->link = mysql_connect($server, $username, $password, $new_link, $client_flags); 

        } 

     

        public function errno() 

        { 

            return mysql_errno($this->link); 

        } 



        public function error() 

        { 

            return mysql_error($this->link); 

        } 



        public static function escape_string($string) 

        { 

            return mysql_real_escape_string($string); 

        } 



        public function query($query) 

        { 

            return mysql_query($query, $this->link); 

        } 

         

        public function fetch_array($result, $array_type = MYSQL_BOTH) 

        { 

            return mysql_fetch_array($result, $array_type); 

        } 



        public function fetch_row($result) 

        { 

            return mysql_fetch_row($result); 

        } 

         

        public function fetch_assoc($result) 

        { 

            return mysql_fetch_assoc($result); 

        } 

         

        public function fetch_object($result) 

        { 

            return mysql_fetch_object($result); 

        } 

         

        public function num_rows($result) 

        { 

            return mysql_num_rows($result); 

        } 

         

        public function close() 

        { 

            return mysql_close($this->link); 

        } 



You’ll notice that there are many more mysql functions than methods that are adapted in the interface in listing 3. However, this small subset of functions is sufficient to meet the needs of most applications requiring trivial data storageimageand retrieval. The additional functions can be implemented and I have done this in the attached example file, you may also choose to add additional functionality to the class and the interface.

Listing 5: Creating a database class

$db = new MySqlDb; 

    $db->connect('host', 'username', 'password'); 

    $db->query('use users'); // we could also use $db->select_db here but it is not consistent with the interface 



    $result = $db->query("SELECT username FROM users"); 

         

    while($row = $db->fetch_assoc($reuslt)) { 

        echo($row['username']); 

    } 



As shown in listing 5, you can now create a class for each database you want and as long as it implements the DB interface, switching from one to another is as easy as changing one line of code:

$db = new MsSqlDb; 



Conclusion

In this first article, you’ve seen how to create an abstraction layer to access a database. Using this, you saw how creating an interface helps you to isolate your application so that you can easily switch from one database to anther without rewriting your own applications.

Downloads

You can download phpcodefiles.zip here.

About the Author

Adam Delves is a university student and web programmer from the UK who is studying computingimage. He has been a PHP programmer for over 3 years and now runs two small websites and writes articles for PHP builder.com.

http://widwebway.com/en/blog/?p=30 에서 참조

Interface VS Abstract Class in PHP

Interface and class Abstract are concepts of OOP in PHP underused. The reasons behind lack of use for those two concepts are:

  • unclear requirements (or unclear gone by the developer) in the design phase
  • shortage in knowledge

What is an interface?
The clearest definition is that an interface is a contract.
Features:

  • All classes that implement an interface must develop all the methods that have been defined
  • The class implementing the interface must use the exact same method signatures as are defined in the interface. Not doing so will result in a fatal error
  • All methods declared in an interface must be public, this is the nature of an interface
  • A class can implement more than one interface
  • An interface can be used by the Type Hinting

Example:

interface logsInterface

{

 public function log ( $message , $priority = null);

}

What is an abstract class?
It’s a kind “father” that must be inherited to be used. Classes that inherit differ from them only in the abstract methods and can access the methods of the parent class using the keyword parent. Features:

  • can not be instantiated
  • methods can be abstract (not implemented)
  • methods may be not abstract (implemented)
  • a class can inherit from a single abstract class

Example

abstract class logsAbstract

{

 abstract public function logMethod (); 

 public function getVariable ()

 {

  return $this->variable;

 }

}

SUMMARY OF INTERFACE VS ABSTRACT CLASS

Abstract Class Interface For abstract class a method must be declared as abstract. Abstract methods doesn’t have any implementation. For interface all the methods by default are abstract methods only. So one cannot declare variables or concrete methods in interfaces. The Abstract methods can declare with Access modifiers like public, internal, protected. When implementing in subclass these methods must be defined with the same (or a less restricted) visibility. All methods declared in an interface must be public. Abstract class can contain variables and concrete methods. Interfaces cannot contain variables and concrete methods except constants. A class can Inherit only one Abstract class and Multiple inheritance is not possible for Abstract class. A class can implement many interfaces and Multiple interface inheritance is possible. A child class may or may not override a method defined in the parent class A class that implements an interface must override all interface methodsIn principle, if an abstract class contains only abstract methods we’re using it as an interface.

CONCLUSIONS
Abstract classes are used to share functions.
The interfaces are used to share how you have to do something.

http://www.phpk.org/archives/301

에서 참조

같은 클래스 안에 속한 정적 함수를 호출 할 때에는 $this 변수를 사용하지 않고 self 키워드를 사용합니다. 이  self 키워드의 특징은 self 를 실행하는 자기 클래스가 아니라 호출하려는 메소드가 정의된 클래스를 의미합니다.

 1: <?php 
 2: class ParentClass { 
 3: public static function who() { 
 4: echo 'I am Parent Class.'; 
 5: } 
 6: 
 7: public static function whoAreYou() { 
 8: self::who(); 
 9: } 
 10: } 
 11: 
 12: class ChildClass extends ParentClass { 
 13: public static function who() { 
 14: echo ' I am Child Class.'; 
 15: } 
 16: } 
 17: 
 18: ChildClass::whoAreYou(); 
 19: 
 20: ?>

위 코드와 같이 ChildClass 가 ParentClass 를 상속 받았습니다. ChildClass 에 있는 whoAreYour() 함수를 호출하여 who() 함수를 실행했을 때 어떤 문자열이 출력될까요.

결과는 I am Parent Class. 입니다.

정적 함수의 상속 관계를 그림으로 보면 아래와 같습니다.

2009-07-15_135134

Last Static Bindings

PHP 5.3.0 에서 추가된 Late Static Bindings는 static 키워드를 추가하여 정의된 부모 클래스가 아니라 상속을 받은 자기 자신을 지징할 수 있도록 했습니다. 코드를 보면 아래와 같습니다.

 1: <?php 
 2: class ParentClass { 
 3: public static function who() { 
 4: echo 'I am Parent Class.'; 
 5: } 
 6: 
 7: public static function whoAreYou() { 
 8: static::who(); 
 9: } 
 10: } 
 11: 
 12: class ChildClass extends ParentClass { 
 13: public static function who() { 
 14: echo ' I am Child Class.'; 
 15: } 
 16: } 
 17: 
 18: ChildClass::whoAreYou(); 
 19: 
 20: ?>

바뀐 부분을 눈치 채셨나요? ParentClass 의 whoAreYou() 함수 안에서 self::who() 코드가  static::who() 로 바뀌었습니다. 이렇게 static 키워드를 사용하면 상속 받은 자식 클래스에서 자신의 함수를 사용할 수 있습니다. 이 static 키워드를 사용하면 아래 코드처럼 작성할 수도 있습니다.

아래 코드에서는 ParentClass 에 who() 함수가 없습니다. 그럼에도 불구하고 ParentClass 에서 who() 를 호출하고 있습니다. 이런 경우 ChildClass 의 who() 가 호출 될 것이므로 ParentClass 에 who() 함수가 정의되어 있지 않아도 됩니다.

 1: <?php 
 2: class ParentClass { 
 3: 
 4: public static function whoAreYou() { 
 5: static::who(); 
 6: } 
 7: } 
 8: 
 9: class ChildClass extends ParentClass { 
 10: public static function who() { 
 11: echo ' I am Child Class.'; 
 12: } 
 13: } 
 14: 
 15: ChildClass::whoAreYou(); 
 16: 
 17: ?>

http://www.phpk.org/archives/301

에서 참조

같은 클래스 안에 속한 정적 함수를 호출 할 때에는 $this 변수를 사용하지 않고 self 키워드를 사용합니다. 이  self 키워드의 특징은 self 를 실행하는 자기 클래스가 아니라 호출하려는 메소드가 정의된 클래스를 의미합니다.

 1: <?php 
 2: class ParentClass { 
 3: public static function who() { 
 4: echo 'I am Parent Class.'; 
 5: } 
 6: 
 7: public static function whoAreYou() { 
 8: self::who(); 
 9: } 
 10: } 
 11: 
 12: class ChildClass extends ParentClass { 
 13: public static function who() { 
 14: echo ' I am Child Class.'; 
 15: } 
 16: } 
 17: 
 18: ChildClass::whoAreYou(); 
 19: 
 20: ?>

위 코드와 같이 ChildClass 가 ParentClass 를 상속 받았습니다. ChildClass 에 있는 whoAreYour() 함수를 호출하여 who() 함수를 실행했을 때 어떤 문자열이 출력될까요.

결과는 I am Parent Class. 입니다.

정적 함수의 상속 관계를 그림으로 보면 아래와 같습니다.

2009-07-15_135134

Last Static Bindings

PHP 5.3.0 에서 추가된 Late Static Bindings는 static 키워드를 추가하여 정의된 부모 클래스가 아니라 상속을 받은 자기 자신을 지징할 수 있도록 했습니다. 코드를 보면 아래와 같습니다.

 1: <?php 
 2: class ParentClass { 
 3: public static function who() { 
 4: echo 'I am Parent Class.'; 
 5: } 
 6: 
 7: public static function whoAreYou() { 
 8: static::who(); 
 9: } 
 10: } 
 11: 
 12: class ChildClass extends ParentClass { 
 13: public static function who() { 
 14: echo ' I am Child Class.'; 
 15: } 
 16: } 
 17: 
 18: ChildClass::whoAreYou(); 
 19: 
 20: ?>

바뀐 부분을 눈치 채셨나요? ParentClass 의 whoAreYou() 함수 안에서 self::who() 코드가  static::who() 로 바뀌었습니다. 이렇게 static 키워드를 사용하면 상속 받은 자식 클래스에서 자신의 함수를 사용할 수 있습니다. 이 static 키워드를 사용하면 아래 코드처럼 작성할 수도 있습니다.

아래 코드에서는 ParentClass 에 who() 함수가 없습니다. 그럼에도 불구하고 ParentClass 에서 who() 를 호출하고 있습니다. 이런 경우 ChildClass 의 who() 가 호출 될 것이므로 ParentClass 에 who() 함수가 정의되어 있지 않아도 됩니다.

 1: <?php 
 2: class ParentClass { 
 3: 
 4: public static function whoAreYou() { 
 5: static::who(); 
 6: } 
 7: } 
 8: 
 9: class ChildClass extends ParentClass { 
 10: public static function who() { 
 11: echo ' I am Child Class.'; 
 12: } 
 13: } 
 14: 
 15: ChildClass::whoAreYou(); 
 16: 
 17: ?>