이 문제를 쉽게 해결할 수 있는 방법이 있나요?아니면 레거시 코드를 모두 다시 써야 하나요?
PHP 치명적 오류: 참조별 호출 시간이 제거되었습니다…30호선
이것은 변수가 코드 전체에 걸쳐 참조로 함수에 전달될 때 어디에서나 발생합니다.
질문에 대한 답변
함수 정의에서는 실제 콜이 아닌 참조로 콜을 나타내야 합니다.PHP가 버전 5.3에서 디프리퍼런스 에러를 표시하기 시작했기 때문에 코드를 다시 쓰는 것이 좋다고 생각합니다.
매뉴얼에서 다음 항목을 참조하십시오.
함수 호출에는 참조 기호가 없습니다. 함수 정의에만 해당됩니다.함수 정의만으로도 인수를 참조로 올바르게 전달할 수 있습니다.PHP 5.3.0에서, 사용 시 “call-time pass-by-reference”가 권장되지 않는다는 경고가 표시됩니다.
&
에foo(&$a);
.
예를 들어, 다음을 사용하는 대신:
// Wrong way! myFunc(&$arg);
# Deprecated pass-by-reference argument function myFunc($arg) { }
용도:
// Right way! myFunc($var);
# pass-by-value argument function myFunc(&$arg) { }
저처럼 대규모 레거시 프로젝트를 5.6으로 업데이트해야 하기 때문에 이 글을 읽으시는 분은 여기 답변에서 지적한 바와 같이 빠른 해결책은 없습니다. 문제가 발생할 때마다 수동으로 찾아서 수정해야 합니다.
프로젝트 내에서 문제가 있는 모든 라인을 찾는 가장 편리한 방법은 (매우 정확하지만 에디터에서 올바른 위치로 바로 이동하는 완전한 정적 코드 분석기를 사용하는 것 이외) Visual Studio Code와 검색을 허용하는 검색 기능을 사용하는 것입니다.Regex. (물론 PHP 보풀링 및 Regex 검색을 수행하는 IDE/Code Editor를 사용할 수 있습니다.)
이 정규식 사용:
^(?!.*function).*(&$)
프로젝트 전체를 검색하여 발생 여부를 확인할 수 있습니다.&$
함수 정의가 아닌 행에서만 사용할 수 있습니다.
이것은 여전히 많은 잘못된 긍정이 발견되지만, 작업을 더 쉽게 만듭니다.
VSCode의 검색 결과 브라우저를 사용하면 문제 행을 쉽게 찾을 수 있습니다. 각 결과를 클릭하면 해당 검색 결과가 빨간색으로 표시되어 있는지 확인할 수 있습니다.고쳐야 할 것들.
PHP 및 참조는 다소 의도적이지 않습니다.적절한 장소에서 참조를 적절히 사용하면 퍼포먼스가 대폭 향상되거나 매우 추악한 회피책이나 비정상적인 코드를 회피할 수 있습니다.
다음과 같이 에러가 발생합니다.
function f(&$v){$v = true;}
f(&$v);
function f($v){$v = true;}
f(&$v);
아래 규칙을 따를 수 있지만 많은 레거시 혼란을 방지하기 위해 제거 또는 비활성화되었으므로 이들 중 어느 것도 실패할 필요가 없습니다.
정상적으로 동작하는 경우는, 양쪽 모두 참조로의 용장 변환이 필요하게 됩니다.또한 두 번째 변환은 범위가 포함되는 변수로의 용장 변환도 필요하게 됩니다.
두 번째 방법은 참조와 함께 작동하도록 의도되지 않은 코드에 참조를 전달할 수 있도록 하는 것이 가능했습니다.이것은 유지보수가능성에 있어서 매우 추악합니다.
이렇게 하면 아무 것도 할 수 없습니다.
function f($v){$v = true;}
$r = &$v;
f($r);
더 구체적으로 말하면, 참조를 요청하지 않았기 때문에 참조가 다시 정규 변수로 바뀝니다.
이 조작은 유효합니다.
function f(&$v){$v = true;}
f($v);
그러면 참조를 전달하고 있지만 참조가 필요하므로 참조로 변환됩니다.
즉, 참조를 명시적으로 요구하지 않는 함수에 참조를 전달할 수 없습니다.이 함수는 PHP가 전달 타입에 엄격한 몇 안 되는 영역 중 하나이며, 이 경우 메타 타입에 가깝습니다.
보다 동적인 동작이 필요한 경우, 다음과 같이 동작합니다.
function f(&$v){$v = true;}
$v = array(false,false,false);
$r = &$v[1];
f($r);
여기에 참조가 필요한 것으로 표시되고 이미 참조가 있으므로 그대로 둡니다.그것은 또한 참조를 묶을 수도 있지만 나는 이것이 의심스럽다.