Extra Form
PHP PHP 7.2
CMS Rhymix 2.x

최근에 구현한 게시판 스킨에 공유 기능이 아직 없어서 애드온로 추가를 했습니다.

 

그런데 문제가 발생하더군요. 문서열람 중인지 를 체크하지 않고 작동을 해서 목록페이지 등에서 스크립트의 오류가 납니다.

공유 관련 변수들이 존재하지 않기 때문에 문제가 발생할텐데요.

 

애드온에 문서열람 페이지가 아닌경우 애드온 코드 진행을 중단하시키려고 코드를 넣어보다가 

 

애드온에서 문서정보를 가지고 오기 위해서 

$oDocument = Context::get('oDocument');

 

이렇게 가져왔더군요. 

 

그래서 저는 순진하게 

 

$oDocument->document_srl 로 리턴을 시키려고 시도해 보았습니다.

어... 그런데 이게 리턴이 안되는 것 같습니다.

 

그래서 찍어보니 문서 목록 페이지에서도 $oDocument 값이 있고 

$oDocument->document_srl 값도 0 으로 가지게 되더군요..  헐....

 

이래서 배우고 코드를 짜야 하는데 ...

 

그리고 다시 코드를 자세히 보니 애드온 개발자분이 리턴 코드 대신에 반대로 동작이 가능한 조건을 넣었는데 거기에

$oDocument->document_srl 이 있으면 이라는 조건을 걸었더라구요. 나름 오류를 막으려고 하신 것 같긴 합니다.

 

결국 

1. $oDocument->document_srl 은 아예 안되는 거였다는거를 뒤늦게 깨달은 거 같습니다.

 

그럼 다시 원래 해오던 방식 두가지가 있는데..

 

2번의 방법으로 

Context::get('document_srl') 를 쓰는 겁니다. 이거로 하긴 했습니다.

아주 심플하면서도 문제가 없을 것 같구요.

 

3번의 방법으로는 

$oDocument = Context::get('oDocument');

$oDocument->isExists() 입니다.

 

근데 이 방법이 한가지 의외의 문제를 경험한 적이 있습니다. 상담기능 게시판 목록에서는 $oDocument 자체를 가지지 못해서 500에러가 납니다. 그래서 예전에 배운게 

 

$oDocument && $oDocument->isExists() 

로 앞에 방패를 세워주라는 거였는데요.

 

 

