PHP、SPL、ArrayAccess 接口
Posted
技术标签:
【中文标题】PHP、SPL、ArrayAccess 接口【英文标题】:PHP, SPL, ArrayAccess Interface 【发布时间】:2012-07-05 05:16:56 【问题描述】:我正在尝试理解 ArrayAccess 接口背后的想法,
我不明白每种方法的含义,如果这些方法(函数)是“内置”函数,而 ArrayAccess 接口(也是“内置”)只是“确保”我将实现那些“内置”方法(函数)
我试图了解每个函数对我们的“幕后”代码的作用。
function offsetSet($offset, $value);
function offsetGet($offset);
function offsetUnset($offset);
function offsetExists($offset);
如果我理解 ArrayAccess 是一个包含要实现的密封的内置接口,当我们实现它们时,我们只实现对内置函数的引用,如果有人可以帮我解决这个问题,我会很高兴。
【问题讨论】:
这个类在这里有很好的记录php.net/manual/en/class.arrayaccess.php 【参考方案1】:如果你实现了那个接口,那么对象就像一个数组。例如,如果$foo
是实现ArrayAccess
的类的实例:
$foo['bar'] = 42
呼叫offsetSet('bar', 42)
。
echo $foo['bar']
呼叫offsetGet('bar')
。
unset($foo['bar'])
呼叫offsetUnset('bar')
。
isset($foo['bar'])
呼叫offsetExists('bar')
。
您永远不会自己显式调用函数 offset*。当您将对象作为数组访问时,它会隐式发生。
【讨论】:
非常感谢马修,如果您确认我对这个主题的理解,我将非常高兴,数组接口是一个“内置接口”,这个接口包含这些函数的签名,这些函数是引用当我们将对象作为数组访问时自动响应的“内置”函数,非常感谢您的回答我正在尝试手册并且不理解此界面,如果您可以确认,祝您有美好的一天马修. 接口内置了这四个函数签名,但 PHP 程序员必须实际实现它们。像数组一样访问它们时自动调用 offset* 函数的行为也是内置的……这是您无法使用自己的接口执行的操作。 (有一些内置接口在实现时会类似地影响核心 PHP 功能。) 谢谢 Matthew,如果我做对了,只有函数和参数签名,以及自动调用 offset* 的行为,但请告诉我,这种行为仅在您以数组调用偏移*,我的意思是这种行为仅指函数名称?这意味着我有责任将功能设置为我想要的功能,再次感谢。 程序员必须编写 offset* 函数来做一些有用的事情。例如,通常offsetSet($key, $val)
类似于$this->data[$key] = $val
。 PHP 负责其余的工作。写一些测试代码,你会发现它可以工作了。
Matthew 非常感谢你,直到现在我才试图理解它,我没有理解手册,我正在寻找像你一样的答案,祝你有美好的一天,再次感谢。【参考方案2】:
在比较ArrayAccess
和SimpleXMLElement
(一个没有实现它的内部类)时,我也很好奇。该界面已在手册中详细记录,因此我想强调一些特定偏移类型的差异。
但首先是实现ArrayAccess
的类的样板示例实现,在访问时会给出输出:
/**
* ArrayAccess Example
*/
class ExampleArrayLikeAccess implements ArrayAccess
/**
* Whether a offset exists
*
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
* @param mixed $offset - An offset to check for.
* @return boolean true on success or false on failure.
*
* The return value will be casted to boolean if non-boolean was returned.
*/
public function offsetExists($offset)
echo " - offsetExists(", $this->varString($offset),")\n";
/**
* Offset to retrieve
*
* @link http://php.net/manual/en/arrayaccess.offsetget.php
* @param mixed $offset The offset to retrieve.
* @return mixed Can return all value types.
*/
public function offsetGet($offset)
echo " - offsetGet(", $this->varString($offset),")\n";
/**
* Offset to set
*
* @link http://php.net/manual/en/arrayaccess.offsetset.php
* @param mixed $offset The offset to assign the value to.
* @param mixed $value The value to set.
* @return void
*/
public function offsetSet($offset, $value)
echo " - offsetSet(", $this->varString($offset), ", ", $this->varString($value), ")\n";
/**
* Offset to unset
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
* @param mixed $offset The offset to unset.
* @return void
*/
public function offsetUnset($offset)
echo " - offsetUnset(", $this->varString($offset),")\n";
/**
* helper to give a variable dump in form of a string
*/
private function varString($var)
ob_start();
var_dump($var);
return trim(strtr(ob_get_clean(), ["\n" => '', "\r" => '']), ' ');
用它运行一些使用示例。我以 cmets 的形式留下了笔记。它应该是不言自明的:
$like = new ExampleArrayLikeAccess();
/* offsetExists */
// indexes/keys that behave similar to PHP arrays:
isset($like[1]); # integer stay integer
# offsetExists(int(1))
isset($like['1']); # string like an integer - converted to integer
# offsetExists(int(1))
isset($like['01']); # string unlike an integer - stays string
# offsetExists(string(2) "01")
isset($like[TRUE]); # booleans are converted to integer
# offsetExists(bool(true))
// indexes/keys that differ to PHP arrays:
isset($like[1.1]); # a float stays a float (double)
# offsetExists(double(1.1))
isset($like[NULL]); # NULL stays NULL
# offsetExists(NULL)
isset($like[array()]); # array stays array
# offsetExists(array(0))
isset($like[$like]); # object stays object
# offsetExists(class SxeLikeAccess#2 (0))
/* offsetGet */
// indexes/keys behave the same as with offsetExists:
$like[1]; # offsetGet(int(1))
$like['1']; # offsetGet(int(1))
$like['01']; # offsetGet(string(2) "01")
// ...
/* offsetSet */
$like[1] = 'value'; # index/key behaves the same as with offsetExists
# offsetSet(int(1), string(5) "value")
$like[] = 'value'; # index/key is NULL
# offsetSet(NULL, string(5) "value")
$like[NULL] = 'value'; # index/key is NULL
# offsetSet(NULL, string(5) "value")
/* offsetUnset */
unset($like[1]); # index/key behaves the same as with offsetExists
unset($like[NULL]); # same for NULL
与标准 PHP 数组的主要区别在于,您不仅可以使用整数和字符串作为偏移量。
【讨论】:
以上是关于PHP、SPL、ArrayAccess 接口的主要内容,如果未能解决你的问题,请参考以下文章