라르게덴님의 트리거 강좌를 숙독하고 열심히 응용해보고 있는데요.

(역시나 트리거 없는 대상에서 트리거 만들기는 어렵더군요ㅎ)

member 모듈에서 insert, update, delete 실행에 따라, 요즘 제작 중인 user 모듈(nick_name과 user_name의 자소 분리 문자열을 별도의 테이블에 담고 있어요)에도 반영을 하고 있습니다.

 

근데 이 놈의 욕심 때문에ㅋ 사용자정의(extra_vars)도 변수별로 자소 분리를 해서 테이블에 담는 것까지도 성공을 했어요.

사용자정의 대상으로도 자동완성 검색을 해서 회원 검색이 가능하도록 해보려구요.

 

0.png

 

다행히 insertMember, deleteMember에도 잘 반응하고 있습니다만, 유독 updateMember에 대해서만 동작이 어렵네요.

 

public function triggerUpdateMember($obj) // 호출시점은 before
{
    $oUserModel = getModel('user');

    $args = new stdClass();
    $args->member_srl = $obj->member_srl;
    $orgMemberInfo = executeQuery('member.getMembers', $args)->data;
    if ( $orgMemberInfo->user_name != $obj->user_name || $orgMemberInfo->nick_name != $obj->nick_name || $orgMemberInfo->extra_vars != $obj->extra_vars )
    {
        $args = new stdClass();
        $args->member_srl = $obj->member_srl;
        $args->user_name = $oUserModel->getDissemble($obj->user_name); // getDissemble()은 한글 체크 후 자소 분리를 해주는 함수
        $args->nick_name = $oUserModel->getDissemble($obj->nick_name);
        $args->type = 'update';

        $this->handleUser($args); // handleUser()는 $args->type에 따라 rx_user 테이블을 핸들링(삽입, 수정, 삭제)해주는 함수
    }
    else
    {
        return;
    }
}

 

이렇게 해서 기존의 extra_vars값과 새로 수정된 extra_vars값이 다를 경우, DB에 반영이 되도록 했어요.

nick_name이나 user_name에 변화가 있을 경우엔 잘 반영이 되거든요.

근데 회원정보에서 사용자정의값만 수정했을 경우에는 이게 반응을 안 하더라구요.

정확히 말하자면, 사용자정의값을 두 번 수정할 때 첫 번째 수정된 값만 반영됩니다;;;

(무슨 말인지 헷갈리시죠? 저도 도통 잘 이해가 안 되는 로직이에요ㅠ)

 

extra_vars가 직렬화된 데이터여서 그런 건지, 트리거 호출 시점을 after로 따로 하나 더 해야 하는 건지, 답답하네요.

 

결론 : 이렇게 하소연하고 나면 문제가 해결되는 경우가 있어서, 하소연 남기고 문제해결을 기도해봅니다ㅜ

윤삼

