-->

PHP的魔术方法捉array_push(php magic method to catch arra

2019-09-16 10:59发布

我正在寻找一种方式来拦截行动array_push ,因为当它会检索它的阵列的每个值都有像另一个信息:

class ClassName {

    var $test = array();

    function __set($attr, $value) {
      $this->$attr = 'My extra value'.$value;
    }    

    function index(){
      array_push($this->test, "some val");
      array_push($this->test, "some other val");

      print_r($this->test);

    }
}

$o = new ClassName();
$o->index();

并有望获得类似:

Array
(
    [0] => My extra value some val
    [1] => My extra value some other val
)

但我得到:

Array
(
    [0] => some val
    [1] => some other val
)

谢谢大家

Answer 1:

而不是使用一个数组,你可以使用实现了ArrayAccess接口的类。 这样,你有超过你时追加到数组中发生的事情完全控制。

http://php.net/manual/en/class.arrayaccess.php

其缺点是,并非所有的阵列功能将对象(即排序等)上工作,但你可以把像这样:

$object[] = 'new value';

另一种方法是简单地使一个包装函数用于添加到阵列。

public function addToArray($key, $value) {
   if ($key === null) {
      $this->test[] = 'My extra value ' . $value;
   } else {
      $this->test[$key] = 'My extra value ' . $value;
   }
}


Answer 2:

我不完全理解你问什么,但你试图做到这一点:

$this->test['key'] = "some val";

这将允许您设置自己的输出很好。 由于array_push()将抛出另一个嵌套级别。

更新:沿着这些路线或许真的?

function push($prefix)
{
    $refl = new ReflectionClass($this);
    $prop = $refl->getProperties();
    foreach($prop as $p) {
        $this->{$p} = $prefix . $this->{$p};
    }
}


Answer 3:

为了实现你在找什么,我建议你自己创建的前缀是独立于任何价值,它的使用功能:

function prefix($value) {
    return 'My extra value '.$value;
}

然后,您可以使用该功能的内index()函数:

function index()
{
    $test = array("some val", "some other val");
    foreach($test as $value)
    {
        $this->test[] = $this->prefix($value);
    }
    print_r($this->test);
}


Answer 4:

从PHP手册:

__set() is run when writing data to inaccessible properties.
__get() is utilized for reading data from inaccessible properties.

这只叫上读取/写入性能无法访问。 然而,你的财产是公开的,这意味着它是可访问的。 访问修饰符更改为保护解决这个问题。

尝试这个:

    class ClassName {

        private $test = array();

        public function __set($attr, $value) {
          $this->test[$attr] = $value;

        }    

        public function __get($attr) {
        return $this->test[$attr];
        }    

        public function index(){

          array_push($this->test, "some val");
          array_push($this->test, "some other val");

          return $this->test;

        }
    }

    $o = new ClassName();
    $o->setData = 'My extra value';
    print_r($o->index());


Answer 5:

PHP手册说,关于魔术方法如下:

__set()中写入数据时,以不可访问性能运行。 (重点煤矿)

由于test属性是该方法和访问它是在该方法内的函数内,该函数将直接看到变量并且将使用魔术设定器。

此外,即使你试图对魔法二传手类本身之外 ,这仍然无法工作使用array_push。 你会得到错误array_push() expects parameter 1 to be array, object given

如果你想支持array_push,你应该写自己的push($item)方法:

function push($item) {
    $this->test[] = 'My extra value' . $item
}

要么:

function push() {
    $items = func_get_args();

    // Using array_map is one of the many ways to do this.
    // You could also do it with a simpler `foreach` but I like this way.
    $prepend = function($item) {
        return 'My extra value' . $item;
    };
    $items = array_map($prepend, $items);
    array_push($this->test, $items);
}

如果你想支持一边推着多个项目。



文章来源: php magic method to catch array_push