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' ];
我在 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' ];