CI 묻고 답하기

제목 ci hook 사용중
카테고리 CI 2, 3
글쓴이 pwrlove 작성시각 2016/09/12 15:56:22
댓글 : 17 추천 : 0 스크랩 : 0 조회수 : 22560   RSS
$config['enable_hooks'] = TRUE;

hook 기능을 활성화 했더니, 뷰의 table 사용중 아래와 같은 오류가 나네요.

hook에 적용된 기능은 정상적으로 작동이 잘 되는 듯 한데.

 

A PHP Error was encountered

Severity: Notice

Message: Undefined property: CI_Loader::$table

그래서 다시 

$config['enable_hooks'] = FALSE; 로 바꾸면

페이지가 정상적으로 나오고, 뭘 확인해야 하는 건가요?

hook 기능을 처음 적용해보니, 이것도 쉽지 않네요?

 다음글 테이블 데이터가져오기 하나의 모델에서 처리가능한지? (5)
 이전글 ci mysqli 사용 관련 오류 질문입니다. (10)

댓글

kaido / 2016/09/12 15:59:01 / 추천 0

당연히 hook 파일을 확인해 보셔야죠.

hook 파일은 include 방식으로 작동 한다고 생각 하시면 안됩니다.

그냥 별도의 프로세스로 한번 돈다고 생각 하세요.

pwrlove / 2016/09/12 16:07:24 / 추천 0

그냥 별도의 프로세스로 돈다는 말씀은 이해가 되는데,

왜 다른 컨트롤러에서 생성된 인스턴스가 영향을 받나요?

A 컨트롤러 -> A 모델 -> A 뷰

->hook 컨트롤러

훅킹이 개입하는 순서를 명확히 지정해 주지 않아서 그런건가요?

A 컨트롤러에서 바인딩된 인스턴스가 왜 A 뷰를 렌더링할때 영향을 받는거죠?

kaido / 2016/09/12 16:14:57 / 추천 0

잠시만요.

왜 다른 컨트롤러에서 생성된 인스턴스가 영향을 받나요? 

 

1. 후킹은 기본적으로 모든 컨트롤러에 영향을 줍니다.

2. ci 후킹은 끼어드는 타이밍이 있습니다.

http://www.ciboard.co.kr/user_guide/kr/general/hooks.html

후킹 포인트 참조해 주세요.

가령 포인트가 컨트롤러가 실행되기도 전에 컨트롤러와 관련된 기능을 호출 한다면 에러가 발생 할 수도 있습니다.

 

A 컨트롤러에서 바인딩된 인스턴스가 왜 A 뷰를 렌더링할때 영향을 받는거죠?

이건 무슨 의미인지 잘 모르겠네요.

pwrlove / 2016/09/12 16:15:39 / 추천 0

그냥 단순히 페이지가 로그인 되었나 세션만 확인하는 기능만 넣었는데,

훅킹하는 클래스에서도 대상이 되는 모든 컨트롤러에서 사용되는 라이브러리를 로드해 줘야하는 건가요?

이건 좀 전 잘 이해가 되지 않는데요. 훅킹하고 연관된 라이브러리만 로드하면 안되나요?

kaido / 2016/09/12 16:16:49 / 추천 0

아아. 이제 조금 이해가 가네요.

 

후킹에 사용하는 라이브러리와 컨트롤러에 사용하는 라이브러리는 별도로 로드해 줘야 합니다.

 

http://cikorea.net/bbs/view/lecture?idx=12894&lists_style=

 

간단하게 한번 봐주세요.

 

pwrlove / 2016/09/12 16:26:11 / 추천 0

A 컨트롤러에서 바인딩된 인스턴스가 왜 A 뷰를 렌더링할때 영향을 받는거죠?

A라는 컨트롤러 클래스에 대개 필요한 라이브러리를 모두 로드하는걸 일반적으로 OOP에서 바인딩이라는 용어를 쓰는데,

C++ 이나 자바 같은 경우, 그렇게 많이들 사용합니다. 어쨌든, PHP도 OOP(객체지향 프로그래밍)이니 그렇게 혼용을 한것 같습니다.

죄송합니다, 여기서 잘 쓰지 않는 표현을 해서요.

제가 다른쪽 언어를 많이 써서....

어쨌든, 컨트롤러 객체가 생성되고, 로드된 라이브러리는 어딘가 메모리에 존재를 할꺼고, 그걸 A 컨트롤러가 로드된 라이브러리의 객체를 바인딩하고 있다고 생각됩니다.

