哪个 PHP 接口允许对象?属性可以通过数组表示法访问吗?

发布于 2024-08-22 03:08:01 字数 1367 浏览 11 评论 0原文

哪个 PHP SPL 接口允许对象执行此操作:

$object->month = 'january';
echo $object['month']; // january

$record['day'] = 'saturday';
echo $record->day; // saturday

例如,在 Doctrine (Doctrine_Record) 等库中,

我如何实现此操作?我尝试过使用 ArrayObject,但它们的行为并不像我想象的那样。

$object = new ArrayObject();
$object['a'] = 'test';
$object['a'] == $object->a; // false

编辑:

我尝试了一个名为 Arrayable 的准系统实现。

class Arrayable implements ArrayAccess
{
    protected $container = array();

    # implement ArrayAccess methods to allow array notation 
    # $object = new Arrayable();
    # $object['value'] = 'some data';

    function offsetExists($offset)
    {
        return isset($this->container[$offset]);
    }

    function offsetGet($offset)
    {
        return $this->container[$offset];
    }

    function offsetSet($offset, $value)
    {
        $this->container[$offset] = $value;
    }

    function offsetUnset($offset)
    {
        unset($this->container[$offset]);
    }

    # now, force $object->value to map to $object['value'] 
    # using magic methods

    function __set($offset, $value)
    {
        $this->offsetSet($offset, $value);
    }

    function __get($offset)
    {
        return $this->offsetGet($offset); 
    }
}

Which PHP SPL interface allows objects to do this:

$object->month = 'january';
echo $object['month']; // january

$record['day'] = 'saturday';
echo $record->day; // saturday

e.g. such as in libraries like Doctrine (Doctrine_Record)

how do I implement this? I've tried using ArrayObject, but they don't behave as I thought they would.

i.e.

$object = new ArrayObject();
$object['a'] = 'test';
$object['a'] == $object->a; // false

EDIT:

I tried a barebone implementation that I called Arrayable.

class Arrayable implements ArrayAccess
{
    protected $container = array();

    # implement ArrayAccess methods to allow array notation 
    # $object = new Arrayable();
    # $object['value'] = 'some data';

    function offsetExists($offset)
    {
        return isset($this->container[$offset]);
    }

    function offsetGet($offset)
    {
        return $this->container[$offset];
    }

    function offsetSet($offset, $value)
    {
        $this->container[$offset] = $value;
    }

    function offsetUnset($offset)
    {
        unset($this->container[$offset]);
    }

    # now, force $object->value to map to $object['value'] 
    # using magic methods

    function __set($offset, $value)
    {
        $this->offsetSet($offset, $value);
    }

