sınıfından bir yöntem olarak bir kapak tanımlamak

3 Cevap php

Ben PHP5.3 ve kapanması ile oynamaya çalışıyorum.

Ben (. Nesnenin içindeki 7 Kapanış İlan: http://www.ibm.com/developerworks/opensource/library/os-php-5.3new2/index.html) burada görmek bu geri arama işlevi $ bu kullanmak mümkün olduğunu, ama öyle değil. Yani kullanım değişken olarak $ this vermeye çalışın:

$self = $this;
$foo = function() use($self) { //do something with $self }

Yani aynı örneği kullanmak için:

class Dog
{
private $_name;
protected $_color;

public function __construct($name, $color)
{
     $this->_name = $name;
     $this->_color = $color;
}
public function greet($greeting)
{
     $self = $this;
     return function() use ($greeting, $self) {
         echo "$greeting, I am a {$self->_color} dog named {$self->_name}.";
     };
}
}

$dog = new Dog("Rover","red");
$dog->greet("Hello");

Output:
Hello, I am a red dog named Rover.

Bütün bu örneğin ilk dize yazdırmak ama geri dönüş fonksiyonu, ama bu benim sorunum değil gelmez.

Geri arama fonksiyonu global işlev değil Köpek nesneden bağlamda çünkü İkincisi ben, özel veya korunan erişemiyor. Benim sorunum Tha't. Bu kadar aynı:

function greet($greeting, $object) {
    echo "$greeting, I am a {$self->_color} dog named {$self->_name}.";
}

Ve ben istiyorum:

public function greet($greeting) {
    echo "$greeting, I am a {$self->_color} dog named {$self->_name}.";
}

Dog hangi ve küresel değildir.

3 Cevap

Kapatma arka (Kapatma sınıfı) bir nesne olduğundan Eh, $ this kullanamazsınız bütün nedeni vardır.

Bu yaklaşık iki yolu vardır. İlk olarak, (eğer $ obj (ararsanız denir ne)) __ invoke metodunu eklemektir ..

class Dog {

    public function __invoke($method) {
        $args = func_get_args();
        array_shift($args); //get rid of the method name
        if (is_callable(array($this, $method))) {
            return call_user_func_array(array($this, $method), $args);
        } else {
            throw new BadMethodCallException('Unknown method: '.$method);
        }
    }

    public function greet($greeting) {
        $self = $this;
        return function() use ($greeting, $self) {
            $self('do_greet', $greeting);
        };
    }

    protected function do_greet($greeting) {
        echo "$greeting, I am a {$this->_color} dog named {$this->_name}.";
    }
}

Eğer ana nesnesi değiştirirseniz kapatma değiştirmek istiyorsanız, sadece böyle bir şey için geri dönüş işlevini değiştirebilirsiniz:

public function greet($greeting) {
    $self = (clone) $this;
    return function() use ($greeting, $self) {
        $self('do_greet', $greeting);
    };
}

Diğer bir seçenek, bir genel getter sağlamaktır:

class Dog {

    public function __get($name) {
        return isset($this->$name) ? $this->$name : null;
    }

}

Daha fazla bilgi için, bkz: http://www.php.net/manual/en/language.oop5.magic.php

PHP 5.4.0 alpha1 itibariyle, $this, bir nesne örneği bağlamında erişebilirsiniz:

<?php
class Dog
{
  private $_name;
  protected $_color;

  public function __construct($name, $color)
  {
    $this->_name = $name;
    $this->_color = $color;
  }

  public function greet($greeting)
  {
    $func = function() use ($greeting) {
      echo "$greeting, I am a {$this->_color} dog named {$this->_name}.";
    };

    $func();
  }
}

$dog = new Dog("Rover","red");
$dog->greet("Hello");

Bunu da bunu yapabilirsiniz:

$dog = new Dog("Rover", "red");
$getname = Closure::bind($dog, function() { return $this->_name; });
echo $getname(); // Rover

Gördüğünüz gibi, o yüzden dikkatli olun ... Özel veri ile kolayca karışıklık mümkündür.

Well it makes sense that you cannot access private and protected fields of an object. And by explicitly passing $self to your function, it is treated just as a normal object.
You should create getters in order to access these values , i.e. :

class Dog
{
    private $_name;
    protected $_color;

    public function __construct($name, $color)
    {
         $this->_name = $name;
        $this->_color = $color;
    }
    public function getName() {
        return $this->_name;
    }
    public function getColor() {
        return $this->_color;
    }
    public function greet($greeting)
    {
         $self = $this;
         return function() use ($greeting, $self) {
             echo "$greeting, I am a {$self->getColor()} dog named {$self->getName()}.";
         };
    }
}

Sen konuda, zaten getter (ve belirleyiciler) oluşturmanız gerekir encapsulation.


Başka bir not: Eğer bağlantı makale PHP 5.3 final sürümü öncesi yayımlandı serbest bırakıldı. Belki bu örtük nesne geçen çıkarıldı.