2012-08-06 2 views
3

원래 변수를 참조로 덮어 쓰면 내부적으로 어떻게됩니까?
의미가 잘못 되었습니까? 추가 시간이나 리소스가 필요합니까?원래 변수를 참조로 덮어 쓰면 내부적으로 어떻게됩니까?

<?php 
function db(){ 
    global $db; 
    if(empty($db)) $db = new PDO('sqlite:/tmp/default.db3'); 
    return &$db; 
} 

$db = db(); 
?> 
+1

참조로 "덮어 쓰지"않았습니다 * 않습니다 *. 아마 당신은 참조로 돌아가는 것에 대해 실제로 이해하지 못하는 것을 더 잘 공식화 할 수있을 것입니다. – hakre

+0

2012 년 PHP에서'global'을 사용합니다 - 나쁜 습관입니다. – voodoo417

+2

흥미로운 질문입니다. 나는 이것이 그렇게 나쁜 처사 일 것이라고 생각한다. 그냥 이론적으로 유지하십시오. (필자는 upvotes로 추론하기는 거의하지 않지만 이것이 필요했습니다.) – Whisperity

답변

0

개체보다 항상 작은 개체의 주소를 반환하므로 더 이상 리소스를 소비하지 않아야합니다.

내가 실수하지 않은 경우, 객체가 PHP 5로 반환되면 (&)을 앞에 붙이지 않아도 참조로 반환됩니다. (I 정정 스탠드 객체는 referance에 의해 반환되지 않음) :

내가 개체에 의해 반환되는 모든 다른 프로그래밍 언어에서 알고

http://php.net/manual/en/language.references.return.php

통과/복사하여 참조 및 기본 데이터 유형에 의해 반환.

예제에서 전역 변수를 사용할 때 이미 함수 외부의 변수를 참조했습니다. 이미 오버라이드 했으므로 반환 값은 필요 없습니다. 당신이

global $db; 

를 사용하는 경우

+2

다시 올바르지 않습니다. 개체는 참조로 반환되지 않습니다. PHP 매뉴얼에서 찾을 수 있습니다 : [Objects and references] (http://de.php.net/manual/language.oop5.references.php) – hakre

+0

내가 실수하지 않았다면 나는 말했다. 나는 이것을 읽었을 뿐이다. http://php.net/manual/en/language.references.return.php – thedethfox

+0

아니요, 객체는 항상 값에 의해 반환됩니다. 그러나 그 값은 객체 식별자입니다. 따라서 값을 복사하더라도 식별자 만 복사합니다. 따라서 가치에 따라 객체를 복사 할 수 없으므로 (일부는 참조 여야한다고 생각하는 이유가 있지만 실제로는 그렇지 않습니다), 객체를 [복제] 할 수 있습니다 (http://de.php.net/clone). – hakre

3

이 로컬 범위에 글로벌 변수 $db를 가져옵니다.

그런 다음 다른 변수 (전역 변수를 나타냄)로 존재합니다. 당신은 마침내 그 변수에 대한 참조를 반환을 시도 :

return &$db; 

하지만이 return by reference 없습니다. 대신 값을 반환합니다.

그런 다음 글로벌 변수 테이블에 $db의 값을 직접 입력해야합니다. 그게 여기서 일어나고있는 모든 것입니다.

추가 시간이나 리소스가 필요합니까?

불필요한 모든 작업에는 추가 시간 또는 리소스가 필요합니다. 그러나 PHP는 copy on write (COW)라는 최적화 기능을 가지고 있으므로 일반적으로 많이 신경 쓰지 않아도됩니다. PHP는 부담을 덜어줍니다.

코드에서 개체와 관련이 있습니다.

<?php 

$db = new PDO('sqlite:/tmp/default.db3'); 

?> 

그런 다음이 필요한 DB를 개체를 전달 : 그냥이 방법을 변경합니다. 간단하게, 어리 석다.

0

참조로 반환하는 방법이 아닙니다. 당신은 참조로 개체를 반환하지 않아도, 언어는 모든 객체가 자동으로 참조로 반환하고, 매뉴얼도 강하게 객체에 대한 참조 연산자로 사용하지 않는 것이 좋습니다 지정

function &return_by_ref() 
{ 
    $something=""; 
    return $something; 
} 

: 이 같은 기능을 선언해야합니다 .

유 실제로 무엇을 의미하는지 이것이다 :

class DB{ 
    private function __construct(){} 
    public static $db=null; 
} 

function db($db) 
{ 
    if(!isset(DB::$db)) 
     DB::$db=new PDO('sqlite:/tmp/default.db3'); 
    return DB::$db; 
} 

사용법 :

function create_user() 
{ 
    db()->exec("INSERT INTO `users` SET `name`='John Doe'"); 
    return db()->lastInsertId(); 
} 

function get_users() 
{ 
    return db() 
     ->query("SELECT * FROM `users`") 
     ->fetchAll(PDO::FETCH_ASSOC) 
    ; 
} 
+0

Hakre가 말했듯이, 문서는 실제로 "언어는 모든 객체가 참조에 의해 자동으로 반환됨을 지정합니다"라고 말하지 않습니다. 참조로 전달하지 않고 함수 내에서 객체 변수를 수정하려고하면 효과가 비슷하지만 실제로 객체를 수정하지는 않습니다. (참조를 잃어 버리고 새 변수가 생깁니다.) 함수에 전달 된 값은 변수가 위치한 메모리 내 공간에 대한 참조가 아니라 객체의 식별자입니다. – williamvicary

+0

그 증거가 있습니까? PHP 구현이 여러 개 있다는 것을 알고 있습니까 (Zend, HipHop, Phalanger)? 가능성이있는 최적화라고 알고 있습니까? 아직 존재하지 않는다면, 앞으로도 계속 될 것입니다. Exception의 stack trace에서 객체가 다른 수정을 추가 한 모든 함수에 대해 마지막으로 수정 된 상태로 표시된다는 것을 알고 있었습니까? (디버깅이 고통 스럽습니까?) –

+0

또한 내 대답의 첫 번째 줄을 읽었습니까? 질문에 잘못된 PHP 코드가 포함되어 있습니다. 그렇다면 잘못된 PHP 코드로 인해 PHP 내부에 대해 대답 할 수 없습니다. –

0

원래 예 구문 오류이기 때문에, 나는 이것이 당신이 쓰고 싶다 어떤 생각 :

function db(){ 
    static $db = null; 
    if ($db === null) { 
     $db = new PDO('sqlite:/tmp/default.db3'); 
    } 
    return $db; 
} 

당신이 실제로 그런 경향이 있다면, vulcan logic disassembler으로 스크립트를 실행하고 opcode를 얻을 수 있습니다. 유일한 주목할만한 차이점은 참조가있는 버전이 RETURN 및 ASSIGN 대신 RETURN_BY_REF 및 ASSIGN_REF opcode를 사용한다는 것입니다. 엔진이 실행될 때 엔진이 수행하는 작업을 결정하는 것은 간단하지 않지만 주로 복사시 복사 동작은 대개 복사를 방지합니다.

관련 문제