php 입문 | 구조와 객체 지향 | 함수로 구조화하기


프로그래밍 수준이라는 것은 무엇으로 결정할까? 이는 사실은 ‘분량’이라고 말할 수 있다. 전부해서 100 라인 정도의 프로그램이라면 아마추어도 작성할 수 있지만, 1000 라인의 프로그램은 초보자는 작성할 수가 없다. 1만 라인의 프로그램은 프로가 아니면 어렵다. 이는 사용하는 함수가 어렵거나 알고리즘이 복잡하거나 하는 것은 이전의 문제이다. 즉, “얼마나 큰 프로그램을 깔끔하게 정리해서 파악할 수 있도록 설계할 수 있는가"라는 문제이다.

100 라인 프로그램은 단지 줄줄이 쓰는 것만으로도 만들 수 있다. PHP으로 여러 폼을 송신하거나 하는 것만으로도 순식간에 작성할 수 있을 것이지만, 1000 라인 프로그램은 그런 식으로는 만들 수 없다. 프로그램을 그 역할에 띠라 정리하고 필요에 따라 필요한 처리를 호출하는 구조를 제대로 생각해서 설계해야 한다. 이것이 “구조화"라는 개념이다.

PHP에서 구조화의 첫 걸음은 “함수"이다. 그냥 줄줄이 쓰고 있었던 스크립트를 정리하고 부분 부분을 분리하여 “함수"로 정의해 나가는 것으로, 전체적으로 깨끗하게 알기 쉽게 설계하는 것이 더 큰 프로그램을 쓸 수 있게 되는 첫 걸음이라고 할 수 있다.

함수라고 하면, 지금까지 echo 라든지 implode/explode이나 fopen/fclose 이라든지, 여러 가지가 등장 했었다. PHP에서는 기본적인 기능은 모두 함수로 정의되어 있다. 이 함수라는 것은 이렇듯 ‘PHP 본체에 준비되어 있는 것’만 아니다. 개발자가 직접 스크립트를 작성하여 정의할 수도 있는 것이다. 이 함수는 다음과 같이 정의한다.

function 함수명(가인수1, 가인수2, ...) {
    ...... 여기에 수행할 처리을 쓴다 ......
    ...... 결과를 반환한다면, 마지막에 return한다 ......
}

함수를 만들 때, 생각해야 할 것은 “인수"와 “반환 값"이다. 인수라는 것은 함수를 호출할 때 전달되는 값이다. 예를 들면, fopen( "data.txt");와 같은 식으로 함수를 호출 할 때는 ()에 필요한 값을 넣어 지금까지도 호출했던 것이다. 이것이 인수이다.

자신의 함수를 정의할 때도 그 함수로 어떤 값이 필요할 것인가를 생각하고 그것을 인수로 지정한다. 이것은 함수의 () 내에 전달되는 값을 담을 변수를 기술해야 한다. 이것이 “가인수"라는 것이다. 함수를 호출하면 인수에 지정된 값이 이 가인수의 변수에 할당된다. 그리고 이후는 이 변수를 사용하여 전달된 인수의 값을 사용할 수 있다는 것이다.

반환 값은 그 함수를 호출 측에 결과 값을 반환하는 것이다. 이것은 반환하기 원하는 값을 “return 값;“와 같은 형식으로 작성한다. 이 return은 함수를 빠져나가서, 지정된 값을 호출한 측에 돌려준다. 이는 처리를 벗어나는 것이기 때문에, return 후에 처리가 있어도 그것은 실행되지 않는다.

그럼 함수를 실제로 사용해 보자. 우선, 함수를 이용하기 전에 소스 코드를 적어 보겠다.

