PHP 数组重构为对象

PHP Array Refactor to Object

我在 legacy 代码中有一个非常大的数组。就像来自数据库条目的 500k+。它在用户登录时获取 populatet。全球用户数组可以这么说。

现在我得到了重构这个坏男孩的不愉快的完整任务。

该数组是一维分配数组,如

 $data['username'] = 'idiots'; ( and tons of other values)

现在我想在一个对象中重构它,只有当我真正需要它时才会调用数据库中的值。我的想法是用对象替换数组赋值部分。

那么 $user = array(); 我想要用户 $user = new user();

是否有任何已知的方法来访问 class 函数,以便我可以通过 $user['name'] 访问其属性,以便将其传递给 __get method

我知道这是一项艰巨的任务,而且很可能是不可能的。但我还是要问 :)

一种方法是制作一个实现 ArrayAccess 的 class 并将您的延迟加载逻辑放入 offsetGet:

class User implements ArrayAccess {
    private $cache = array();

    public function offsetSet($key, $value) {
        throw new Exception("Read-only!");
    }

    public function offsetUnset($key) {
        throw new Exception("Read-only!");
    }

    public function offsetExists($key) {
        // consult the DB schema and return true if the `key` makes sense
    }

    public function offsetGet($key) {
        if(!isset($this->cache[$key])) {
            // load stuff from the DB
            $this->cache[$key] = ...;
        }
        return $this->cache[$key];
    }
}

$u = new User();
print $u['name'];
$data['username'] = 'idiots';
$data = (object) $data;
echo $data->username; // prints 'idiots'

对此有两种选择。第一个是传统的:

<?php

/**
 * @see http://php.net/manual/en/language.oop5.overloading.php#object.call
 */
class User
{
    protected $data = array();

    /**
     * @see http://php.net/manual/en/language.oop5.overloading.php#object.get
     */
    public function __get( $name )
    {
        echo "Getting $name " . PHP_EOL;
        return $this->data[ $name ];
    }

    /**
     * @see http://php.net/manual/en/language.oop5.overloading.php#object.set
     */
    public function __set( $name, $value )
    {
        echo "Setting $name to $value " . PHP_EOL;
        $this->data[ $name ] = $value;
    }
}

$user = new User();
$user->a = 'Example';

echo $user->a;

第二种是使用 PHP SPL 接口 ArrayAccess,它允许对象像 PHP 关联数组一样获取和设置:

<?php

/**
 * @see http://php.net/manual/en/class.arrayaccess.php
 */
class User implements ArrayAccess
{
    protected $data = array();

    /**
     * @see http://php.net/manual/en/arrayaccess.offsetexists.php
     */
    public function offsetSet( $key, $value )
    {
        echo "Setting $name to $value " . PHP_EOL;
        if( empty( $offset ) )
        {
            $this->data []= $value;
        }
        else
        {
            $this->data[ $key ] = $value;
        }
    }

    /**
     * @see http://php.net/manual/en/arrayaccess.offsetget.php
     */
    public function offsetExists( $key )
    {
        return isset( $this->container[ $key ] );
    }

    /**
     * @see http://php.net/manual/en/arrayaccess.offsetunset.php
     */
    public function offsetUnset( $key )
    {
        unset( $this->data[ $key ] );
    }

    /**
     * @see http://php.net/manual/en/arrayaccess.offsetset.php
     */
    public function offsetGet($offset)
    {
        echo "Getting $name " . PHP_EOL;

        if( $this->offsetExists( $key ) )
        {
            return $this->data[ $key ];
        }

        return null;
    }
}

$user = new User();
$user->[ 'a' ] = 'Example';

echo $user->[ 'a' ];