일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- hash table
- 자바입력
- scanner
- JAVA11
- SpringBoot 2
- input
- R
- Easy
- 수학
- 카데인 알고리즘
- Kadane's Algorithm
- array
- 자바 스레드 실행 순서 제어
- heroku
- 사칙연산
- 자바 thread 실행 순서 제어
- Today
- Total
DeFacto-Standard IT
PHPStorm + Codeigniter 코드 자동완성(Code Completion) 활성화하기 본문
PHPStorm + Codeigniter 코드 자동완성(Code Completion) 활성화하기
defacto standard 2018. 10. 27. 04:49PHPStorm과 Codeigniter를 쓰면서 가장 불편했던 것은,
자바와 다르게 컴파일 언어가 아니라 스크립트 언어와 이에 대한 프레임워크라 그런지 코드 자동완성 기능이 아주 아주 부족하다는 것이다.
단, @property라는 PHP DOC 주석을 통해 IDE에 힌트를 제공하여 자동완성 기능을 사용할 수 있다.
이를 아는 개발자들은 보통 다음과 같이 Loader클래스를 사용하여 라이브러리나 모델 클래스의 인스턴스를 만들어 로드하고,
로드된 객체를 통해 함수 등을 수행한다.
class user_model {
public function echoModel() {
echo 'echo';
}
}
/**
* @property user_model $user_model
*/
class Welcome extends CI_Controller {
public function index() {
$this->load->model('user_model');
}
public function echoMethod() {
$this->user_model->echoModel();
}
}
위와 같이 PHP DOC 주석에 @property를 사용하는 방법을 통해,
user_model이라는 클래스가 존재한다는 것을 IDE에 힌팅으로 제공한다면 다음과 같이 코드 자동완성 기능이 동작하게 된다.
위는 Welcome 컨트롤러에 PHP DOC을 통해 user_model 클래스가 존재한다는 힌트를 제공해서 Code Completion을 수행시킨 결과다.
위와 같은 방법의 단점은,
Welcome 컨트롤러가 아닌 다른 컨트롤러에서 user_model을 사용할 때, 또 다시 다른 컨트롤러에 PHP DOC을 작성해야 한다는 점이다.
만약 user_model을 사용하는 모든 컨트롤러에 위와 같이 한다고 해도,
user_model의 이름이 변경된다면 모든 PHP DOC을 일일이 찾아서 변경해줘야 한다.
아무리 IDE에서 검색기능을 제공해서 이를 통해 수정한다고 하더라도, 노가다를 해야 하는 것은 변함 없으며,
여러 프로젝트가 존재한다면 user_model이 어느 프로젝트의 user_model인지 확인해야 한다는 점은 동일하다.
user_model을 사용하는 A라는 컨트롤러가 Welcome 컨트롤러를 상속한다면
A컨트롤러의 PHP DOC에는 user_model 에 대한 @property PHP DOC을 기술하지 않아도 상위 클래스의 PHP DOC에 의해 서브 클래스에서도 인식이 된다.
따라서 이를 응용한다면 편하게 자동완성 기능을 이용할 수 있을 것 같다.
CodeIgniter에서 컨트롤러를 정의하는 방법은, controller 폴더 내에 클래스를 정의하고 CI_Controller를 상속받는 것이다.
따라서 CI_Controller에서 user_model에 대한 @property PHP DOC을 기술한다면 모든 컨트롤러가 user_model을 인식하고 자동완성 기능을 사용할 수 있게 된다.
하지만 이 방법은 좋지 않다.
CI_Controller는 코드이그나이터의 Core단에 존재하는 클래스다.
코드이그나이터의 버전을 업그레이드할 때, 코어단의 소스가 변경되므로 user_model에 대한 @property PHP DOC은 사라지게 된다.
만약 코어단의 CI_Controller의 PHP DOC에 정의해놓은 @property가 많은 상태라면 처음부터 다시 모두 등록해야 한다.
기본적으로 프레임워크 코어단의 소스를 고치는 것은 아주 부적절하다.
하지만 일괄적으로 PHP DOC을 적용하는게 불가능한 것은 아니다.
다른 경로에 사용자가 만든 커스텀 CI_Controller를 인식시키게 하고,
이 커스텀 CI_Controller의 PHP DOC에 인식시키고 싶은 클래스들을 @property PHP DOC으로 지정하면 된다.
커스텀 CI_Controller를 만들면 기존의 CI_Controller를 동시에 인식하게 된다.
이 상태에서 CI_Controller를 상속받으면, 같은 이름의 클래스가 2개라 IDE에서 노란 줄로 warning을 표시한다.
따라서 Core단에 존재하는 CI_Controller를 인식하지 않게 하는 작업도 필요하다.
이렇게 한다면 실제로는 코어단의 CI_Controller를 사용하므로 문제없이 동작하게 되고,
IDE에서 코딩할 때는 커스텀 CI_Controller를 인식하여 사용자가 정의한 라이브러리나 모델 클래스에 존재하는 메서드나 프로퍼티를 쉽게 자동완성으로 warning없이 깔끔하게 보여줄 수 있게 된다.
커스텀 CI_Controller는 코어단의 경로에 위치하지 않기 때문에,
코드이그나이터의 버전을 변경하더라도 개발자가 만든 소스로 인식되 덮어씌워지지도 않는다.
1. 다음 링크에서 phpstorm.php를 다운로드
https://github.com/natanfelles/codeigniter-phpstorm
2. phpstorm.php파일을 CI 프로젝트 최상단에 위치시킴
3. phpstorm.php의 CI_Controller, CI_Model 클래스에 @property를 활용하여 힌팅을 제공할 클래스 정보 입력
* @property CI_Utf8 $utf8 Provides support for UTF-8 environments
* @property Ispconfig $ispconfig This class enables you to use the ISPConfig 3 Remote API
* @property Boleto $boleto Boleto Class
* --------------------------------------------------------------------------------
* @property user_model $user_model
*/
class CI_Controller {
public function __construct()
{
}
}
* @property CI_Xmlrpcs $xmlrpcs XML-RPC server class
* @property CI_Zip $zip Zip Compression Class
* @property CI_Utf8 $utf8 Provides support for UTF-8 environments
* --------------------------------------------------------------------------------
* @property user_model $user_model
*/
class CI_Model {
public function __construct()
{
}
}
CI_Controller와 CI_Model의 @property PHP DOC에 user_model 등록한다면,
CI_Controller 및 CI_Model을 상속받는 클래스에서 user_model에 대한 클래스가 인식된다.
3. 프로젝트/system/core 로 이동해서, Controller.php와 Model.php를 선택 후 우클릭, 'Mark as Plain Text' 선택
코어단의 CI_Controller와 phpstorm.php의 CI_Controller를 동시에 인식하고 있어, IDE 상에서는 중복된 클래스 네임으로 warning 언더라인을 그린다.
따라서 Core단의 CI_Controller 인식을 못하게 하는 작업이다. IDE에서 Plain Text로 인식시킬 뿐, 소스코드에는 변경이 없으므로 배포하거나 실행해도 문제없이 동작한다.
4. 테스트
이제 CI_Controller 및 CI_Model을 상속받는 모든 클래스에서 주석 없이도 코드 자동완성이 동작하게 됐다.
한 가지 더 생각해볼 것이 있다.
라이브러리의 경우는 CI_Model이나 CI_Controller를 상속받지 않는다.
따라서 커스텀으로 작성한 CI_Model과 CI_Controller의 PHP DOC에 대한 영향을 받지 않는다.
어떤 경우에는 라이브러리에서 Model 등을 사용하게 될 수도 있다.
Loader 클래스를 사용하려면 $this 객체를 사용하여야 한다. 그래야만 $this->load->model('user_model')을 호출해서 사용할 수 있다.
문제는 이는 CI_Model 또는 CI_Controller를 상속받아야 하는 것인데, 이 중 어떤 것도 상속받지 않는 라이브러리의 경우는 Model의 사용 방법이 다르다는 것이다.
보통 라이브러리에서는 CI 객체를 &get_instance() 를 사용해 할당받아서 사용한다.
get_instance()의 구현을 보면 CI_Controller::getInstance() 의 호출결과를 리턴한다.
이는 싱글톤으로 구현되어 있음을 의미하고, CI_Controller 클래스의 객체 자체가 리턴된다고 볼 수 있다.
따라서 CI_Controller에 @property PHP DOC을 등록해놓는다면,
이 정보들이 &get_instance()로 부터 리턴받은 객체에도 동일하게 적용되기 때문에 자동완성 기능을 쓸 수 있다.
물론 이러한 방법을 사용 할 때 주의할 점이 있다.
자동완성 기능은 위에서 말했듯이 @property PHP DOC에 기술된다면 해당 정보를 통해 출력된다.
이는 실제로 Loader 클래스를 사용해서 클래스의 인스턴스를 로드하지 않아도, 자동완성 기능 상으로는 사용할 수 있다는 얘기다.
Loader 클래스를 사용해서 로드하지 않고 그대로 사용한다면 당연히 에러가 날 것이다.
따라서 개발자들이 이를 간과하고 그대로 코드를 작성할 위험이 있다.
하지만 이는 PHP DOC을 사용해야 자동완성이 작동되는 것 자체의 문제이고,
phpstorm.php과 같은 커스텀 파일에 CI_Controller를 따로 정의해서 생기는 문제는 아니다.
require_once를 사용하지 않고, Loader 클래스를 통해 인스턴스를 로드하여 이를 사용한다는 코드이그나이터의 철학을 그대로 사용한다면 자동완성 기능을 PHP DOC을 등록해야만 사용할 수 있다는 것은 엄청난 단점으로 작용한다.
이를 보완할 수 있는 방법이므로, 차라리 특정 클래스를 사용하기 전에 확실히 로드했는지 잘 확인하고, 테스트를 충분히 하여 편한 개발을 할 수 있게 하는 것이 더 중요하다고 생각한다.
'DEV tools > PHPStorm' 카테고리의 다른 글
PHPStorm + Xdebug + XAMPP + PHP/CodeIgniter 로컬에서 디버깅하기 (2) | 2018.09.10 |
---|