PHP

include와 namespace

프로그램은 작고 단순한 것에서 크고 복잡한 것으로 진화한다. 그 과정에서 코드의 재활용성을 높이고, 유지보수를 쉽게 할 수 있는 다양한 기법들이 사용된다. 그 중의 하나가 코드를 여러개의 파일로 분리하는 것이다. 이를 통해서 얻을 수 있는 효과는 아래와 같다.

  • 자주 사용되는 코드를 별도의 파일로 만들어서 필요할 때마다 재활용할 수 있다.
  • 코드를 개선하면 이를 사용하고 있는 모든 애플리케이션의 동작이 개선된다.
  • 코드 수정 시에 필요한 로직을 빠르게 찾을 수 있다.
  • 필요한 로직만을 로드해서 메모리의 낭비를 줄일 수 있다.

include란?

PHP에서는 필요에 따라서 다른 PHP 파일을 코드 안으로 불러와서 사용할 수 있다. 그 방법에 대해서 알아보자.

include가 없다면

우선 include가 없는 애플리케이션을 하나 만들어보자. 이 코드의 파일명은 1.php 다.

<?php
function welcome(){
    return 'Hello world';
}
echo welcome();
?>

위의 코드는 아무런 문제가 없다. 하지만 welcome 함수가 자주 사용되는 것이라고 가정해보자. 이런 경우 이것이 필요할 때마다 이 함수를 정의해서 사용하는 것은 유지보수도 어렵고 낭비가 될 것이다. 이럴 때 include가 필요하다. 함수 welcome을 include해보자.

include의 사용

새로운 파일을 만든다. 이름은 greeting.php다.

greeting.php

<?php
function welcome(){
    return 'Hello world';
}
?>

새로운 파일을 만들고 아래와 같이 greeting.php를 인클루드한다.

2.php

<?php
include 'greeting.php';
echo welcome();
?>

이전 예제와 비교했을 때 결과는 같다. 하지만 함수 welcome을 외부 파일로 분리했다. 다음은 위의 코드에 대한 분석이다.

include 'greeting.php';

include는 외부의 php 파일을 로드할 때 사용하는 명령이다.

PHP는 외부의 php 파일을 로드하는 방법으로 4가지 형식을 제공한다. 형식의 종류는 아래와 같다.

  • include
  • include_once
  • require
  • require_once

include와 require의 차이점은 존재하지 않는 파일의 로드를 시도했을 때 include가 warning를 일으킨다면 require는 fatal error를 일으킨다는 점이다. fatal error는 warning 보다 심각한 에러이기 때문에 require가 include 보다 엄격한 로드 방법이라고 할 수 있다.

_once라는 접미사가 붙은 것은 파일을 로드 할 때 단 한번만 로드하면 된다는 의미다.

네임스페이스

네임스페이스가 무엇인가를 정의하기에 앞서서 파일을 생각해보자. 파일은 데이터를 보관하고 있는 일종의 컨테이너다. 그리고 이 컨테이너는 파일명으로 식별이 된다. 파일의 수가 많아지면서 파일을 관리하는 것이 점점 어려워진다. 그래서 고안된 것이 바로 디렉토리다. 디렉토리를 이용하면 같은 이름의 파일이 하나의 컴퓨터에 존재할 수 있다. 파일명의 충돌을 회피 할 수 있게 된 것이다. 네임스페이스란 간단하게 디렉토리와 같은 것이라고 생각하자. 하나의 에플리케이션에는 다양한 모듈을 사용하게 된다. 그런데 모듈이 서로 다른 개발자에 의해서 만들어지기 때문에 같은 이름을 쓰는 경우가 생길 수 있다. 이런 경우 먼저 로드된 모듈은 나중에 로드된 모듈에 의해서 덮어쓰기 되기 때문에 이에 대한 대책이 필요하다. 네임스페이스가 필요해지게 되는 것이다. 

만약 환영인사를 언어별로 다르게 하고 싶다면 어떻게 해야 할까? 3개의 파일을 만든다.

greeting_en.php

<?php
function welcome(){
    return 'Hello world';
}
 위의 코드에는 PHP 구문의 종료를 의미하는 닫히는 기호가 없다. 닫히는 기호는 생략이 가능하다.

greeting_ko.php

<?php
function welcome(){
    return '안녕세계';
}

5.php

<?php
require_once 'greeting_ko.php';
require_once 'greeting_en.php';
echo welcome();
echo welcome();
?>

위의 코드는 아래와 같은 에러를 발생시킨다.

