具有不存在索引的默认值的PHP数组
我喜欢Ruby的Hash实现,在这里可以用默认值初始化Hash对象。目前,我正在努力用PHP实现一个类似的对象。这是我在这方面的第一次(非工作)尝试具有不存在索引的默认值的PHP数组,php,arrays,hash,Php,Arrays,Hash,我喜欢Ruby的Hash实现,在这里可以用默认值初始化Hash对象。目前,我正在努力用PHP实现一个类似的对象。这是我在这方面的第一次(非工作)尝试 class DefaultArray extends ArrayObject { protected $_defaultValue; public function setDefault($defaultValue) { $this->_defaultValue = $defaultValue; } publi
class DefaultArray extends ArrayObject {
protected $_defaultValue;
public function setDefault($defaultValue) {
$this->_defaultValue = $defaultValue;
}
public function offsetExists($index) {
return true;
}
public function offsetGet($index) {
if(!parent::offsetExists($index)) {
if(is_object($this->_defaultValue))
$default = clone $this->_defaultValue;
else
$default = $this->_defaultValue;
parent::offsetSet($index, $default);
}
return parent::offsetGet($index);
}
}
$da = new DefaultArray();
assert($da["dummy"] == null);
$da->setDefault = 1;
assert($da["dummy2"] == 1);
第二个断言将失败。单步遍历代码显示调用了offsetGet并执行if子句。然而,任何数组值都是空的。有其他实现的想法吗
我厌倦了写作
if(!isset($myarr['value']))
$myarr['value'] = new MyObj();
$myarr['value']->myVal=5;
而不仅仅是写作
$myarr['value']->myVal=5;
您还可以使用uu构造魔术函数:
class DefaultArray extends ArrayObject
{
public function __construct($value = null){
if(is_null($value))
{
$this->value = 'default';
} else {
$this->value = $value;
}
}
}
为什么这么复杂
function initVal($value) {
global $myarr;
if(!isset($myarr['value']))
$myarr['value'] = new MyObj();
}
现在您只需拨打:
initVal('bla');
$myarr['bla']->bla = 'bla';
但是我明白了,你的要整洁得多。试试这个
现在,您只需要使用不同的键,因为读取访问将初始化该数组项:
$da = new DefaultArray();
assert($da['foo'] == null);
$da->setDefault(1);
assert($da['bar'] == 1);
在这种情况下,您可以使用我的微型库,例如:
class DefaultArray extends ArrayObject
{
public function __construct($value = null){
$this->value = ValueResolver::resolve($value, 'default'); // returns 'default' if $value is null
}
}
不要忘记使用namespace使用LapaLabs\ValueResolver\Resolver\ValueResolver代码>
还可以进行类型转换,例如,如果变量的值应为整数
,请使用以下方法:
$id = ValueResolver::toInteger('6 apples', 1); // returns 6
$id = ValueResolver::toInteger('There are no apples', 1); // returns 1 (used default value)
查看更多示例使用ArrayObject类将所有变量和支持方法保留在一个位置。其中,使用全局函数可能会导致将来出现维护问题。当访问不存在的密钥时,offsetGet
将使用默认值设置该密钥(请参见offsetSet
)。这意味着下一次它将存在。如果您不希望出现这种行为,并且总是为不存在的键获取当前默认值,请删除offsetSet
调用。感谢Gumbo的重要澄清,这种行为在我的第一次测试中让我感到困惑,但这是预期的行为。现在问题已经解决了,我将保留错误的测试代码。谢谢,你发现了我的错误!它是$da->setDefault(1),而不是$da->setDefault=1!哦,尴尬!通过此修改,我的示例按预期工作。我还考虑在构造函数中传递默认值,但希望保留ArrayObject的原始构造函数参数。您可以使用我的微型库使其更紧凑。
class DefaultArray extends ArrayObject
{
public function __construct($value = null){
$this->value = ValueResolver::resolve($value, 'default'); // returns 'default' if $value is null
}
}
$id = ValueResolver::toInteger('6 apples', 1); // returns 6
$id = ValueResolver::toInteger('There are no apples', 1); // returns 1 (used default value)