PHP 참조 개념
인용은 무엇입니까?
PHP에서 참조하는 것은 같은 변수 내용에 다른 이름으로 액세스하는 것을 의미합니다.이것은 C 포인터가 아닙니다. 저장된 것은 메모리 주소가 아니므로 포인터 연산을 할 수 없습니다.인용은 기호표의 별명일 뿐이다.Unix 시스템의 하드 링크와 같이 Windows 시스템의 바로 가기입니다.
위쪽은 공식 수첩의 원문인데 뭐랄까, 인용은 사실 우리가 기억하는 C 안의 지침과 같은 개념이 아니다.지침은 실제 메모리에 대한 조작이고, 인용은 이 메모리를 가리키는 기호표에 대한 조작이다.아니면 운영체제의 바로 가기에서 볼 때 바로 가기는 삭제할 수 있는데 이것이 바로 PHP의 인용이다.그리고 C는 단축키를 삭제했을 뿐만 아니라 원본도 삭제했다. 이것이 바로 C의 지침 조작이다.
//
$a = 1;
$b = &$a;
echo $a, '===', $b, PHP_EOL;
unset($b);
echo $a, '===', $b, PHP_EOL;
위의 코드는 PHP에서 우리는 b변수를 b변수로 가리키며 a의 인용변수로 한다.그리고 a의 인용 변수를 삭제합니다.그리고 b를 삭제합니다. $a에는 아무런 영향이 없습니다.
#include <stdio.h>
#include <stdlib.h>
int main()
{
// C
int a = 1;
int* b = &a;
printf("%i
", a); // 1
free(b); // free b
printf("%i
", a); //get error: *** error for object 0x7fff6350da08: pointer being freed was not allocated
return 0;
}
그리고 C의 인용 바늘은 안 됩니다. 우리가 b변수를 삭제한 후에 a변수를 인쇄하면 바로 오류를 보고합니다.PHP의 밑바닥도 C가 썼다고 하지만 우리는 C의 바늘이 변태라는 것을 알고 있다. 일정한 기초가 없으면 틀리기 쉽다.그래서 PHP 개발자들은 C의 원시 포인터 능력을 노출하지 않고 자바와 같은 유사한 인용 능력을 채택했다.이것도 현대 언어의 특성이다. 우리가 지나치게 밑바닥의 능력에 관심을 가지지 않고 업무 실현에 더 많은 시간을 기울일 필요가 없다.
그룹과 대상에 인용된 사용
인용이 있는 그룹이 복사되면 그 값은 인용을 해제하지 않습니다.수조 전치 함수에 대해서도 마찬가지다.
$arr1 = ["a", "b"];
$t1 = &$arr1[1];
$arr2 = $arr1;
$arr2[1] = "c";
var_dump($arr1);
// array(2) {
// [0]=>
// string(1) "a"
// [1]=>
// &string(1) "c"
// }
$arr1 = ["a", "b"];
$t1 = &$arr1[1];
unset($t1); // unset
$arr2 = $arr1;
$arr2[1] = "c";
var_dump($arr1);
// array(2) {
// [0]=>
// string(1) "a"
// [1]=>
// string(1) "b"
// }
이것은 사실 매우 재미있다. 우리는 이 두 가지 예를 비교해 보면 하나의 문제를 알 수 있다. t변수는 t변수가arr[1]를 가리키는 인용을 가리킨다.arr2직접=이arr2직접=이arr1은 인용을 사용하지 않았습니다. 그리고arr2는arr2[1]의 내용을 수정했습니다. arr1에 해당하는 내용도 바뀌었습니다. 만약unset이arr1에 해당하는 내용도 바뀌었고 만약unset가 t 변수를 바꾸면 $arr1에 해당하는 내용도 바뀌지 않습니다.이에 대해 문서에서 다음 설명을 찾았습니다.PHP 내부 작업의 특수성 때문에 그룹의 단일 요소를 인용한 다음에 그룹을 복사하면 값을 부여하든 함수 호출 중의 값을 통해 전달하든 인용을 그룹의 일부로 복사합니다.이것은 모든 수조에 대한 이러한 요소의 변경이 다른 수조 (다른 인용 중) 에서 중복된다는 것을 의미한다. 설령 수조가 서로 다른 작용역을 가지고 있다 하더라도. (예를 들어 하나는 함수 내부의 매개 변수이고, 다른 하나는 전체적인 것이다.)복사할 때 인용되지 않은 원소와 수조를 복사한 후에 다른 원소에 분배된 인용은 정상적으로 작동합니다 (즉 다른 수조와 독립적).
수조뿐만 아니라 대상의 인용에도 재미있는 문제가 있을 수 있다.
$o1 = new stdClass();
$o1->a = 'a';
var_dump($o1);
// object(stdClass)#1 (1) {
// ["a"]=>
// string(1) "a"
// }
$o2 = &$o1;
$o3 = $o1;
$o2->a = 'aa';
var_dump($o1);
// object(stdClass)#1 (1) {
// ["a"]=>
// string(2) "aa"
// }
var_dump($o3); // $o2 $a 'aa',$o3 'aa'
// object(stdClass)#1 (1) {
// ["a"]=>
// string(2) "aa"
// }
$o1->a = 'aaa';
$o1 = null;
var_dump($o2); // $o2 null
// NULL
var_dump($o3); // $o3 , $a 'aaa'
// object(stdClass)#1 (1) {
// ["a"]=>
// string(3) "aaa"
// }
상기 예에는 세 가지 대상이 있는데 o1, o1, o2, o3이다. 그 중에서 o3, 그 중에서 o2는 o1에 대한 인용이고 o1의 인용이며 o3은 직접 부여된 값이 o1이다.맞다o2 속성에 대한 조작은 o1에 반영될 뿐만 아니라 o1에도 반영될 뿐만 아니라 o3에도 반영될 것이다.사실 우리가 전에 전문적으로 한 문장에서 말한 이 문제는 우선 대상의 기본 값이 인용이고 그 다음에 이 예는 인용이 하나의 기호표의 귀속임을 잘 증명했다.단축키를 삭제해도 원래 객체와 다른 단축키에는 아무런 영향이 없습니다.참조된 전달
인용이 방법 매개 변수에 전달되는 데 있어서 가장 중요한 것은 두 가지를 기억하는 것이다. 첫째, 방법 내부에서 변수를 수정하면 외부도 변한다. 이것은 인용의 특성이잖아.둘째, 변수, New 문장, 함수에서 되돌아오는 인용 세 가지 유형만 전달할 수 있다.
error_reporting(E_ALL);
function foo(&$var)
{
$var++;
echo 'foo:', $var;
}
function bar() // Note the missing &
{
$a = 5;
return $a;
}
foo(bar()); // PHP 5.0.5 , PHP 5.1.1
// PHP 7.0 notice ,Notice: Only variables should be passed by reference
foo($a = 5); // , , Notice: Only variables should be passed by reference
// foo(5); // !5 !
///////////////////////////////
//
$a = 5;
foo($a); //
function &baz()
{
$a = 5;
return $a;
}
foo(baz()); //
function foo1(&$var)
{
print_r($var);
}
foo1(new stdClass()); // new
참조된 반환
인용의 귀환은 결코 자주 사용하는 능력이 아니다.문서의 원문은 되돌아오는 인용으로 성능을 높이지 말고 엔진이 충분히 똑똑해서 스스로 최적화해야 한다는 것이다.합리적인 기술적 원인이 있을 때만 인용을 되돌려줍니다!
$a = 1;
function &test(){
global $a;
return $a;
}
$b = &test($a);
$b = 2;
echo $a, PHP_EOL;
인용 변수를 되돌려 주고 싶을 때, 방법 정의와 방법 호출을 할 때 & 기호를 사용해야 합니다.이것은 주의해야 할 점이다.다른 곳에서 원래의 변수 값을 수정하거나 되돌아오는 변수 값이 수정되면 이 값을 호출하는 모든 곳에 영향을 줍니다.따라서 인용된 반환은 비교적 위험하다. 언제 어디서 이 값이 수정되었는지 잘 모르기 때문에 버그에 대한 조사는 매우 어려울 것이다.참조의 취소
인용을 취소하는 것은 사실 변수를 바로 unset하면 된다.그러나 반드시 기억해야 할 것은 PHP의 인용은 가리키는 기호표로 원시의 실제 값에 작용하지 않기 때문에 unset이 가장 원시적인 그 변수를 떨어뜨려도 다른 인용에 부여된 변수에 영향을 주지 않는다!!
$a = 1;
$b = &$a;
$c = &$b;
$b = 2;
echo ' :', $a, '===', $b, '===', $c, PHP_EOL;
unset($b);
$b = 3;
echo ' $b , $a、$c:', $a, '===', $b, '===', $c, PHP_EOL;
$b = &$a;
unset($a);
echo ' $a, $b、$c:', $a, '===', $b, '===', $c, PHP_EOL;
// :2===2===2
// $b :2===3===2
// $a, $c:===3===2
$a = 1;
$b = & $a;
$c = & $b; // $a, $b, $c reference the same content '1'
$a = NULL; // All variables $a, $b or $c are unset
echo ' :', $a, '===', $b, '===', $c, PHP_EOL;
총결산
이번에는 비교적 철저하게 인용을 철저히 한 셈이다.PHP에 대한 인용은 그 정의만 기억하면 이해하기 쉽다. 가장 직관적인 것은 운영체제의 단축방식이라고 생각하면 된다. 우리가 생각했던 것처럼 그렇게 어렵지 않다. C의 바늘에 비해 정말 인형급이다. 연습을 많이 하고 복습을 많이 하면 자연히 사용을 잘 파악할 수 있다.
테스트 코드:github.com/zhangyue050…
이상은 PHP에서 인용한 개념의 상세한 내용입니다. PHP 인용에 관한 더 많은 자료는 저희 다른 관련 글을 주목해 주십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
laravel에 yo에서 angularJs&coffeescript를 사용할 수 있도록 한다.먼저 yo 명령을 사용할 수 있어야하므로 아래에서 설치 global에 설치한 곳에서 laravel의 프로젝트 루트로 이동. 클라이언트 코드를 관리하는 디렉토리를 만들고 이동합니다. 클라이언트 환경 만들기 이것으로 히...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.