2011-01-12 3 views
11

PHP 5.3에서는 참조로 반환 값을 deprecated으로 지정했습니다. 따라서PHP 5.3 및 참조로 new의 반환 값을 할당

$obj =& new Foo(); 

은 이제 E_DEPRECATED 오류를 발생시킵니다.

레거시 코드가 많은 대형 응용 프로그램을 5.3으로 업그레이드하면 원치 않는 고지가 많이 생깁니다.

이 문제의 잠재적 인 해결책으로 정규 표현식을 사용하여 =& new의 모든 인스턴스를 찾고 = new으로 대체하는 것이 좋습니다. 예를 들어, 다음은 모든 PHP 파일을 찾아 =& new의 모든 인스턴스 쓸어됩니다

find ./ -name '*.php' | xargs perl -p -i -e 's/=(\s*)&(\s*)?new\b/= new/g' 

다음과 같은 질문에 대한 답을 찾는 상대 :

  1. 는 그냥 잘 작동을? 어떤 잠재적 인 문제가 발생할 수 있습니까?
  2. 그렇지 않은 경우 코드 예로 을 = new으로 바꾸면 PHP 5.3에서 동작이 변경됩니다.
  3. 이 경우 널리 사용되는 라이브러리의 예는 문제를 일으키는 것으로 알려져 있습니다.
  4. 방대한 양의 =& new을 수정하는 데 다른 어떤 아이디어를 권하고 싶습니까?

이것이 정상적으로 작동하지만 문제가 될 수있는 가장자리의 경우를 찾고 있습니다. 예, 오류보고 설정을 변경할 수 있음을 알고 있습니다. 그러나 나는 그 고지들을 숨기고 싶지 않다. 나는 고쳐주고 싶다.

+0

E_DEPRECATED는 오류가 아닌 통지 클래스에 속합니다. 나는 그것을 고치려고 서두를 필요가 있는지 확신하지 못한다. (magic_quotes는 PHP 4.2에서 deprecated로 선언되었거나 그렇게 선언되었다.) 정규 표현식에 관해서는 :'new' 다음에'\ b'를 추가해야합니다. 그렇지 않으면 실행 가능한 재 작성 접근법입니다. 그러나 예상되는 처리 논리를 손상시키는 경우에만 테스트 할 수 있습니다 (거의 없습니다). – mario

+0

@mario E_DEPRECATED는 단지 오류입니다 * 수준 *. 어느 쪽이든 그것을 참조하는 것이 적절할 것입니다. \ b와 좋은 점. – mfonda

답변

14

귀하의 느낌이 옳습니다. 일반적으로 정상적으로 작동하지만 가장자리가없는 경우가 있습니다. =&를 사용

= 이러한 차이가 있습니다

  • =& 것은 오른쪽이 참조를 얻을 수 있도록 노력하겠습니다을; =은 오른쪽 측면이 참조를 반환 할 수 있다고하더라도 참조로 반환하는 함수와 같습니다.
  • =&은 기존 레퍼런스 세트를 깨고 왼쪽과 오른쪽을 모두 새 것으로 두는 반면 =은 왼쪽과 동일한 참조 세트의 모든 요소 값을 오른쪽의 값으로 변경합니다 .

첫 번째 차이점과 두 번째 의견의 절반은이 경우에 부적합합니다. 할당 후에는 새 객체 *의 값이있는 단 하나의 변수 만 존재하며 단일 요소 참조 집합은 의미가 없습니다. 그러나 =& 휴식 이전 참조 설정하는 것이 사실은 중요하다 :

<?php 

$g = 4; 
$v =& $g; 
$v = new stdclass(); 
var_dump($g); // object(stdClass)#1 (0) { } 

$g = 4; 
$v =& $g; 
$v =& new stdclass(); 
var_dump($g); // int(4) 

* 어쩌면 생성자 참조 누수하지만 누수 경우에도, 생성자 내부 $this가 가리키는 경우에도, 다른 변수가 될 수 있습니다하지 않는 한 같은 대상으로. 그래서 저는 이것으로 인해 행동 차이를 관찰 할 수 있을지 의심 스럽습니다.

+4

+1은 오래된 참조의 파손을 보여줍니다. 그러나 오타는'= &'이 아니라'& ='이되어야합니다. – Jonah

+0

@Jonah 고침, 고마워! – Artefacto

+0

와우, 멋진 것들. 차이가 있다고 생각하지 않았을 것입니다. +1 – NikiC

3

예, =& new= new으로 바꿀 수 있습니다. 객체는 기본적으로 PHP 5.3에서 참조로 전달되므로 아무런 동작이 변경되지 않습니다.

+1 고지를 숨기지 않고 고치기위한 것입니다.

+0

+1 (의무적 인 "참조로 전달 된 참조 값, 참조로 전달 된 객체가 아닙니다"여기에 보행자가 표시됩니다.) – BoltClock

+0

+1 빨리 배우고 있습니다. – Ish

+0

-1 부적절하고 관련성이 없습니다. 그들은 서로 교환 할 수 없으며 아무도 참조 또는 값으로 아무것도 (생성자 인수 제외)를 전달하지 않습니다 ... – Artefacto

2

아무런 문제가 없어야합니다. 최악의 경우 PHP 4에서 애플리케이션의 속도가 약간 느려지지만 기능이 변경되지는 않습니다.

이론적으로 문제가 될 수있는 유일한 문제는 누군가가 =& new을 문자열에 썼다는 것입니다. 알아 두어야 할 것은 매우 희박하지만, 실제로 모든 경우를 '=' T_WHITESPACE? '&' T_WHITESPACE? T_NEW으로 바꾸려면 Tokenizer을 사용해야합니다.

+0

물론, 그게 좋은 일일 수 있습니다. 누군가가 주석에서 일부 코드의 "예제 사용"을 가졌다면 정규식은 예제 사용법을 수정합니다. 하지만하지 말아야 할 일의 예가 있다면 나쁜 것이라고 생각합니다 :-) – mfonda

+0

그들은 같은 것이 아닙니다. 좋은 점은'= & new'가 문자열에 나타나는 것입니다. – Artefacto

관련 문제