2,3번의 구현방법이 실제적으로 전혀 차이가 없어 보이긴 한데 정말 실제 작동에는 아무 차이가 없겠죠???

 

 

 

  • profile

    1. Context::get 은 사실 그냥 먼저 Context::set 으로 선언한 키값에 변수들을 따로 저장하는 개념입니다. 그래서 미리 그 변수들이 저장되어 있지 않다면 가져올 수 없겠지요.

    즉 $oDocument 변수가 비어있을 수 있고 documentItem 클래스가 있을 수 있고 그런 모든 상황이 다르게 적용될 수 있다는 뜻입니다.

    변수에는 어떤 클래스의 함수들을 호출할 수 있는 형태로도 데이터값을 저장시킬 수 있는데 $oDocument 라는 항목에는 대부분 document.item.php 클래스의 함수들을 호출할 수 있는 변수가 들어가잖아요.

    근데 $oDocument 가 비어있을 수 있다고 아까 말씀드렸으니 $oDocument가 비어있다면 당연히 클래스 호출에 위치를 찾을 수 없으니 500Error가 나타나게 되는 겁니다.

    그럼 document.item.php 을 가져오는 방법을 알아야겠지요.

    document.item.php 을 호출할때 보통

    $oDocument = new documentItem($document_srl);

    이렇게 호출하게 됩니다.

    느낌오시나요?.

    $document_srl 이 있는 상태로 $document_srl 이 게시글의 번호여야 정상적으로 게시글의 정보를 가져올 수 있는 상태가 됩니다.

    즉, 변수자체가 비어있거나 정상적인 상황이 아닌 경우 두가지가 있을 수 있겠지요.

    즉, if($oDocument) 로 비어있는것과 $document_srl 을 가져올 수 있는 상황이 항상 연출 된다면 $document_srl 까지 함께 채크하는 것이 좋겠지요.

     

    --------------------------------

     

    추가로 그냥 문서 열람하는 페이지인지 확인할 예정이시라면 act를 검사해보세요.

     

    act가 넘어오지 않는다면 어쩔수 없는데 디버그 찍어서 $act = Context::get('act') 해보신다음 dispBoardContentView 인경우인지도 확인할 수 있다면 좀 더 좋겠지요.

  • profile profile
    네. 간단하게 썻지만 현재 열린 페이지가 글 열람 페이지냐를 판단하기 위해서 Context::get 를 사용하는 것을 전제로 한 것입니다.

    문서가 진짜 있는지 함수로 조회하는 그런 것에 관한 궁금증은 아니었구요.

    Context::get('document_srl') 로 쓰면 아무 문제가 없지 않냐?? 라는 질문입니다.
    혹시 제가 모르는 다른 차이가 있는지 궁금해서요.
  • profile profile

    다른 서드파티에 따라 좀 달라집니다. 서드파티에서 그 document_srl 키값에 갑자기 숫자를 선언해버리면 그것또한 골치아파질 수 있거든요.

    근데 그럴일은 거의 없다는 가정이 있다면, document_srl 으로 검사하셔도 됩니다.

    근데 더 좋은게 document_srl을 가져올 수 있는 상황이라면 아에 그냥 다시 클래스를 만들어버리시는 것도 나쁘지 않아요

    if($document_srl)
    {

    // 애드온에서의 변수명은 항상 독립될 수 있게 다른 애드온이나 모듈에 영향을 주지 않도록 바꿔서 쓰세요.
    $oDocumentAd = getModel('document')->getDocument($document_srl);
    }
    else
    {
    return
    }

  • profile profile
    근데 document_srl 으로만 검사하기엔 좀 너무 리스크가 있을 수 있을 것 같고 위에 말씀하신 부분에서 3번째 항목

    $oDocument && $oDocument->isExists()

    쓰시면 될것 같아요
  • profile profile

    아.. 이제 정리가 좀 될 것 같습니다. 그동안 흐릿했던게 선명해지네요.

    $document_srl = Context::get('document_srl');
    $oDocumentModel = getModel('document');
    $oDocument = $oDocumentModel->getDocument($document_srl);
    if($oDocument->isExists())


    Context::get('document_srl') 이게 가짜일수 있다는 전제를 무시해서는 안된다는 거네요.


    앞으로는 이렇게 확실히 검증이 될 정도로 해서 코드를 짜도록 해야겠습니다.

    저 말고도 Context::get('document_srl') 퉁치는 개발자분들 많은거 같습니다.

     

    다시 달아주신 $oDocument && $oDocument->isExists() 요것 쓰는 것도 안전한 방법인 것 같네요.

  • profile

    드물지만 서드파티 자료가 $oDocument에 엉뚱한 것을 넣어놓는 경우를 본 적이 있습니다. (대개 content 위젯 스킨이 범인입니다.) $oDocument에 문서가 아닌 것이 들어 있으면 isExists()라는 함수가 존재하지 않아서 오류가 날 수도 있습니다.

    이런 경우까지 감안하여 완벽하게 방어하고 싶다면

    $oDocument && $oDocument instanceof documentItem && $oDocument->isExists()

    로 하시면 됩니다. 두 번째 조건은 $oDocument가 정말로 documentItem인지 확인하는 문법입니다. instanceof가 굉장히 길어 보이지만 그냥 ==, >=, != 와 같은 연산자의 일종입니다

  • profile profile
    $oDocument 도 가짜가 있군요. 헐.....
  • profile profile
    $oDocument = new stdClass()

    이렇게 선언할 수도 있잖아요.

    즉 코딩 하는 사람들의 따라 어떻게 만드냐가 다 틀리니까 무조건 저건 게시글이야! 라고 단언하여 사용할 수 없는 것 이죠.

    $oDocument는 그냥 "변수"일 뿐 다른게 없거든요 ㅎㅎ