질문/조언질답게시판

php7.1 에서는 함수에 변수가 있는데, 초기값이 없는데 전달 인자가 없으면 에러가 나는 현상이 있었고
php7.2 에서는 Object 클래스의 중복으로 인한 오류가 있었죠

 

이번에 php8 로 넘어오면서

기존 XE Core 라든지  배포된 또는 서드파티 자료들에서 

php8 때문에 생길 수 있는 오류의 대표적인 원인들이 어떤게 있나요?   

예전엔 오류가 아니었을건데, php8 변경때문에 오류가 되어버리는 사항들의 주요원인을 알면

고치기가 쉬워서 php8 전환해본 분들께 여쭤봅니다.  ^^  

 

저도 무료 배포한 자료들은 좀 고쳐둘까해서요~

  • profile

    굉장히 많고 광범위합니다. 제가 디버그 켜고 잡아보려고 올린 질문만 해도....

    대표적으로  in_array, count, new stdClass(); 이것 말고도 종류가 엄청 많습니다.

  • profile ?
    답변 감사합니다 ^^
  • ? profile
    아 한가지 더 스킨 제작자분들이 굉장히 많이 실수 한거 '' 홀따옴표 빼먹은거 엄청 많습니다.
  • profile ?
    제가 아직 php8 로 안 올려봐서

    '' 를 빼먹는다는게...
    변수 전달할때 문자열(string) 변수명 '' 를 써야하는데 안 쓴다는 의미인가요?

    $args->title = '제목'; 이렇게 해야하는걸 $args->title = 제목; 이렇게 했다는건가요?
  • ? profile

    $document->getRegdate(YmdHi)

     

    이런식으로 스킨 제작하신 분들은 나머지도 대부분 다 빼먹으셨더라구요.

  • profile ?
    아.. 함수 사용할때..
    인자값이 문자열인 경우 '문자열' 이렇게 반드시 해야한다는거군요. 숫자형은 아마도 괜찮을테고

    기존에는 문자열에 '' 를 안 써도 오류가 안 났었나봐요?
    이때까지 문자열에 '' 안 쓰면 원래 오류나는 줄 알고 있었거든요..
  • ? profile
    함수밑 변수의 value 값넣을때도 안넣는 경우가 많더군요..
  • ? profile
    예전에도 E_WARNING이 떴는데... XE에서는 그게 보이지 않습니다. ㅎㅎ
  • profile

    가장 흔히 보이는 오류는 아래의 2가지입니다.

     

    $args = new stdClass(); 라고 먼저 선언하지 않고

    $args->document_srl = 1234; 이런 식으로 오브젝트 문법을 사용하려고 시도하는 것

    (null로 초기화하는 등, $args가 오브젝트가 아닌 경우 포함)

     

    count(), in_array() 등 배열을 넣어야 하는 함수에

    빈 문자열, null, 오브젝트 등 배열이 아닌 것을 넣고 뭔가 결과가 나오기를 기대하는 것

    (특히 count가 심각합니다. 이걸 !empty라는 의미로 사용한 사례가 많아서요.)

     

    즉, 오브젝트와 배열에 한해서 타입 검사가 대폭 강화된 것 같습니다.

    문자열에 숫자가 들어 있으면 숫자로 취급할 수 있다거나, 이런 건 20년 전이나 지금이나 똑같고요.

     

    그 밖에도 존재하지 않는 배열 키에 접근하려고 한다거나, 초기화되지 않은 변수를 참조하면

    E_WARNING이 발생하는데, 이건 현 시점에서 치명적인 오류는 아닙니다.

  • profile ?

    1) $args = new stdClass(); 이건 저도 거의 모든 자료가 다 이걸 빼고 했는데
    심지어 새로 선언하기 귀찮아서 일부로 $args_new, $args_document 이렇게 바꿔쓰면서...
    그래도 전 그나마 거의 대부분의 변수를 $args_ 형태로 써서..
    $args 로 검색해서 앞에다가 추가하기만 하면 되겠네요.


    2)
    뭐 XE 자체에서 executeQuery 와 executeQueryArray 를
    executeQueryArray  는 배열형태로 원래 리턴한다는 의미였고
    executeQuery  는  그냥 단일 출력값이라는 전제로 ( 보통 count , exist , 단일문서확인할때 ) 썼는데
    ( 물론 XE 에서 이 두개가 이상하게 혼용되어 에러도 안 내고.. 어느 경우도 그냥 작동은 했었는데 )

    보통 count 를 count($output->data) 형태로 쓸때 값이 있으면 괜찮은데,
    query 의 결과값이 없어서, 즉 $output->data 에 값이 없는 경우.. 오류가 나버린다는거죠?

    흔히 query 의 결과값이 있는지 확인하려고 count 를 많이 쓸텐데
    그럼 이걸 추후에는 어떻게 대체를 해야하는건가요?


    3) in_array 는  php7 기준으로는
    첫번째가 mixed, 두번째 인자가 array 잖아요
    첫번째는 mixed 니까 어느 형태든 상관이 없다는거고, 뒤의 인자만 array 면 되었던건데
    이게 php8 에서 어떻게 변했다는건가요? ( 아니면 기존 제작자들이 어떤 실수를 주로 한건가요? )


    ps. XE Core 자체도 이 문제들이 그대로 다 있으니
    php8 대응은 무조건 라이믹스 기반에서 테스트를 할 수 밖에 없겠네요
    이게 한번 해보고 익숙해지면 XE 자체를 php8 버전으로 고쳐보긴해야겠네요.. (혹시나를 대비해 )

  • ? profile

    그냥 값이 있는지 확인하려면 if($output->data) 하기만 해도 충분합니다.
    executeQuery, executeQueryArray 둘 다 통합니다.
    값이 없으면(null) 거짓이고, 빈 배열이어도 거짓으로 나오니까요.

     

    값이 있는지 확인하고 갯수까지 확인하고 싶다면
    executeQueryArray 한정으로 if($output->data && count($output->data))

    executeQuery는 오브젝트가 나올 수도 있으므로 안 통합니다.

     

    라이믹스에서는 배열이든 오브젝트든 가리지 않고 무조건 예전 방식으로 카운트해주는

    countobj 함수를 추가하여 애매한 경우에 활용하고 있습니다.

     

    in_array는 두 번째 인자가 배열이어야 하는데 배열이 아닌 것이 들어가도 예전에는 봐줬습니다.
    이런 경우는 대부분 아래와 같은 패턴입니다.

        foreach($document_list as $document) {

            if(문서가 어떤 조건에 맞으면) {

                $list[] = $document->document_srl;  // $list를 초기화한 적이 없습니다.

            }

        }

    조건에 맞는 문서가 있다면 괜찮겠지만, 만약 조건에 맞는 문서가 하나도 없다면

        if(in_array($document_srl, $list))

    이런 소스를 썼을 때 $list가 null이니까 에러를 뿜겠지요.

  • profile ?

    foreach 돌렸는데 우연히도 $list 값이 하나도 없을때 발생할 수 있겠군요
    결국 배열 사용할거면 그냥 왠만하면 앞쪽에 $list = array(); 로 선언을 해주는게 좋다는거네요

    php 가 변수형 선언 안 해도 알아서 배정되고, mixed 도 많이 허용되고
    그러면서 처음에 초기화나 선언을 안 해줘도 알아서 다 되던게 장점이라면 장점이였는데
    php7.1 에서 함수 변수인자값 전달이 부족하면 에러난것처럼.. 점점 이런게 엄격해지네요

    stdClass() 선언도 그렇고,  이런 배열선언도 그렇고..
    편의성을 줬던 걸 뒤늦게 빼앗아버리니 ( 물론 이유가 있는거겠지만 ) 좀.. 불편은 하네요 ^^;;

  • ? profile
    이게 몇 년에 걸쳐서 서서히 바뀌는 중인데
    E_WARNING을 숨겨버리니 미리 대비할 수가 없어서 갑작스럽게 느껴지죠...