마찬가지로 A 모델도, 또 A뷰도 모두 구조상 A 컨트롤러에 로드가 되어서 같이 바인딩되어 있을테고,

그걸 최종적으로 html로 만들어져서 브라우저에 던져지고 렌더링이 될텐데, 후킹이라는 기능적 매커니즘은 그 중 어딘가 개입을 해서 하나의 코드 스니핏으로 html에 넣어질 것으로 봤는데, 그 과정에서 왜 영향을 주는지 잘 이해가 되지 않아서요.

 

제가 너무 장황하게 설명을 늘어놔서 오히려 정신이 없네요.

 

 

 

 

kaido / 2016/09/12 16:34:02 / 추천 0

저도 java c++ 합니다 ㅎㅎ

제가 의문이 든것은 후킹 질문에  A컨트롤러 랜더링을 왜 신경 쓰시는지에 대한 궁금증이었습니다..

 

자세한건 저도 코어를 보지 않았서 이렇다고 해명은 어렵습니다만, 후킹은 말 그대로 컨트롤러 하고 전혀 다른 존재입니다.

A 컨틀롤러가 바인딩이 되어 있다고 후킹이 가져다 쓰지 않는 다는 의미입니다.

말 그대로 각기 다른 객체가 사용된다는 의미입니다. [그래서 후커에서 세션을 로드해도 컨트롤러에서도 세션을 또 로드해야합니다.]

view 쪽도 제가 알기로는 pwrlove 님이 아시는 개념처럼 바인드 해서 쓰는 개념이 아닌 걸로 알고 있습니다.

 

이런 부분이 ci4에 가면 조금 달라 지긴 합니다. 

물론 정식 버전이 나와봐야 확실해지겠지만 말이죠.

 

변종원(웅파) / 2016/09/12 16:43:17 / 추천 0

자바랑 php는 태생이 다릅니다. 메모리에 다 가지고 있을 거란 생각 자체가 다릅니다.

그리고 hook을 쓰려면 ci의 $this객체를 사용할 수 있는 곳이 어디인지 알아야 합니다. 그외에는 모두 인스턴스를 따로 선언하여

사용해야 합니다. 그리고 hook 포인트에 따라 자원을 쓸 수 있고 없고 할 수 있습니다.

pwrlove / 2016/09/12 16:47:37 / 추천 0

네, 도움주신거 참고하여 이리저리 해 보고 있는데요.

아직도 전 잘 이해가 안되고 있습니다.

후킹에서 사용한 객체에서 모든 라이브러리를 다 로드해 봐도 테이블 기능이 전혀 안되고 있습니다.

뭔가 정리를 다시 해 봐야 겠습니다.

그런데, 다른 분들도 후킹과 테이블, 페이지네이션 트러블은 없었나요?

궁금해 지네요? 제가 뭘 특별하게 구현했는지도 궁금하구요.

전 코드이그나이터 매뉴얼 세심하게 읽어보고 한건데....ㅠㅠ

kaido / 2016/09/12 16:51:18 / 추천 0

후킹 관련 에러 질문은 보통 '세션이 안돼요' 정도 입니다.

그것도 제가 링크해 드린 부분은 참고하시면 바로 해결 가능 하시구요.

 

딱히 어렵게 생각 하지 않고, 대전제만 가지고 가시면 됩니다.

ci hook 는 딱히 많은 것을 하는 것도 아니거든요.

pwrlove / 2016/09/12 17:00:14 / 추천 0

아무리 언어적 태생 조건이 달라도, 기본적으로 컴퓨터 아키텍처상 대개 언어의 구조적 유사성을

많을 거란 생각을 조금은 하고 있습니다. 물론 다를 수 도 있지만요.

제가 생각하고 있는건 OOP를 기능적으로 구현할경우 비록 개념이 다른 언어라고 할지라도 현존하는 technology를 최대한 활용할테구요. 자바의 아키텍처는 컴파일링 후, 바이트코드라는 최적화된 코드를 가상머신에서 돌리는 거고,

PHP는 인터프리터를 사용해 html 결과를 만들어서 클라이언트에 전송하는 거지만, 결과를 만들기위해서 parser 및 자료구조등은 거의 같은 기술을 사용할 수 밖에 없다고 생각합니다. 그렇기 때문에 비슷한 방식으로 구현이 될 수 밖에 없고, 그렇게 이해를 하는것이 일반적인 접근방법 일 겁니다.