    function __get($offset)
    {
        return $this->offsetGet($offset); 
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浅语花开 2024-08-29 03:08:01

它是 ArrayAccess

请参阅 Doctrine_Record 的源代码

abstract class Doctrine_Record 
    extends Doctrine_Record_Abstract 
    implements Countable, IteratorAggregate, Serializable

Doctrine_Record_Abstract

abstract class Doctrine_Record_Abstract extends Doctrine_Access

最后 Doctrine_Access

abstract class Doctrine_Access 
    extends Doctrine_Locator_Injectable 
    implements ArrayAccess

来自 DocBlock

为 Doctrine 子类提供数组访问和属性重载接口


实现 ArrayAccess 的对象必须具有这些方法

abstract public boolean offsetExists  ( mixed $offset  );
abstract public mixed offsetGet ( mixed $offset );
abstract public void offsetSet ( mixed $offset , mixed $value );
abstract public void offsetUnset ( mixed $offset );

PHP 手册中有一个基本使用示例(上面链接)

It's ArrayAccess

See the sourcecode for Doctrine_Record

abstract class Doctrine_Record 
    extends Doctrine_Record_Abstract 
    implements Countable, IteratorAggregate, Serializable

and Doctrine_Record_Abstract

abstract class Doctrine_Record_Abstract extends Doctrine_Access

and finally Doctrine_Access

abstract class Doctrine_Access 
    extends Doctrine_Locator_Injectable 
    implements ArrayAccess

From DocBlock

Provides array access and property overload interface for Doctrine subclasses


An object implementing ArrayAccess has to have these methods

abstract public boolean offsetExists  ( mixed $offset  );
abstract public mixed offsetGet ( mixed $offset );
abstract public void offsetSet ( mixed $offset , mixed $value );
abstract public void offsetUnset ( mixed $offset );

There is a basic usage example in the PHP manual (linked above)

小瓶盖 2024-08-29 03:08:01

您在这里使用两个不同的东西:

$a[key] 的 ArrayAccess 接口和
http://php.net/manual/en/language.oop5.overloading。 php for $a->key

发生的情况是

$a[key] 将调用 $a->offsetGet(key) (继承自 ArrayAccess)和 $a->key 将调用 $a->__get(key)$a->__set( key, val) (在诸如 $a->key = val 的上下文中)。

You are using two different things here:

The ArrayAccess interface for $a[key] and
http://php.net/manual/en/language.oop5.overloading.php for $a->key

What happens is

$a[key] will call $a->offsetGet(key) (inherited from ArrayAccess) and $a->key will call $a->__get(key) or $a->__set(key, val) (in contexts like $a->key = val).

夜灵血窟げ 2024-08-29 03:08:01

我认为你可以转换对象和数组..

$object = (object)array('name'=>'aviv');
echo $object->name; // prints aviv

反之亦然..

$array= (array)$object;
echo $array['name']; // prints aviv

I think you can cast object and arrays..

$object = (object)array('name'=>'aviv');
echo $object->name; // prints aviv

And vise versa ..

$array= (array)$object;
echo $array['name']; // prints aviv
偏爱自由 2024-08-29 03:08:01

您可以实现自己的类
例如

class PropertyTest {
 $month;
}

然后在代码中使用

$object = new PropertyTest;
$object->month = "January";
echo $obejct->month;

You can implement your own class
e.g.

class PropertyTest {
 $month;
}

then in code use

$object = new PropertyTest;
$object->month = "January";
echo $obejct->month;
丑疤怪 2024-08-29 03:08:01

我使用您的示例代码回答这个问题,并进行了一些补充:

<?php
$object = new ArrayObject([], ArrayObject::ARRAY_AS_PROPS);

$object['a'] = 'test';
var_dump($object['a'] == $object->a); // expected: bool(true)

$object->month = 'january';
echo $object['month'];               // expected: january

$object['day'] = 'saturday';
echo $object->day;                   // expected: saturday

演示https:// 3v4l.org/Nd5NW


ArrayObject 接受第二个构造函数参数,它是

  • ArrayObject::STD_PROP_LIST
    当作为列表(var_dump、foreach 等)访问时,对象的属性具有其正常功能。

  • ArrayObject::ARRAY_AS_PROPS
    条目可以作为属性进行访问(读取和写入)。

参考http://php.net/manual/de /class.arrayobject.php

I'm answering the question using your example code with a minor addition:

<?php
$object = new ArrayObject([], ArrayObject::ARRAY_AS_PROPS);

$object['a'] = 'test';
var_dump($object['a'] == $object->a); // expected: bool(true)

$object->month = 'january';
echo $object['month'];               // expected: january

$object['day'] = 'saturday';
echo $object->day;                   // expected: saturday

Demo: https://3v4l.org/Nd5NW


ArrayObject accepts a 2nd constructor argument, which is either

  • ArrayObject::STD_PROP_LIST
    Properties of the object have their normal functionality when accessed as list (var_dump, foreach, etc.).

  • ArrayObject::ARRAY_AS_PROPS
    Entries can be accessed as properties (read and write).

Referencing: http://php.net/manual/de/class.arrayobject.php

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文