2010-09-15 40 views
11

Tôi đang cố gắng tham chiếu biến riêng của một đối tượng từ bên trong một đóng. Mã bên dưới dường như hoạt động, nhưng nó phàn nàn Fatal error: Cannot access self:: when no class scope is active in test.php on line 12Fatal error: Using $this when not in object context in test.php on line 20.Truy cập các biến riêng tư trong một đóng cửa

Bất kỳ ý tưởng nào về cách thực hiện các kết quả tương tự bằng cách đóng cửa trong khi vẫn giữ các biến riêng tư và không có chức năng trợ giúp (đánh bại toàn bộ ý tưởng về biến riêng tư).

class MyClass 
{ 

    static private $_var1; 
    private $_var2; 

    static function setVar1($value) 
    { 
     $closure = function() use ($value) { 
      self::$_var1 = $value; 
     }; 
     $closure(); 
    } 

    function setVar2($value) 
    { 
     $closure = function() use ($value) { 
      $this->_var2 = $value; 
     }; 
     $closure(); 
    } 

} 

MyClass::setVar1("hello"); //doesn't work 

$myclass = new MyClass; 
$myclass->setVar2("hello"); //doesn't work 

Trả lời

14

Chỉnh sửa cần lưu ý, câu trả lời này ban đầu được dành cho PHP5.3 trở về trước, nó có thể bây giờ. Để biết thông tin hiện tại, hãy xem this answer.


Điều này không thể trực tiếp. Đặc biệt, các bao đóng không có phạm vi liên quan, vì vậy chúng không thể truy cập các thành viên riêng tư và được bảo vệ.

Bạn có thể, tuy nhiên, sử dụng tài liệu tham khảo:

<?php 
class MyClass 
{ 

    static private $_var1; 
    private $_var2; 

    static function setVar1($value) 
    { 
     $field =& self::$_var1; 
     $closure = function() use ($value, &$field) { 
      $field = $value; 
     }; 
     $closure(); 
    } 

    function setVar2($value) 
    { 
     $field =& $this->_var2; 
     $closure = function() use ($value, &$field) { 
      $field = $value; 
     }; 
     $closure(); 
    } 

} 

MyClass::setVar1("hello"); 

$myclass = new MyClass; 
$myclass->setVar2("hello"); 
+0

Heh - copycat ;-) – DMI

+0

@ Dave Tôi đã thực sự viết nó trước khi tôi đọc câu trả lời của bạn. Dù sao, +1 cho bạn như là một giải quyết: p – Artefacto

+0

Heh. Phát triển song song nhanh chóng. Cảm ơn bạn đã +1 và đã trở lại bằng hiện vật khi bạn nỗ lực nhiều hơn tôi! :-) – DMI

2

đóng cửa không có khái niệm về $this hoặc self - họ không gắn với đối tượng theo cách đó. Điều này có nghĩa rằng bạn sẽ phải vượt qua các biến thông qua các khoản use ... cái gì đó như:

$_var1 =& self::$_var1; 
$closure = function() use ($value, &$_var1) { 
    $_var1 = $value; 
}; 

$_var2 =& $this->_var2; 
$closure = function() use ($value, &$_var2) { 
    $_var2 = $value; 
}; 

tôi đã không kiểm tra mã trên, nhưng tôi tin rằng nó là đúng.

+0

Điều đó không chính xác, ít nhất là không phải trong 5.4. Xem: http://php.net/manual/en/closure.bindto.php – GuyPaddock

4

Điều này có thể bắt đầu trong PHP 5.4.0

class test { 
    function testMe() { 
     $test = new test; 
     $func = function() use ($test) { 
      $test->findMe();  // Can see protected method 
      $test::findMeStatically(); // Can see static protected method 
     }; 
     $func(); 
     return $func; 
    } 

    protected function findMe() { 
     echo " [find Me] \n"; 
    } 

    protected static function findMeStatically() { 
     echo " [find Me Statically] \n"; 
    } 
} 

$test = new test; 
$func = $test->testMe(); 
$func();  // Can call from another context as long as 
      // the closure was created in the proper context. 
+1

Chỉ cần làm rõ, liệu nó có hoạt động với 'hàm findMe riêng biệt()'? –

Các vấn đề liên quan