Fatal error: Cannot redeclare welcome() (previously declared in D:\BitNami\wampstack-5.4.12-0\apache2\htdocs\include\greeting_ko.php:3) in D:\BitNami\wampstack-5.4.12-0\apache2\htdocs\include\greeting_en.php on line 4

로드한 두개의 파일 모두 welcome라는 함수를 선언했기 때문이다. PHP에서는 함수의 중복 선언을 허용하지 않는다. 이런 경우 네임스페이스를 사용할 수 있다. 아래와 같이 로드되는 파일의 내용을 수정해보자.

greeting_en_ns.php

<?php
namespace language\en;
function welcome(){
    return 'Hello world';
}

greeting_ko_ns.php

<?php
namespace language\ko;
function welcome(){
    return '안녕하세요';
}

6.php

<?php
require_once 'greeting_ko_ns.php';
require_once 'greeting_en_ns.php';
echo language\ko\welcome();
echo language\en\welcome();
?>

로드되는 파일의 초입에 키워드 namespace를 이용해서 네임스페이스를 만들었다. 그리고 네임스페이스를 사용할 때는 함수 앞에 네임스페이스의 이름을 붙여서 사용하면 된다. 이로서 동일한 이름의 함수를 하나의 php 에플리케이션 안에서 사용할 수 있게 되었다.

하나의 파일에는 복수의 네임스페이스가 존재 할 수도 있다.

greeting_lang.php

<?php
namespace language\en;
function welcome(){
    return 'Hello world';
}
namespace language\ko;
function welcome(){
	return '안녕세계';
}
<?php
require_once 'greeting_lang.php';
echo language\ko\welcome();
echo language\en\welcome();
?>

네임스페이스는 함수 뿐만 아니라 클래스와 상수에 대해서도 사용할 수 있다. 네임스페이스에 대한 자세한 내용은 아래의 자료들을 참고하자.

댓글

