기존 코드베이스를 PHP 8.1로 업데이트: Null 값을 사용하여 Null을 허용하지 않는 내부 함수 매개변수 처리
P粉344355715
P粉344355715 2023-10-31 20:01:48
0
2
812

저는 PHP 8.1과 호환되도록 코드를 업그레이드하기 시작했습니다. 잠재적인 null 값을 내부 함수에 전달하는 코드 조각이 많이 있습니다.

으아악

$row는 null 값을 가질 수 있는 소스(예: 쿼리)에서 나옵니다. 다음과 같은 경우 지원 중단 경고가 생성될 수 있습니다.

지원 중단: strlen(): 문자열 유형의 매개변수 #1에 null을 전달하는 것은 더 이상 사용되지 않습니다($string)

전역 검색 및 바꾸기가 수행될 수 있는 위치를 수정하는 등 이 코드 업그레이드를 처리하는 가장 쉽고 시간 효율적인 방법을 찾고 있습니다. 기능을 변경하지 않고 내부 함수에 전달한 변수를 타입캐스트하는 것 같습니다.

으아악

이러한 방식으로 인코딩하는 도덕적 측면을 제외하고 이 내부 기능 접근 방식에 문제가 있습니까? (코드를 완전히 다시 작성하고 null 값을 다르게 처리하는 것 외에) 더 좋은 방법이 있습니까? 나는 이 솔루션이 v7.4와 역호환되는 것을 선호하지만 아마도 8.0과도 호환될 것입니다.

사용자 정의 함수에 다른 옵션이 있다는 것을 알고 있습니다.

P粉344355715
P粉344355715

모든 응답(2)
P粉436410586

"이 코드 업그레이드를 처리하는 가장 쉽고 시간 효율적인 방법"에 대한 질문에 답하세요.

간단히 말하면 할 수 없습니다.


먼저, 배경지식...

15%의 개발자가 strict_types=1을 사용하므로 귀하는 사용하지 않는 대다수에 속합니다.

당신은 지금 이 문제를 무시할 수 있지만(더 이상 사용되지 않음) PHP 9.0은 치명적인 유형 오류를 만들어 많은 문제를 일으킬 것입니다.

하지만 여전히 NULL 연결 문자열을 사용할 수 있습니다:

으아아아

NULL을 빈 문자열과 비교할 수 있습니다.

으아아아

그리고 계산에 NULL을 사용할 수도 있습니다(여전히 0으로 처리됩니다):

으아아아

여전히 NULL을 인쇄/에코할 수 있습니다:

으아아아

NULL을

에 전달하여 sprintf() 中,并使用 %s처럼 빈 문자열로 강제 변환할 수 있습니다. 으아아아

(규칙에 따라)

와 같은 다른 값을 강제로 적용할 수 있습니다. 으아아아

NULL 강제는 그 이후로 이런 식으로 작동했습니다. 처음부터 가정하고 문서에도 나와 있습니다.


어쨌든 고치려면...

첫 번째 부분에서는 업데이트해야 하는 코드를 찾으려고 시도합니다.

이러한 함수 인수 중 하나에 NULL

을 전달할 수 있을 때마다 이런 일이 발생합니다.

이로 인해 영향을 받는 최소

335 매개변수가 있습니다.

추가

104가 있는데 약간 비린내가 나고 558에 NULL에 문제가 있습니다 . define(NULL, '值')Psalm

은 이에 도움이 되는 유일한 도구입니다.

시편은 매우 높은 검사 수준(1, 2 또는 3)에 있어야 합니다.

그리고 문제를 무시하기 위해 기준선을 사용할 수 없습니다(개발자가 기존 프로젝트에 정적 분석을 도입하여 신규/편집된 코드만 확인하는 기술).

이전에 정적 분석 도구를 사용해 본 적이 없다면(걱정하지 마세요. 33%의 개발자가 이 도구를 사용하는 것이 좋습니다) 코드를 수정하는 데 많은 시간이 소요될 것으로 예상됩니다(가장 느슨한 레벨 8에서 시작). , 그리고 당신의 길을 가십시오).

