У меня есть действительно гигантский массив в наследие код. как 500k + от записей в БД. Он заполняется один раз при входе пользователя в систему. Глобальный пользовательский массив, так сказать.
Теперь я получил непростой квест на реорганизацию этого плохого мальчика.
массив представляет собой одномерный заданный массив, как
$data['username'] = 'idiots'; ( and tons of other values)
Теперь я хочу реорганизовать это в объект, который будет вызывать значение из БД только тогда, когда он мне действительно нужен. Моя идея состояла в том, чтобы заменить часть присвоения массива объектом.
Так где $user = array();
Я хочу пользователя $user = new user()
;
Есть ли какой-либо известный способ доступа к функции класса, чтобы я мог получить доступ к ее свойствам через $user['name']
так что это передается __get method
?
Я знаю, что это высокий заказ, и это, вероятно, невозможно. Но я все равно спрошу 🙂
Одним из способов является создание класса, который реализует ArrayAccess
и положить вашу ленивую логику загрузки в 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'];
Есть две альтернативы этому. Первый, являющийся традиционным:
<?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 Assocative Array:
<?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' ];
$data['username'] = 'idiots';
$data = (object) $data;
echo $data->username; // prints 'idiots'