PHP 변수는 값으로 전달됩니까, 참조로 전달됩니까?
PHP 변수는 값으로 전달됩니까, 참조로 전달됩니까?
PHP 설명서에 따른 값입니다.
기본적으로는 함수 인수는 값으로 전달됩니다(함수 내 인수 값이 변경되어도 함수 외부에서는 변경되지 않습니다).함수가 인수를 수정할 수 있도록 하려면 해당 인수를 참조로 전달해야 합니다.
항상 참조에 의해 전달되는 함수에 대한 인수를 가지려면 함수 정의의 인수 이름에 앰퍼샌드(&)를 추가합니다.
<?php
function add_some_extra(&$string)
{
$string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str; // outputs 'This is a string, and something extra.'
?>
PHP에서는 기본적으로 개체가 새 개체에 대한 참조로 전달됩니다.
다음의 예를 참조해 주세요.
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue($obj)
{
$obj->abc = 30;
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 30
자, 이걸 보세요.
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue($obj)
{
$obj = new Y();
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 10 not 20 same as java does.
자, 이걸 보세요.
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue(&$obj)
{
$obj = new Y();
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 20 not possible in java.
이해해주셨으면 좋겠습니다.
많은 사람들이 사물이 함수에 전달되는 방식과 참조에 의해 전달되는 의미에 대해 혼란스러워 하는 것 같습니다.개체는 여전히 값으로 전달됩니다. PHP5에서 전달되는 값은 참조 핸들입니다.그 증거:
<?php
class Holder {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function getValue() {
return $this->value;
}
}
function swap($x, $y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
출력:
a, b
참조에 의해서 건네지는 것은, 발신자가 인식하는 변수를 변경할 수 있는 것을 의미합니다만, 상기의 코드에서는 분명히 변경할 수 없습니다.스왑 기능을 다음과 같이 변경해야 합니다.
<?php
function swap(&$x, &$y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
출력:
b, a
참조로 통과하기 위해.
http://www.php.net/manual/en/migration5.oop.php
PHP 5에는 새로운 오브젝트 모델이 있습니다.PHP의 객체 처리가 완전히 변경되어 더 나은 성능과 더 많은 기능을 제공합니다.이전 버전의 PHP에서는 개체는 원시 유형(예: 정수 및 문자열)처럼 처리되었습니다.이 메서드의 단점은 변수 할당 시 개체 전체가 의미론적으로 복사되거나 메서드에 매개 변수로 전달된다는 것입니다.새로운 접근법에서는 객체는 값이 아닌 핸들로 참조됩니다(핸들을 객체의 식별자로 생각할 수 있습니다).
PHP 변수는 값에 따라 할당되고, 값에 따라 함수에 전달되며, 개체를 포함/표시할 때 참조에 의해 전달됩니다.&'을 사용하여 변수를 강제로 참조로 전달할 수 있습니다.
값/참조 예에 따라 할당됨:
$var1 = "test";
$var2 = $var1;
$var2 = "new test";
$var3 = &$var2;
$var3 = "final test";
print ("var1: $var1, var2: $var2, var3: $var3);
출력:
var1: 검정, var2: 최종 검정, var3: 최종 검정
값/참조 예에 의해 전달됨:
$var1 = "foo";
$var2 = "bar";
changeThem($var1, $var2);
print "var1: $var1, var2: $var2";
function changeThem($var1, &$var2){
$var1 = "FOO";
$var2 = "BAR";
}
출력:
var1: foo, var2 BAR
참조 예시로 전달된 개체 변수:
class Foo{
public $var1;
function __construct(){
$this->var1 = "foo";
}
public function printFoo(){
print $this->var1;
}
}
$foo = new Foo();
changeFoo($foo);
$foo->printFoo();
function changeFoo($foo){
$foo->var1 = "FOO";
}
출력:
풀
(마지막 예시는 아마 더 나을 것입니다.)
변수를 함수에 참조로 전달할 수 있습니다.이 함수는 원래 변수를 수정할 수 있습니다.
함수 정의에서 참조로 경로를 정의할 수 있습니다.
<?php
function changeValue(&$var)
{
$var++;
}
$result=5;
changeValue($result);
echo $result; // $result is 6 here
?>
어느 쪽이든 상관없습니다.
앞에 '&' 기호를 붙이면 전달되는 변수가 원본과 동일하고 하나가 됩니다. 즉, 복사하지 않고 참조를 통해 전달할 수 있습니다.
그렇게
$fred = 5;
$larry = & $fred;
$larry = 8;
echo $fred;//this will output 8, as larry and fred are now the same reference.
원시 유형을 포함하는 변수는 PHP5에서 값으로 전달됩니다.개체를 포함하는 변수는 참조에 의해 전달됩니다.2006년 Linux Journal에서 4와 5의 차이점 및 기타 OO에 대해 언급한 흥미로운 기사가 있습니다.
http://www.linuxjournal.com/article/9170
TL;DR: PHP는 pass by value와 pass by reference를 모두 지원합니다.참조는 앰퍼샌드를 사용하여 선언됩니다.&
C++의 경우와 매우 유사합니다.함수의 형식 파라미터가 앰퍼샌드로 선언되지 않은 경우(즉, 참조가 아님), 객체를 포함한 모든 것이 값에 의해 전달됩니다.개체와 기본 요소가 전달되는 방식에는 차이가 없습니다.중요한 것은 객체가 함수에 전달될 때 무엇이 전달되는지 이해하는 것입니다.여기서 포인터를 이해하는 것이 매우 중요합니다.
향후에 이것을 접하게 되는 사람을 위해서, 익명의 유저가 투고하고 있는 PHP 문서의 이 보석을 공유하고 싶다.
여기에 뭔가 혼란이 있는 것 같습니다.포인터와 참조의 구별은 특별히 도움이 되지 않습니다.이미 게시된 일부 "포괄적인" 예제의 동작은 보다 단순한 통합 용어로 설명할 수 있습니다.예를 들어 Hayley의 코드는 사용자가 예상해야 할 것과 정확히 일치합니다. (>= 5.3 사용)
첫 번째 원칙:포인터는 오브젝트에 액세스하기 위한 메모리 주소를 격납한다.오브젝트가 할당될 때마다 포인터가 생성됩니다.(아직 Zend 엔진에 대해 자세히 알아보지는 못했지만, 제가 보기엔 이것이 해당됩니다.)
두 번째 원칙이자 가장 혼란스러운 원인: 변수를 함수에 전달하는 것은 기본적으로 값 패스로 수행됩니다. 즉, 복사본을 사용하여 작업합니다."하지만 객체는 참조로 전달됩니다!"여기에서도 Java 세계에서도 흔히 볼 수 있는 오해입니다.난 '무엇'의 복사본이라고.기본 전달은 값에 따라 수행됩니다.항상.그러나 복사되어 전달되는 것은 포인터입니다.「->」를 사용하는 경우는, 발신자 기능의 원래의 변수와 같은 내부 기능에 액세스 할 수 있습니다."="만 사용해도 복사본만 재생됩니다.
세 번째 원칙: &는 다른 변수 이름/메모리를 분리할 때까지 다른 것과 동일한 메모리 주소로 자동으로 영구적으로 설정합니다.여기서 "에일리어스"라는 용어를 사용하는 것이 맞습니다."unset()"로 강제로 분리될 때까지 힙의 두 포인터를 결합하는 것으로 간주합니다.이 기능은 동일한 범위 내에 존재하며 인수가 함수에 전달될 때 모두 존재합니다.C와 C++에서 "값에 의한 전달"과 "기준에 의한 전달"의 특정 차이 때문에 종종 전달된 인수를 "참조"라고 부릅니다.
객체 자체가 아닌 객체에 대한 포인터는 함수에 전달됩니다.이러한 포인터는 파라미터 목록에서 "&"를 사용하여 실제로 원고를 전달하지 않는 한 원본의 복사본입니다.오브젝트의 내부를 파헤칠 때만 원고가 바뀝니다.
다음은 예를 제시하겠습니다.
<?php
//The two are meant to be the same
$a = "Clark Kent"; //a==Clark Kent
$b = &$a; //The two will now share the same fate.
$b="Superman"; // $a=="Superman" too.
echo $a;
echo $a="Clark Kent"; // $b=="Clark Kent" too.
unset($b); // $b divorced from $a
$b="Bizarro";
echo $a; // $a=="Clark Kent" still, since $b is a free agent pointer now.
//The two are NOT meant to be the same.
$c="King";
$d="Pretender to the Throne";
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByValue($c, $d);
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByRef($c, $d);
echo $c."\n"; // $c=="Pretender to the Throne"
echo $d."\n"; // $d=="King"
function swapByValue($x, $y){
$temp=$x;
$x=$y;
$y=$temp;
//All this beautiful work will disappear
//because it was done on COPIES of pointers.
//The originals pointers still point as they did.
}
function swapByRef(&$x, &$y){
$temp=$x;
$x=$y;
$y=$temp;
//Note the parameter list: now we switched 'em REAL good.
}
?>
저는 JavaScript를 위해 이 주제에 대해 광범위하고 상세한 블로그 투고를 작성했습니다만, PHP, C++, 그리고 사람들이 pass by value와 pass by reference에 대해 혼동하고 있는 것 같은 다른 언어에도 동일하게 적용된다고 생각합니다.
분명히 PHP는 C++와 마찬가지로 pass by reference를 지원하는 언어입니다.기본적으로 개체는 값으로 전달됩니다.객체를 저장하는 변수를 사용하는 경우 이러한 변수를 포인터로 보는 것이 좋습니다(어셈블리 수준에서는 기본적으로 이러한 변수이기 때문입니다).값을 기준으로 포인터를 전달해도 포인터를 "추적"하여 가리키는 개체의 속성을 수정할 수 있습니다.다른 오브젝트를 가리키도록 할 수 없습니다.파라미터가 참조에 의해 전달되었다고 명시적으로 선언한 경우에만 이 작업을 수행할 수 있습니다.
개체는 PHP 5에서는 참조로 전달되고 PHP 4에서는 값으로 전달됩니다. 변수는 기본적으로 값으로 전달됩니다!
여기: http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html
class Holder
{
private $value;
public function __construct( $value )
{
$this->value = $value;
}
public function getValue()
{
return $this->value;
}
public function setValue( $value )
{
return $this->value = $value;
}
}
class Swap
{
public function SwapObjects( Holder $x, Holder $y )
{
$tmp = $x;
$x = $y;
$y = $tmp;
}
public function SwapValues( Holder $x, Holder $y )
{
$tmp = $x->getValue();
$x->setValue($y->getValue());
$y->setValue($tmp);
}
}
$a1 = new Holder('a');
$b1 = new Holder('b');
$a2 = new Holder('a');
$b2 = new Holder('b');
Swap::SwapValues($a1, $b1);
Swap::SwapObjects($a2, $b2);
echo 'SwapValues: ' . $a2->getValue() . ", " . $b2->getValue() . "<br>";
echo 'SwapObjects: ' . $a1->getValue() . ", " . $b1->getValue() . "<br>";
속성은 참조에 의해 전달되지 않은 경우에도 수정할 수 있으므로 주의하시기 바랍니다.
출력:
Swap Objects: b, Swap Values: a, b
오브젝트가 함수에 전달되는 방법에 대해서는 "&"가 없으면 오브젝트 핸들, 값으로 전달되는 오브젝트 핸들, 포인터의 값을 포함하는 오브젝트 핸들이라는 점을 이해해 둘 필요가 있습니다.단, 이 포인터는 "&"를 사용하여 참조로 전달할 때까지 변경할 수 없습니다.
<?php
class Example
{
public $value;
}
function test1($x)
{
//let's say $x is 0x34313131
$x->value = 1; //will reflect outsite of this function
//php use pointer 0x34313131 and search for the
//address of 'value' and change it to 1
}
function test2($x)
{
//$x is 0x34313131
$x = new Example;
//now $x is 0x88888888
//this will NOT reflect outside of this function
//you need to rewrite it as "test2(&$x)"
$x->value = 1000; //this is 1000 JUST inside this function
}
$example = new Example;
$example->value = 0;
test1($example); // $example->value changed to 1
test2($example); // $example did NOT changed to a new object
// $example->value is still 1
?>
원래 변수를 단순히 변경하고 새 값이 할당된 동일한 변수 이름으로 다시 되돌리려는 함수에 사용합니다.
function add(&$var){ // The & is before the argument $var
$var++;
}
$a = 1;
$b = 10;
add($a);
echo "a is $a,";
add($b);
echo " a is $a, and b is $b"; // Note: $a and $b are NOT referenced
실제로는 두 가지 방법이 모두 유효하지만, 필요에 따라 다릅니다.참조로 값을 전달하면 스크립트가 느려지는 경우가 많습니다.따라서 실행 시간을 고려하여 값을 기준으로 변수를 전달하는 것이 좋습니다.또한 값을 기준으로 변수를 전달하면 코드 흐름이 더 일관됩니다.
PHP 참조는 별칭으로, 두 개의 다른 변수를 동일한 값에 쓸 수 있습니다.
또한 PHP에서 객체를 포함하는 변수가 있는 경우 해당 변수는 객체 자체를 포함하지 않습니다.대신 해당 개체의 ID가 포함됩니다.개체 접근자는 식별자를 사용하여 실제 개체를 찾습니다.따라서 함수에서 개체를 인수로 사용하거나 다른 변수에 할당할 때 개체 자체를 가리키는 식별자를 복사합니다.
https://hsalem.com/posts/you-think-you-know-php.html
class Type {}
$x = new Type();
$y = $x;
$y = "New value";
var_dump($x); // Will print the object.
var_dump($y); // Will print the "New value"
$z = &$x; // $z is a reference of $x
$z = "New value";
var_dump($x); // Will print "New value"
var_dump($z); // Will print "New value"
버전에 따라 4는 값, 5는 참조 값입니다.
언급URL : https://stackoverflow.com/questions/879/are-php-variables-passed-by-value-or-by-reference
'source' 카테고리의 다른 글
MySQL 데이터 원본이 Visual Studio에 나타나지 않음 (0) | 2022.10.19 |
---|---|
각도 2를 사용하여 인도 형식으로 숫자 표시 (0) | 2022.10.19 |
404의 URL을 PHP로 테스트하는 쉬운 방법? (0) | 2022.10.19 |
Gson이 "<"와 ">"를 Unicode 이스케이프 시퀀스로 변환하는 것을 피할 수 있습니까? (0) | 2022.10.19 |
json_encode PHP 어레이를 JSON 개체가 아닌 JSON 어레이로 코드합니다. (0) | 2022.10.19 |