제 생각은 그렇습니다.

pwrlove / 2016/09/12 17:15:38 / 추천 0

정리하자면,

A라는 컨트롤러에서 필요한 라이브러와 모델, 뷰를 로드했는데(근데, 왜 혼동되게 로드하고 했을까요? ㅎㅎ)

그 순간 어느시점(여기선 프리후킹으로 가정하겠습니다.)에 후킹 객체가 실행되어서 어떤 기능(여기선 세션생성 여부만 확인)을 하고,

다시 A 컨트롤러로 제어권이 넘어왔을때, 기존에 로드된 것들 중 테이블과 페이지네이션만 기능이 없어졌다.

이렇게 밖에 이해가 되지 않는데, 그렇다면 우리가 여기서 확인해야 할것은 왜 유독 다른 건 이상없는데,

테이블과 페이지네이션만 뷰가 호출되었을때.

$this->table 이 부분에서 기능이 문제가 되는건데, 이때의 $this는 후킹으로 갔다 되돌아 오고, 여전히 후킹 클래스의 this 포인트로

남아 있는 경우가 되는 걸까요?

아님, 싱글 인스턴스처럼 후킹에서 제거되어버려서 없어졌으니, 다시 A 컨트롤러에서 재 로딩이 이루어져야 하는 건지?

전 이 두경우가 아니라면, 저렇게 작동이 되는 상황이 잘 이해되지 않는다는 말이었습니다.

아, 그리고, 전 뷰에

$this->table->add_row();

echo $this->table->generate();

echo $this->pagenation->create_links();

를 사용하고 있거든요. 그러니, 뷰를 최종적으로 html로 생성할경우(이걸 렌더링이라고 했습니다.) 인터프리터가 저 코드를 번역해서

html table 코드를 만들텐데, 저 부분에서 문제가 생기거든요.

그러니, 제가 그런 표현을 쓴겁니다.

pwrlove / 2016/09/12 23:10:07 / 추천 0

다음과 같은 코딩을 통해 저런 문제가 발생하는 걸 확인했습니다.

hook에 사용된 Login.php를 어딘가에서 찾은 예제를 사용했더니 그렇게 되는 군요.

 

class Login extends CI_Controller
{
   private $CI;

   function __construct()
   {
      parent::__construct();

      $this->CI =& get_instance();
//    $this->CI->load->library('Datatables');
//    $this->CI->load->library('table');
//    $this->CI->load->library('pagination');
//    $this->CI->load->library('session');
//    $this->CI->load->helper('url');
   }

 

일단 다음과 같이 고치면 잘 되는걸 확인했습니다.

class Login
{
   private $CI;

   function __construct()
   {
      $this->CI = &get_instance();
      $this->CI->load->library('session');
      $this->CI->load->helper('url');
   }

컨트롤러를 상속 받으면 안되는 것 같습니다.

위의 소스가 이상없는것이라면 저한테는 구조상 문제가 있거나, 아니면 제가 가정했던 싱글턴 인스턴스로 처리가 되는 부분이 있나보네요.

아마도 아래의 이 부분이 스태틱 인스턴스를 참조하는 부분이고, 컨트롤러 상속을 받게되면 어떤 영향을 주는 것 같습니다.

제 추정입니다. 잘 아시는 분 검증 부탁드립니다.

$this->CI = &get_instance();
한대승(불의회상) / 2016/09/13 01:48:23 / 추천 0

@pwrlove 잘 작성 하셨네요.

추정 하신대로 컨트롤러는 싱글톤 처리가 되어 있습니다. 

작성하신 소스처럼 hook에는 CI_Controller를 상속 받지 않은 클래스를 사용하셔야 합니다.

CI 기능을 사용 하시려면 get_instance()로 CI를 받아 사용하시면 됩니다.

hook은 kaido님이 언급하신 것처럼 컨트롤러에 상관없이 CI 프레임워크가 실행될때 특정 시점에 실행 됩니다.

특정 url에서는 hook이 동작 하지 않아야 한다면 hook 내에서 예외처리를 해주셔야 합니다.

 

 

pwrlove / 2016/09/13 08:50:39 / 추천 0

도움 주셔서 감사합니다.

많이 배웠습니다.