댓글 본문
작성자
비밀번호
  1. 말봉
    include 'include.php';
    include 'include.php';
    print welcome();

    이렇게 하면 Fatal error: Cannot redeclare welcome() (previously declared in 오류나용 - 0-
  2. HongJu Shin
    선생님 질문있습니다.
    php 에서 문자열을 나타낼 때 ' ' 또는 " " 를 사용하는 것으로 알고 있는데, include, require 쓸 때 왜 파일을 ' '으로 묶는 건가요? 그리고 이것이 어떻게 작동하는지 궁금합니다.
  3. hotshot
    매 과정이 배움의 연속입니다.
  4. jjung
    네임스페이스 라는게 있었군요!
  5. 다시시작
    완료
  6. 고스트프리
    네임스페이스 신기하네요... 감사합니다.
  7. kimjs9105
    include는 다른 언어에도 사용해 보아서 익숙했는데 네임스페이스는 신기한 개념이네요! 링크따라서 한번 더 공부해봐야겠어요~ 감사합니다~^^
  8. spiritord
    감사합니다
  9. sheis
    잘 봤어요^^
  10. 심화평
    2017.07..17 감사합니다
  11. ttt2rrxx
    include 강의 8분 38초에서 설명하시는 데로 하면 include 중복오류가 나는거 아닌가요 ....?
  12. treehouse
    호우
  13. HGERRARD
    egoing님 강의는 이해가 잘 됩니다 !!
  14. 김세창
    잘보고갑니다~^^ ㅎ
  15. Scott Kim
    PHP Version 5.3부터 네임스페이스가 지원될 것입니다.
    apmsetup은 PHP Version 5.2일거에요
    대화보기
    • php가첫취업?
      프로그램 사용하는게 뭐냐에 따라 구동이 잘되고 안되고의 차이가 있네요;;;
      전 참고로apmsetup으로 구동하고 있는데;;;네임스페이스 구동이 잘 안되네요 ㅠㅠ
    • Frank
      고맙습니다~
    • jeong
      Fatal error: Call to undefined function language\en\language\kr\welcome() in C:\
      오류메세지인데요.
      language\en\language\kr\welcome()
      이걸보시면 지금 네임스페이스가 language\en\language\kr 이렇게 설정되있는 걸 보실수 있죠.
      네임스페이스를 language로 바꾸어주시고
      echo language\kr\welcome();
      echo language\en\welcome();

      이부분을

      echo kr\welcome();
      echo en\welcome();

      이렇게 바꾸어 주시면 되어요.

      <?php

      namespace language\kr;
      function welcome() {
      return '안녕 세계';
      }
      namespace language\en;
      function welcome() {
      return 'Hello world';
      }

      namespace language;

      echo kr\welcome();
      echo en\welcome();
      ?>
      대화보기
      • park
        하나의 파일 아래에 여러가지 네임스페이스를 만드려면 namespace를 선언한 바로 밑줄에 함수를 선언해야
        하는 것이겠네요 잘봤습니다
      • NamJin Kim
        감사합니다
      • 신입1
        첫번째 영상에서 welcome 함수에 echo가 없어서 출력은 안되지 않나요?
        호출할때마다 hello world가 출력된다고 설명하셔서 글남겨용
      • enqn1992
        글에 첨부된 링크 중 한글버전 링크를 보니 이런글이 있네요
        '... 함수를 호출할 때에는 네임스페이스 맨 앞에 \ 를 붙여야 합니다.'
        글 내용을 보니 네임스페이스를 지정할 땐 맨 앞에 \가 없지만, 함수를 호출할 때는 \를 최상위 디렉터리로 생각하여 네임스페이스 경로 맨 앞에 꼭 붙여야 한다고 하네요

        덕분에 공부하고 갑니다~

        +방금 해보니 저는 함수 호출 시 경로 맨 앞에 \가 없어도 잘 되네요 음?
        대화보기
        • Sajuk
          아래와 같은 내용이 한 파일 안에서 다 실행하면 "Call to undefined function" 이라는 Fatal 에러가 뜹니다.
          이유가 무엇일까요??
          <?php

          namespace language\kr;
          function welcome() {
          return '안녕 세계';
          }
          namespace language\en;
          function welcome() {
          return 'Hello world';
          }
          echo language\kr\welcome();
          echo language\en\welcome();
          ?>
        • pakellie
          마지막 강의에서 소스 실행시키는데 잘 안됩니다..
          해결하신분 잇으신가요?
        • 오덕소희
          echo language\ko\welcome();
          echo language\en\welcome();
          이렇게 입력하면 함수를 못찾네요!!

          echo \language\en\welcome()
          echo \language\ko\welcome();

          이렇게했더니 됬습니다.
          대화보기
          • JustStudy
            고맙습니다
          • SK Kim
            x 내용으로 echo "test"; 라고 하면
            include x; #1
            include_once x; #2
            include x; #3
            include x; #4
            의 경우 x를 3번(1 3 4) 불러드리네요.
            include_once는 동일한게 이미 include된 상태이면 include하지 않는다로 생각하는데 맞을거 같습니다.
          • LILIS
            네임스페이스가 이런거였군요..!
            잘 배워갑니다~
          • iam777
            감사합니다. 정말 잘 이해가 되고 있습니다.
          • silverwing
            php 5.3버전 이후에서만 사용가능한것 같습니다.
            대화보기
            • ㅁㅅㅈ
              <?php
              require_once 'test1.php';
              require_once 'test2.php';
              echo language\ko\welcome();
              echo language\en\welcome();
              ?>
              강의에 나온대로 이렇게 코딩하면
              Warning: Unexpected character in input: '\' (ASCII=92) state=1 in C:\APM_Setup\htdocs\test\test3.php on line 4
              Parse error: syntax error, unexpected T_STRING, expecting ',' or ';' in C:\APM_Setup\htdocs\test\test3.php on line 4
              이렇게 나오는데 아무래도 echo 뒤에 \가 들어있는 스트링이 오면 안되는 듯하네요....
              에코 뒤에 있는 부분을 따옴표 안에 넣으면
              Parse error: syntax error, unexpected T_STRING in C:\APM_Setup\htdocs\test\test1.php on line 2
              이렇게 상속된 그 전의 파일에서 namespace를 정의하는 부분의 스트링이 걸리는군요...

              그냥 제가 사용하는 버전이 지원을 안하는건가요?
            • omaly
              namespace 지정전에 다른 코드를 삽입하면 에러가 발생합니다. 문서포팻이나 개발환경, 웹서버환경에 따라 차이가 있긴 하지만 php구문 이전에 공백을 허용하지 않는 경우도 있습니다(UTF-8 인코딩에서의 Bytes Order Mark문제). 다음과 같은 경우 에러가 일어납니다.

              (1) error
              <?php
              header("Content-Type:text/html; charset=utf-8");
              namespace language\ko;
              function sayHello() {
              return "내가 고자라니...";
              }
              ?>

              (2) error
              <html>
              <body>
              <?php
              namespace language\ko;
              function sayHello() {
              }
              ?>
              </body>
              </html>

              (3) error
              -----공백-------
              <?php
              namespace language\ko;
              function sayHello() {
              }
              ?>



              # php구문안에 주석이나 공백은 허용됩니다.

              (4) not error
              <?php
              공백
              namespace language\ko;
              ?>

              (5) not error
              <?php
              # comment
              namespace language\ko;



              # 한글을 출력코자 한다면 호스트 파일에 적용하면 됩니다.

              main.php
              <?
              header("Content-Type:text/html; charset=utf-8");

              include_once "language_ko.php";
              print language\ko\sayHello();
              ?>
              대화보기
              • 2015-11-16
                저녁 6시가 넘어가면 버퍼링때문에 동영상 강좌를 보기가 힘드네요....
              • 코딩!
                만에 하나 중복된 함수의 이름이 있을경우엔 namespace를 써서 에러를 방지하는군요!
              • 천국나무
                php5.x 이상부터 되는것으로 알고있습니다.
                낮은 버전 에서는 지원 안될겁니다.^^
                대화보기
                • 이용주
                  일부 php 버전에서는 안되는거 같아요 제가 웹 호스팅을 3개쓰는데 그중에 1곳만 되네요. php 버전차이가 있나 봅니다,. ^^;;
                • 어떤 프로그램을 어떻게 업그래이드 하셨는지 궁금합니다.
                  대화보기
                  • 나은성
                    네임스페이스의 개념을 설명해주셨는데 보충이 필요할거 같습니다.


                    저도 막 배우는 단계지만
                    네임스페이스를 실제로 이런식으로 쓰이는 경우는 거의 없고 대부분 Use 키워드를 사용하는데
                    그부분의 언급이 없는것은 아쉬운 부분입니다.
                  • o그림자o
                    궁금해서 그러는데요... namespace 뒤에 language\en; 디렉토리처럼 쓴다고 했는데..
                    language\en의 디렉토리 명은 임의로 정하는 건가요?
                  • egoing
                    고맙습니다!
                    대화보기
                    • 오정민
                      사소한 오타 보고 드립니다.^^;;

                      네임스페이스 동영상 아래 2번째 라인의
                      "그리고 이 컨텐이너는 파일명으로 식별이 된다."
                      : "컨텐이너는" => "컨테이너는"


                      좋은 강의 잘 보고 있습니다. 항상 감사 드립니다^^
                    • 비기너
                      <meta charset="utf-8" />

                      이 구문은 한글이 깨지는 것을 잡아주는 구문입니다.
                      해당 에러 메시지와는 상관없는 구문이죠.
                      대화보기
                      • 강윤호
                        <meta charset="utf-8" />
                        <?php

                        ?>

                        저걸 추가해도
                        Fatal error: Namespace declaration statement has to be the very first statement in the script in C
                        이러한 에러가 또 뜨는데 이런경우엔 어떻게 해야하나요??
                        php버전도 확인해보았지만 5.4였습니다..
                      • rustypassion
                        아고.. 감기 조심하셔요.
                        아프신것 같은데도 강의를 제작해주셨네요.
                        감사합니다.

                        더 열심히 공부해야 하겠습니다.
                      • 요섭아빠
                        감사합니다. 좋은 강의 잘 듣고있습니다.
                      • Allen Cho
                        <meta charset="utf-8" />
                        <?php

                        ?>

                        형식으로 작성해 보세요.
                        대화보기
                        • zyavermi
                          깨지는 건 인코딩 때문이 아닐까요?
                          대화보기
                          • Sozzi
                            namespace language\ko 에서 리턴해주는 값은 꺠지는데 어떻게 된거죠?
                          • 샤핀
                            항상 좋은 강의 감사합니다. ^^.
                          • 샤핀
                            include 강좌 코드 설명에서 include_once 설명하실 때 좀 이상해서 질문드릴께요.
                            include 강좌 (07:43부분)

                            greeting.php의
                            <?php
                            function welcome(){
                            return 'Hello world';
                            }

                            welcome();
                            ?>
                            와 같은 상황 일 때, welcome 함수 정의 부에 echo 'hello world'라고 정의 되어 있지 않기 때문에... 그러니까 return 'hello world'라고만 되어 있기 때문에... welcome();와 같이 되어 있더라도 출력은 되지 않는다고 해야 하지 않을까요..

                            만약에 설명하시려던 것처럼 출력을 하게 하려면,
                            welcome(); 가 아니라
                            echo welcome(); 로 설명을 하셔야 할 거 같습니다. 헷갈려서요 ^^;;
                          버전 관리
                          egoing
                          현재 버전
                          선택 버전
                          graphittie 자세히 보기