<?php
    if ($_POST != null) {
        $str = $_POST['text1'];
        $str = htmlspecialchars(strtoupper($str));
         
        $result = str_replace('PHP', '<b>PHP</b>', $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>Hello PHP!</h1>
        <p><?php echo $result; ?></p>
        <hr>
        <p>여기에 PHP라는 문자를 포함한 문장을 써주세요.</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>

여기에는 텍스트를 써서 보내면, “PHP"라는 텍스트를 모두 볼드(bold)로 표시한다. 전송된 텍스트를 str_replace 함수로 치환하는 간단한 예제이다. 또한 여기에서 보내 온 텍스트를 “strtoupper"라는 함수로 처리하고 있다. 이는 알파벳을 대문자로 텍스트를 변환하여 반환하는 함수이다.

함수의 장점

그럼 먼저 예제를 함수로 구조화(라고 할만큼 과장하지 않지만 …)하여 작성해 보겠다. 아래에 소스 코드가 작성된 코드이다.

<?php
    function getBoldStr($str) {
        $str = htmlspecialchars(strtoupper($str));
        $res = str_replace('PHP',  '<span style="font-weight:bold;color:red">PHP</span>', $str);
        return $res;
    }
 
    if ($_POST != null) {
        $str = $_POST['text1'];
    }
?>
<!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 echo getBoldStr("Hello PHP!"); ?></h1>
        <p><?php echo getBoldStr($str); ?></p>
        <hr>
        <p><?php echo getBoldStr("여기에 PHP라는 문자를 포함한 문장을 써주세요."); ?></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>

이번에는 더욱 변환되는 곳을 알 수 있도록 볼드(bold) 및 빨간색으로 PHP를 표시해 보았다. 차이점을 살펴 보자.

여기에서는 최초에 function getBoldStr($str)라는 함수를 정의하고 있다. 인수는 $str는 가인수를 하나 준비했다. 이 $str의 텍스트를 치환하고 완성된 것을 return으로 반환한다. 호출하는 곳을 보면,

<?php echo getBoldStr($str); ?>

이런 식으로 작성되어 있다. getBoldStr 후에 필요한 값을 ()로 전달한다. 평범한 PHP에서 제공되는 함수와 사용법이 전혀 다르지 않다는 것을 알 수 있다.

이와 같이 함수화하는 것으로 이 처리는 프로그램의 어디서나 호출 할 수 있게 되었다. 여기에서는 전송된 텍스트 표시뿐만 아니라, 제목과 설명 텍스트 등도 모두 이 함수에서 처리하여 출력시키고 있다. 함수화를 하였기에 동일한 처리를 여러 번 쓸 필요가 없게 되었다. 언제든지 필요할 때 호출하면 필요한 작업을 수행하는 것이다. 이것이 함수화를 했을 때의 장점이다.

변수의 사용 범위 (scope)

이 스크립트를 잘 보면, 변수에 대해 좀 재미있는 것을 알게 될 것이다. 함수의 가인수에도, 그것 이외의 곳에서도, $str이라는 변수가 사용되고 있다. 같은 변수를 이렇게 사용하더라도 도중에 값이 쓰여져 변경되거나 하는 걱정은 없는 것인가? 사실은 함수에서 $str와 외부 $str는 다른 변수이다.

변수에는 그것을 사용할 수 있는 범위라는 것이 정해져 있다. 이는 “스코프(scope)“라고 한다. 함수의 안에서 변수를 사용하는 경우, 그 변수는 함수 내에서만 사용할 있도록 되어 있다. 그 함수에서 빠져나온 시점에서 그 변수는 소멸하는 것이다. 또한 다시 그 함수를 호출해도, 전에 호출 했을 때의 변수는 깨끗하게 없어져 있으며, 모든 새로 만들어 진다.

따라서 함수의 내부에서 만들어진 내부에서만 사용되는 변수를 “로컬(local) 변수"라고 한다. 이에 대해 함수 외부에서 만들어진 스크립트 전체에서 사용할 수 있게하는 변수를 “전역(global) 변수"라고 한다. 함수를 이용하는 경우에는 이 “변수의 범위(scope)“라는 것에 대해 잘 이해하고 있어야 한다.