profile
아무래도 중급 초반 수준의 코딩 오타쿠인 것 같습니다.
  • ?

    음... 굳이 before에서 처리해야 하는 이유가 있나요?

    기존의 extra_vars와 수정된 데이터의 extra_vars 값이 달라졌는지 확인하기 위해 그러신 것 같은데,
    기존의 값을 읽어와서 비교하는 것이나, 읽지 않고 무조건 덮어쓰기 하는것이나,
    결과적으로 받는 DB 부하는 비슷할 것 같은데요..!
    읽어 왔을때 수정이 필요하지 않다면, 읽기 한번만 하면 되지만, 그게 아니라면 읽기/쓰기 두번의 쿼리가 실행되니 오히려 손해가 아닐까요...?

    그 뿐만 아니라, before에서 처리를 하면,
    몇몇 조건에 의해 정보 수정이 진행되지 않았을 경우(금지닉네임, IP차단 등)에도,
    트리거가 작동하기 때문에, 실제로 수정될 것인지 아닌지를 한번 더 체크해야 할거 같은데요...!

     

    정확히 어떤 결과를 원하시는지 몰라서...

    제가 관련 트리거를 사용한 기능을 제작할 때의 경험을 말씀드리는겁니다..!

    윤삼님 경우와는 다를수 있어요.

  • ? profile
    말씀 감사합니다! 눈꺼풀이 확 트이는 느낌이에요.
    말씀대로 굳이 DB를 읽어올 필요는 없겠네요. 아, 이 깨달음.
    조건문 없이 after로 처리했습니다.

    다만, 그렇게 해도 사용자정의 확장변수의 업데이트는 잘 안 먹히네요;;
    확장변수만 수정했을 때에는 user 테이블에 반영이 안 되고,
    또 한번 확장변수만 수정하면 이전에 수정했던 값이 그제야 테이블에 반영이 돼요.
  • profile ?

    수정하신 코드 한번 올려주세요.
    멤버 모듈에서 수정시 after 트리거로 넘겨주는 $obj에 멤버 테이블의 모든 값이 들어가 있을텐데요...?

  • ? profile

    완전 그지 같을 텐데ㅠㅠ

    코드 하일라이터 가독성 때문에 파일로 그냥 첨부해봅니다.

    일단 현재 작업중인 class, controller, model 이라도..

    (영어도 급히 수정했어요ㅋ)

    감사해요ㅜㅜ

  • profile ?

    코드를 보니, extra_vars 는 따로 모델에서 가져오시는 것 같은데,

     

    triggerUpdateMember 함수에서,
    $args->extra_vars = unserialize($obj->extra_vars);
    같은 코드를 통해 handleUser 함수에 extra_vars 값을 넘겨주고,

     

    handleUser 함수에서도,
    updateUserExtraVars 를 실행할 때, member_srl만 넘기지 말고, extra_vars 도 같이 넘겨서
    처리하시면 될 것 같아요.

     

    파일 첨부합니다.

    user.controller.phps

    Atachment
    첨부
  • profile ?

    아, 댓글을 쓰고 보니 다른 파일들도 첨부해 주셨네요.

     

    제가 이전에 첨부해드린 파일의 updateUserExtraVars 함수는 extra_vars 를 싹다 체크해버리는데,
    다른 모듈/애드온에서 extra_vars를 건드리는 경우를 고려하지 못해서 수정본 올립니다.

     

    user.controller.phps

    테스트는 못해보았으니, 개요만 확인하시는걸로...!

    Atachment
    첨부
  • ? profile

    옛, 감사합니다ㅜㅜ
    첫 번째 파일은 완전 잘 되고, 두 번째 파일은 새로 넣으신 변수가 배열 형태가 아닌가봐요.
    $trigger_values[$key]를 $trigger_values->$key로 바꿨더니 잘 됩니다.
    감사해요, 갓데벨님ㅠㅠㅠ

  • profile

    윗분 말씀대로 after에서 처리해 보세요. 조건에 따라 처리 자체를 막거나, 처리 전에 데이터를 미리 조작해야 할 필요가 있을 때를 제외하면 before를 쓰는 것은 권장하지 않습니다.

    after에서도 안 먹힌다면 moduleObject.proc after를 잡아서 $member_srl 값을 기준으로 확장변수들을 일괄적으로 다시 불러오는 방법도 있습니다. (moduleObject.proc before에서 기존의 확장변수들을 미리 불러와서 따로 쟁여놓으면 바뀐 변수가 있는지 확인할 수도 있습니다.)

     

    근데 getDissemble은 어느 나라 말인가요? ㅋㅋ

  • profile ?
    디셈블러라는 단어를 많이들 사용해서
    디셈블 이라는 단어가 어셈블의 역으로 존재하는 단어인줄 알았는데, 아니었군요...!ㅋㅋㅋ
  • ? profile
    디스어셈블러(Disassembler)는 있습니다 ㅋㅋㅋ
  • profile profile
    ㅋㅋㅋㅋㅋ 아, 쪽팔려요
  • profile
    저도 잘 기억나지 않는 트리거를 읽어보셨군요.
    제가 문외한이라 질문드리는데 트리거 사용 형식이 회원정보 수정 시 다른 기능을 수행하는게 아닌 정보를 인터셉트하시는 거 같은데 참조표현(&$obj)을 활용하지 않으시는건지 궁금합니다.
    before로 트리거 받고 $obj에 변환한 확장값을 그대로 저장해주면 updateMember()가 알아서 db로 넘기지 않을까 하는데 말이죠...
  • profile profile
    라르게덴님, 그럼 triggerUpdateMember($obj)와 triggerUpdateMember(&$obj)가 서로 다른 결과로 이어지게 되나요?
    늘 궁금하던 것 중에 하나가 &getModel()이 아니라 getModel()로 해도 결과가 같은 거였거든요.
    다른 모듈들의 트리거 호출도 컨닝을 해보면 많은 경우 그냥 $obj로 변수를 가져오더라구요.

    암튼 위의 경우에는 extra_vars를 가져오는 과정에서 제일 큰 문제가 있었던 것 같아요. 그리고 호출 시점은 윗 분들 말씀처럼 before로 하면 회원정보 수정이 안 됐는데도 현재 모듈('user')에는 수정이 되는 경우가 발생할 우려도 있고 해서 after로 바꿨어요.
  • profile profile
    before에서 회원정보 수정이 안되는 것이 참조표현과 관계가 있을 것 같습니다.
    https://xetown.com/rxe_dev/2499 에 참조표현이 뭔지 설명되어있으니 다시한번 읽어보시고 시도해보세요.
    after도 동작만 된다면 뭘 하든 상관없지만 왠지 너무 복잡한 걸 짜신것 같아서 말씀드립니다. ^^
  • profile profile
    member 테이블에서 extra_vars가 관건이었는데, 1) 이게 직렬 데이터인 데다, 2) 다른 자료들에서 여기에 다른 변수를 집어넣고 쓰는 경우들이 있어서 그걸 분리하는 과정 때문에 복잡했던 것 같아요.
    extra_vars에 괜히 욕심을 내서;;; 암튼 복잡합니다ㅜ

    결과적으론 after로 잘 동작하고 있어요 :)
    틈 나는대로 트리거 공부 계속하고 질문도 남길게요!