PHPStan, Rector, PHP CodeSniffer, PHP CS Fixer 또는 PHPCompatibility를 사용하여 이러한 문제를 찾을 수 없습니다(Source).


각 질문을 찾은 후 두 번째 부분은 편집입니다.

문제가 발생할 가능성이 가장 적은 곳은

와 같이 싱크대를 교체하는 것입니다. 으아악

또는 변수의 소스를 다시 추적하여 처음부터 변수가 NULL로 설정되는 것을 방지할 수 있습니다.

다음은 NULL의 매우 일반적인 소스입니다.

으아악

이러한 함수 중 일부는 기본값을 지정하기 위해 두 번째 인수가 필요합니다. 또는 strval()...但要小心,您的代码可能会通过 ($a === NULL)를 미리 사용할 수 있으며 이를 중단하고 싶지는 않습니다.

많은 개발자는 일부 변수에 NULL이 포함될 수 있다는 사실을 인식하지 못합니다. 예를 들어 네트워크 문제, 브라우저 확장, 브라우저에서 DOM/URL을 편집하는 사용자 등으로 인해 (자신이 만든) 모든 입력 필드가 항상 제출될 것으로 예상합니다. . 이런 일은 일어나지 않을 수도 있습니다.


저는 일년 내내 이 문제를 해결하기 위해 노력해 왔습니다.

저는 이 문제를 해결하기 위해 두 개의 RFC를 작성하기 시작했습니다. 첫 번째는 NULL을 허용하도록 일부 기능을 업데이트하는 것입니다(엄격한 유형을 사용하는 개발자를 화나게 하기 때문에 이상적이지는 않습니다).

두 번째 RFC는 이 경우 NULL이 계속 적용되도록 허용하는 것입니다..... 하지만 저는 그렇게 하지 않았습니다. 방금 부정적인 피드백을 많이 받았기 때문에 투표에 올리지 마세요. 앞으로 이 문제를 해결할 수 없는 이유를 설명하기 위해 거부가 인용되는 것을 원하지 않습니다(원래 변경 사항은 거의 논의되지 않았습니다, 이 하나) .

NULL은 "스칼라 값"으로 처리되지 않기 때문에 다르게 처리되는 것 같습니다. 많은 개발자가 이러한 구분에 관심을 두지 않는 것 같지만 가끔 나타나는 경우도 있습니다.

저와 함께 일한 대부분의 개발자는 이 문제를 무시합니다(나중에 수정하기를 바라지만 이는 아마도 최선의 아이디어는 아닐 것입니다). 으아악

하려고 노력하는 팀이 있습니다. 그러나 1년 이상이 지난 후에도 여전히 문제가 발생하고 있습니다(8.1 알파 1로 테스트 중이라고 합니다).

strval() 应用于所有事情,例如修剪(strval($search))제가 고려하고 있는 또 다른 옵션은 ~335개의 함수를 네임스페이스에서 nullable로 재정의하는 라이브러리를 만드는 것입니다.으아아아

그런 다음 개발자는 라이브러리를 포함하고 네임스페이스 자체를 사용합니다.

으아아아
P粉087074897

명시적으로 처리하려고 null 的情况,那么稍微干净一点的修复方法是 strlen($row ?? '')하려는 경우 "null 병합 연산자"를 사용하세요.

대부분의 경우 둘은 동일하지만 strict_types=1를 사용하면 값이 문자열로 변환될 수 있는 다른 유형인 경우 다르게 동작합니다.

으아아아

반면에 ?? 运算符基于 isset,而不是 === null 변수와 undefine 변수는 다르게 동작한다는 점에 유의하세요.

으아아아

이 경우에 관심이 있다면 이전 동작과 가장 직접적으로 동등한 것은 훨씬 더 장황합니다.

으아아아
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