2

我正在寻找一种拦截动作的方法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
)

谢谢大家

4

5 回答 5

2

您可以使用实现 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;
   }
}
于 2012-04-10T18:23:41.523 回答
0

我不完全明白你在问什么,但你是否试图这样做:

$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};
    }
}
于 2012-04-10T18:10:23.353 回答
0

为了实现您正在寻找的东西,我建议您自己创建一个函数,该函数在任何与其用途无关的值前面加上前缀:

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);
}
于 2012-04-10T18:22:49.777 回答
0

来自 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());
于 2012-04-10T19:04:48.820 回答
0

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);
}

如果您想支持一次推送多个项目。

于 2012-12-19T20:15:37.660 回答