php 입문 | 구조와 객체 지향 | 클래스를 만들어 보자!


그러면 실제로 클래스를 만들고, 그것을 이용하여 보자. 이전에 “텍스트 속에서 PHP라는 텍스트만 표시를 변경"하는 예제를 더 수정하고, 좀 더 범용적인 클래스를 만들어 그것을 이용하기로 해보자.

아래와 같이 예제 코드를 작성한다.

<?php
class TextModify {
    private $header = "<b>";
    private $footer = "</b>";
    private $body = "";
    private $find = "PHP";
     
    public function __construct($h,$f){
        $this->setHeader($h);
        $this->setFooter($f);
    }
     
    function setHeader($s){
        $this->header = $s;
    }
     
    function setFooter($s){
        $this->footer = $s;
    }
     
    function setBody($s){
        $this->body = htmlspecialchars(strtoupper($s));
    }
    function setFind($s){
        $this->find = $s;
    }
     
    function getRenderText(){
        $res = str_replace($this->find, $this->header . $this->find . $this->footer, $this->body);
        return $res;
    }
     
    function writeRenderText(){
        echo $this->getRenderText();
    }
}
 
// 인스턴스 준비
$title_obj = new TextModify('<span style="color:red;">', '</span>');
$title_obj->setFind("PHP");
$title_obj->setBody('Hello PHP!');
$msg_obj = new TextModify('<span style="color:blue;">', '</span>');
$msg_obj->setBody('여기에 PHP라는 문자를 포함한 문장을 써주세요.');
$rep_obj =  new TextModify("<b>","</b>");
if ($_POST != null){
    $str = $_POST['text1'];
    $rep_obj->setBody($str);
}
?>
<!DOCTYPE html>
<html lang="ko">
    <head> 
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
        <title>sample page</title>
    </head>
    <body>
        <h1><?php $title_obj->writeRenderText(); ?></h1>
        <p><?php $msg_obj->writeRenderText(); ?></p>
        <hr>
        <p><?php $rep_obj->writeRenderText(); ?></p>
        <form method="post" action="./index.php">
            <textarea name="text1" cols="40" rows="5"><?php echo $str; ?></textarea>
            <br><input type="submit">
        </form>
        <hr>
    </body>
</html>

여기에서는 “TextModify"라는 클래스를 만들고 이를 이용하여 헤더용, 메시지용, 그리고 텍스트의 대체용의 인스턴스를 준비하고 각각의 기능을 호출하여 표시를 작성한다.

만든 TextModify 클래스를 보면 새롭게 등장한 것이 몇개가 등장하고 있다. 그들을 보충 설명하여 보겠다.

1. 접근자 키워드(access keywords)

여기에서는 $header, $footer, $body, $find라는 4개의 필드를 제공하고 있다. 각각 대체 텍스트 헤더(전에 붙이는 텍스트), 풋터(뒤에 붙이는 텍스트), 바디(대상이 되는 텍스트 본체), 그리고 검색 문자를 저장하는 용도이다.

이 필드들을 보면, 앞에 “private"이라는 것이 붙어 있다. 이것은 이 필드를 어디까지 사용할 수 있는가 하는 이용 범위를 지정하는 것으로, “접근자 키워드"라는 것이다. 여기에는 다음과 같은 것이 준비되어 있다.

  • private : 해당 클래스 중에서만 사용할 수 있다. 외부에서는 절대 사용할 수 없다.
  • protected : 해당 클래스 및 그 서브 클래스에서 사용할 수 있다.
  • public : 클래스 밖에서도 사용할 수 있다.

이 중에 “서브 클래스"라는 것은 객체 지향의 “상속"이라는 기능을 이용한 것이다. 이것에 대해서는 나중에 다시 설명하겠다. 우선 여기에서는 “private으로 하면 클래스 안에서만 사용할 수 있고, public으로 하면 외부에서도 자유롭게 사용할 수 있다"라고만 기억해 두도록 하자.

이러한 필드는 객체의 성질 등을 나타내는 값이 저장되어 있기 때문에, 외부에서 마음대로 변경해 버리면 안된다. 그래서 필드 자체는 private으로 두고, 변경용 메소드를 별도로 준비하여 외부에서 그 메소드를 호출하여 값을 조작할 수 있도록 하는 것이 일반적이다.

2. 생성자 (construct)

여기에서는 __construct라는 특이한 이름의 public(즉, 외부에서 자유롭게 사용할 수 있는) 메소드가 작성되어 있다. 이 메소드는 “생성자"라고 하는 것이다. 이는 new로 인스턴스를 생성할 때, 자동으로 호출되는 메소드에서 인스턴스의 초기화 처리 등을 실행하며, 필요 없으면 생략해도 된다.

이 생성자에는 2개의 인수를 준비하고 있기에 new 할 때도 2개의 인수를 넣게 된다. 실제로 new하고 있는 부분을 보면,

$rep_obj =  new TextModify("<b>", "</b>");

이런 상태에 헤더와 풋터를 인수로 지정해 new한다.

3. 접근 메소드 (access method)

클래스에서 제공되는 메소드 중에는 필드를 조작하는 것이 몇 가지가 준비되어 있다. setHeader, setFooter, setBody, setFind가 있다.

앞서 언급한 바와 같이, 필드는 private으로 해두고, 그 값을 얻거나 변경하는 메소드를 별도로 준비해 두는 것이 일반적이다. 이러한 방법을 ‘접근자’라고 한다.

접근자는 일반적으로 “get필드명”, “set필드명"라는 이름으로 선언한다. 이는 그렇지 않으면 안되는 것은 아니지만, 이러한 규칙에 따라 이름을 붙이는 편이 알기 쉽게 된다.

4. $this 대해

메소드는 “자기 자신"에 대해 작업을 수행하는 경우가 많다. 일반적으로 클래스는 인스턴스를 만들어 사용하지만, 이 “지금 사용하고 있는 이 인스턴스 자신안에 있는 필드나 메소드"를 이용하는 경우 어떻게 해야할까?

이러한 경우에 사용되는 것이 “$this"라는 변수이다. 이것은 “이 인스턴스 자신"을 나타내는 변수이다. 이를 이용하여 자기 자신의 기능을 호출 할 수 있다.

 

우선, 이러한 내용을 생각하면 코드를 보도록 해보자. 어떤 식으로 클래스와 인스턴스가 동작하고 있는지 알게 될 것이다.