본문 바로가기
PHP/생활코딩

5/31(5) 생활코딩

by SKim입니다 2020. 5. 31.

* 오늘의 진도

 PHP

  클래스 로딩과 네임스페이스 (namespace)

 

33. 클래스 로딩과 네임스페이스 (namespace)

클래스 로딩 - 다른 파일에 있는 클래스를 로딩하는 방법

네임스페이스 = 패키지 - 클래스들을 그룹핑하는 수단 (분류의 끝판왕)

 

 

우리 수업의 목표는 Hi와 안녕을 출력하는 클래스를 만드는 것이다.

 

그리고 최종적으로는 en이라는 디렉토리에 Hi라는 클래스가 있고

ko라는 디렉토리에도 Hi라는 똑같은 이름을 갖고 있는 클래스가 있을 때

 

같은 이름을 가진 클래스가 어떻게 하나의 파일 안에 공존할 수 있는 지 살펴볼 것이다

 

 

.

 

 

 

new Hi만 해도 hi가 출력될 것이다.

∵ 생성자(constructor)안에 hi가 있기 때문

 

 

우리는 클래스와 그 클래스를 사용하는 코드가 같은 파일에 있는 것은 배웠지만,

이 두 개가 서로 다른 파일에 담겨 있는 것은 배우지 않았다.

 

클래스가 많아짐에 따라서 클래스는 다른 파일로 쪼갤 필요가 생긴다.

 

main.php 파일을 새로 만들었다.

 

 

require_once는 한 번만 로딩한다는 뜻이다.

만약 이후에도 로딩을 시도하면 php가 다시 로딩하지 않는다. (효율적)

 

 

이 뒤에서는 이런 저런 테크닉들을 배울 것인데,

기하급수적으로 어려워질 것이다.

 

어려우면 그냥 require_once를 사용하면 된다.

뒤에 나오는 것은 세련된 방법이지만 본질적으로 이것과 똑같은 방식이다.

 

SW 규모가 커지면서 require_once 방식은 불편함들이 생기기 때문에,

그 불편함을 낮추는 방식들을 살펴볼 것이다.

 

 

 

 

 

오토 로딩을 통해서

우리가 필요로 하는 파일을 자동으로 require하는 방식

 

이 함수를 사용하면 되는데,

오토로더라는 함수를 정의하고, 

오토로더라는 함수의 이름을 spl_autoload_register 함수의 인자로 준다.

 

 

hi라는 클래스가 없기 때문에 에러가 떴다.

 

우리가 봐야할 부분은 왼쪽 위에 회색으로 선택한 부분이다.

 

php가 hi라는 클래스를 사용하려고 했는데

이 클래스의 정의가 없다.

 

그러면 php는 어떻게 동작하도록 약속돼있냐면,

spl_autoload_register라는 함수를 통해서

함수가 실행될 때 전달된, 함수의 이름에 해당되는 함수를 호출하도록 약속되어 있다.

 

만약 이 상태에서 require_once의 주석을 해제하고 실행시켜보면

hi만 깔끔하게 나온다.

 

즉 autoloader라는 함수가 호출되지 않았다는 뜻이다.

 

즉 require_once를 통해서 왼쪽의 Hi라는 클래스를 로딩한 상태이기 때문에,

 

php는 new Hi를 실행할 때, 왼쪽의 class Hi를 사용하면 되니까

spl_autoload_register를 통해서 등록해놓은 autoloader라는 함수를 호출하지 않는 것이다.

 

즉 php는 우리가 직접 require_once를 하지 않더라도

spl_autoload_register라는 함수를 통해서 로딩할 수 있는 기회를 제공한다.

 

 

 

즉, 

require_once 'greeting.php'와

 

function autoloader(){

 require_once 'greeting.php'

}

spl_autoload_register('autoloader')가

 

결과적으로 같은 것이다.

 

그럼 왜 굳이 후자처럼 복잡하게 쓸까?

 

autoloader는 존재하지 않는 클래스의 정의부 구현체를

자동으로 로딩해주는 역할을 한다.

 

이렇게 하면 아래와 같은 결과가 나온다.

이것은 autoloader의 인자로 전달된 path의 값으로

php가 Hi라는 정보를 줬다는 뜻이다.

 

만약 맨 밑에 Hi 대신 EgoingHi라고 하고 실행시키면

path값으로 EgoingHi가 들어온다.

이렇게 하기로 약속한 것이다.

 

어떤 약속?

 

특정한 함수의 이름(autoloader)을 주면서

spl_autoload_register이라는 함수를 실행시키면

php는 그 함수의 이름을 기억하고 있다.

 

그리고 어떤 특정한 클래스를 인스턴스화 하려고 했을 때,

그 인스턴스하려고 하는 클래스가 존재하지 않는다면,

 

php는 아까 기억하고 있었던 

autoloader라는 이름에 해당되는 함수를 호출하도록 약속이 되어 있다.

 

그러면 autoloader라는 함수가 호출될 때, 호출하면서

php는 첫 번째 인자(아래 그림의 $path)로

