PHP 오토로드 (AutoLoad)

Neptunere·2022년 1월 24일
0

PHP

목록 보기
1/2
post-thumbnail

📖 AutoLoad

인스턴스를 생성하면 자동으로 호출되는 함수

<?php
	require_once 'Member.php';
	require_once 'Company.php';
	require_once 'Main.php';
	require_once 'Setting.php';
 	require_once 'ValidationCheck.php';
	
	class Mypage {
    		// [22.01.25] 회원 정보 불러오기
    		public function getMemberInfo() {
        		$memberInfo = [];
                
                	try .... catch 생략
                
                	return $memberInfo;
        	}
    }
?>

회사에서 작업을 하던 도중, 문득 소스 코드를 보니
require_once가 여러개가 되어 있는걸 보았는데
본 프로젝트는 사이즈가 크기에 후에 불편함이 많아질 것 같아 매우 그렇다. 😅
이런 부분을 어떻게 해결할까 고민을 했는데 AutoLoad 라는걸 발견했다.

AutoLoad 쓰기는 해야 하는데 어떻게 쓸까?


우리는 AutoLoad를 쓰기 전에 우선 알아야할 부분이 있는데 바로 spl_autoload_register입니다.

sql_autoload_register는 자동으로 클래스를 인식해서 OOP를 쉽게 지원을 해주는데

<?php
	spl_autoload_register(function ($class) {
 		require_once "{$class}.php";
	});
?>

이런 식으로 인스터스가 필요한 부분에 자동적으로 클래스를 인식을 해준다.

그런데 만약 클래스마다 경로가 다르다면? 🤔

Model이라는 폴더에 각 DB 테이블명을 지칭하는 하위 폴더들이 있고
그 하위 폴더에 클래스 파일들이 있다면 sql_autoload_register를 사용한 코드에
여러 경로에 대한 많은 예외처리가 들어가지는데 😭

하지만 우리에게는 이를 해결하는 방법이 있으니.....

🦕 NameSpace


우선 클래스마다의 경로를 해결하기 전에 네임스페이스에 대해 짧게 설명을 하겠습니다. 😄

<?php
    class Test1 {
        public function test1() {
            var_dump('Hello World');
        }
    }

    class Test1 {
        public function test1() {
            var_dump('Hello World');
        }
    }

    
    $test1 = new Test1();
    $test1 = new Test1();

    echo $test1->test1();
    echo $test1->test1();
?>

해당 소스 코드를 보면 클래스명도 동일하고 메소드명도 동일하다.
만약 이 소스 코드를 실행하면 어떻게 될까? 🤔

결과는 모두 예측했듯 터진다

네임스페이스는 이렇게 클래스명이나 메소드명이 겹쳤을 때 큰 도움이 되는데
같은 이름의 클래스를 공존할 수 있게 만들 수 있기 때문이다

<?php
    namespace test\t1;

    class Test1 {
        public function test1() {
            var_dump('Hello World');
        }
    }

    namespace test\t2;

    class Test1 {
        public function test1() {
            var_dump('Hello World');
        }
    }

    use \test\{
        t1,
        t2
    };

    new t1\Test1();
    new t2\Test1();
?>

use에 대해서는 namespace 포스팅에서 자세히 알아보는걸로 하고
해당 소스 코드를 보면 분명 같은 클래스명이긴 하지만 바라보는 네임스페이스가 다르기에
오류가 발생하지 않는다.

그럼 이런 점을 이용해서 namespace를 활용해서 경로가 달라도 불러올 수 있게
처리해볼 수 있지 않을까?라는 생각이 듭니다.

🦦 NameSpace를 활용한 호출


api\models\Test.php

<?php
    namespace api\models;

    class Test {
        public function test1() {
            var_dump('Hello World');
        }
    }
?>
api\models\Test2.php

<?php
    namespace api\models;

    class Test2 {
        public function test2() {
            var_dump('Hello World2');
        }
    }
?>

이런 식으로 디렉토리 구조는 PSR namespace 권장 사항을 적용하여 만들어 줍니다.
이제 index.php를 수정해 봅시다.

<?php
    /* require_once('api\models\Test1.php');
     * require_once('api\models\Test2.php'); 
     */
    require_once('vender/autoload.php');

    use api\models\{
        Test1,
        Test2
    };

    $test1 = new Test1();
    $test1->test1();

    $test2 = new Test2();
    $test2->test2();
?>

기존 require_once 여러 개 선언한 부분을 주석 처리하고
맨 처음 만든 autoload.php로 선언을 한다.
이렇게만 보면 기존 여러 개로 되어있던 require_once가 모두 사라져 코드가 간결해졌습니다.

이 상태에서 index.php를 실행을 해봅시다!
웬걸 오류가 발생했는데 왜 일까요? 😱
autoload.php로 돌아가서 클래스를 어떤 식으로 호출 하는지 확인해 봅시다.

<?php
    sql_autoload_register(function ($class) {
        echo "path: {$class}"; exit;
        // require_once "{$class}.php";
    });
?>

결과는 path: api\models\Test1

자세히 보면 경로 부분의 문자가 역슬래쉬('\')로 되어있는걸 확인할 수 있는데
윈도우라면 괜찮지만 만약 리눅스라면? 😨
리눅스 안에서는 경로를 구분할 때 사용하는 문자는 슬래쉬('/')이기 때문에
역슬래쉬('\')로 되어있는 부분을 모두 슬래쉬('/')로 바꾸어야 합니다.

기존 소스코드에서 아래 코드를 첫 줄에 추가해 봅시다.
$class = str_replace('\', '/', $class);

<?php
    sql_autoload_register(function ($class) {
        $class = str_replace('\\', '/', $class);
        echo "path: {$class}"; exit;
        // require_once "{$class}.php";
    });
?>

결과는 path: api/models/Test1

동일하게 소스 코드를 작성하여 실행하였다면 정상적으로 클래스가 호출되는 부분을 확인할 수 있습니다.
아무래도 작업하면서 팀원 간의 메소드명 부분들이 겹치는 일이 발생할 수도 있어
namespace를 사용하여 하는 부분은 꼭 필요한 단계인 것 같다.

namespace를 도입하기 전과 도입하기 후의 차이라고 한다면 아무래도
도입한 후가 더 능률도 좋고 팀원간의 마찰도 많이 적었던 것 같다.

참고 포스팅: 훈잇 블로그

profile
https://jeonghyeonmun.develofolio.com

1개의 댓글

comment-user-thumbnail
2022년 1월 28일

좋은 정보 감사합니다~
저도 php 개발 하고 있는데 정말 좋은 정보입니당!!

답글 달기