호출하는 클래스의 이름(EgoingHi)을 주도록 약속되어 있다.

 

 

 

맨 밑의 EgoingHi를 다시 Hi로 바꿨고,

greeting.php의 이름을 Hi.php로 바꿨다.

 

그리고 4행에 $path의 값을 $path.php로 하고,

6행의 greeting.php를 $path로 바꿨다.

 

결과를 보면,

path: Hi.php는

greeting.php를 Hi.php로 바꾼 파일의 이름과 같다.

 

그러면 자연스럽게 php는 require_once를 통해서

Hi.php를 로딩할 수 있게 되면서

이 파일 안에 존재하는 클래스 Hi의 정의부를 로딩할 수 있게 된다.

 

 

 

 

이것이 바로 spl_autoload_register를 통해서

동적으로 우리가 필요로하는 클래스를 로딩하는 방법이다.

 

Hi.php 파일을 Duplicate해서 Bye.php로 만든다.

내용에서 Hi를 Bye로 바꾼 후

 

마지막 줄에 Bye도 호출하도록 하고 실행시키면

 

 

 

그래도 이 방법도 require_once를 사용하고 있다는 점에서

첫 번째 방법과 똑같은 것이다.

 

 

 

네임스페이스를 통해서

같은 이름의 클래스가 하나의 프로그램 안에 공존하는 방법을 살펴보겠다.

 

여기서 Hi라는 클래스를 정했는데,

이 클래스는 php 전체에서 사용할 수 있는 클래스이다.

 

그 말은 우리나 다른 사람들은 Hi라는 클래스의 이름을 더 이상 사용할 수 없다는 것이다.

(같은 디렉토리 안에 같은 이름의 파일을 만들 수 없는 것처럼)

 

네임스페이스를 써줬다.

 

그러면 다음 네임스페이스가 등장하기 전까지

밑에 있는 클래스들은

해당 네임스페이스에 들어간다.

 

맨 밑에 호출하는 방법

 

greeting이라는 부모 네임스페이스를 만들어주었다.

 

 

 

 

 

이번 시간에는 이것을 다시 분리된 파일로 쪼개보겠다.

 

main.php를 아래쪽 창에 띄웠다.

(클래스 로딩 마지막에 작업했던 php 파일

=

이 내용)

 

 

 

위의 창에서

이 부분을 잘라내기 해서

이 부분에 덮어씌워서 붙여넣었다.

 

회색으로 선택된 부분은

이 코드가 실행된 결과이고,

그 얘기는 new HiEn이라는 클래스를 인스턴스화시킬 때,

여기 있는 부분을 참고해서

이 정보를 

이 path의 값에 넣었다는 것을 알 수 있다.

 

즉 php가 autoloader의 $path 인자로 준 것은

하늘색으로 칠한 부분까지라는 것을 알 수 있다.

 

그러면 우리는 하늘색 값을 잘 조작해서

우리가 원하는 클래스를 php가 require_once할 수 있도록 도와주면 되는 것이다.

 

그걸 하기 위해서 보니까

네임스페이스명까지도 $path 값으로 전달했다는 것을 알 수 있다.

 

그리고 Hi.php 안에는 greeting\en과 greeting\ko라는 두 개의 네임스페이스가

하나의 파일 안에 공존하고 있는 상태였다.

그러면 이것을 쪼개서 파일로 분화해보자.

 

greeting/en과 greeting/ko이라는 폴더를 만들었다.

그리고 Hi.php 파일을 en으로 옮기고, 복사해서 ko에도 붙여넣었다.

 

 

en에서는 ko부분을 지우고,

ko에서는 en부분을 지웠다.

맥에서는 디렉토리와 디렉토리를 구분할 때, \가 아니라 /를 써야한다.

윈도우에서는 잘 될 수도 있다.

 

이 함수를 통해서 바꿔준다.

\를 한 번만 하면 뒤에 있는 '가 escaping이 되므로 \를 두 번 써줘야 한다.

 

깔끔하게 보려고 var_dump를 print로 바꿨다.

굳이 autoloader라는 함수 이름을 만들 필요 없이,

autoloader 함수를 spl_autoload_register 뒤의 ( ) 안에 넣고

autoloader라는 이름을 지웠다. = 익명 함수

 

회색 부분(인자로 전달돼서 언젠가 호출될 것이라고 기대되는 함수)을

나중에 호출된다는 뜻에서 콜백 함수라고 부른다.

 

autoload/autoload.php를 만들고

이 전체를 잘라내기 해서 붙여넣는다.

(인클루드할 것이다.)

 

(이것은 main.php이다.)

 

이제 다른 php 파일에서도

autoload.php 파일을 reqiure하면 사용할 수 있다.

 

'PHP > 생활코딩' 카테고리의 다른 글

6/1(2) 생활코딩 - PHP 기본수업 - 상속  (0) 2020.06.01
6/1 생활코딩 - PHP 기본 수업 - 컴포저  (0) 2020.06.01
5/31(3) 생활코딩  (0) 2020.05.31
5/31 생활코딩  (0) 2020.05.31
5/30(3) 생활코딩  (0) 2020.05.30

댓글