好吧,我有一个配置对象,其中包含各种对象的设置。我的类在运行时生成,只要我想要实例化一个尚未创建的类的新对象,它们依赖于配置对象来知道哪些属性是必需的以及其他一些信息: 想到它有点像这样:
Config
->Class1
->Attributes
->id
->Mandatory: true
->imagesource
->Mandatory: true
.................
->Class2
..........................
我有一个方法,validateObject(),它检查是否为对象设置了强制值,如:
function validateObject($object){
$config = configObject[get_class($object)];
foreach($config->attributes as $attrName => $attrVal){
if($attrVal->mandatory == true){
if(!isset($object->$attrName){
throw Error();
}
}
}
}
到目前为止,这么好。现在,我的配置对象将属性名称变为camelCase。我决定让程序员使用他们想要的任何外壳,最后,我只想检查对象是否有任何属性,转为小写,将匹配Config上的那个转为小写。
我目前的解决方案就像是
function validateObject($object){
$config = configObject[get_class($object)];
foreach($config->attributes as $attrName => $attrVal){
if($attrVal->mandatory == true){
$lowercaseAttr = str_to_lower($attrName);
foreach($object as $key => $value){
if(str_to_lower($key) == $lowercaseAttr){
//don't throw, move to the next attribute in config
}
}
}
}
}
这可以胜任,虽然需要更多的工作。我一直在寻找更优雅的解决方案......
我希望我不要混淆,谢谢你的帮助
答案 0 :(得分:2)
我能想到这样做的唯一方法是向类中添加类似于
的函数 public function check($p){
$props =get_object_vars($this);
$array_to_search;
foreach($props as $key=>$prop){
$array_to_search[strtolower($key)] = strtolower($key);
}
echo "prop :".array_key_exists(strtolower($p),$array_to_search);
}
然后致电
$obj->check("thingtwo");
阵列位可能会被优化,我只是快速将它们放在一起,看它是否适合你。如果你有许多类,那么这个函数可以分开,你可以传入一个对象
function check($obj,$p){
$props =get_object_vars($obj);
$array_to_search;
foreach($props as $key=>$prop){
$array_to_search[strtolower($key)] = strtolower($key);
}
echo "prop :".array_key_exists(strtolower($p),$array_to_search);
}
check($myobj, "propertyname");
如果属性存在但是为null,则上述内容将返回true。您可以通过将功能更改为
来检查值 function check($obj,$p){
$props =get_object_vars($obj);
$array_to_search;
foreach($props as $key=>$prop){
$array_to_search[strtolower($key)] = $prop;
}
echo "prop :".isset($array_to_search[strtolower($p)]);
}
答案 1 :(得分:1)
如你所知,PHP中的数组键区分大小写,那么当开发人员犯错时会发生什么,例如复制现有设置?
一些自定义配置:
$attributes = array(
'settingOne' => array(/* stuff */),
// ...
'settingone' => array(/* different stuff */)
);
现在,当开发者尝试编辑设置时,他可能会修改settingOne
,或者他可能会修改settingone
。如果他碰巧没有编辑你的代码正在读取的那个(这可能总是数组中的第一个),那么他的更改将无法工作,并且他手上很难找到错误。
这是你的设计,但如果我以这种方式做某事,我会要求配置数组键匹配完全我期望它们。这可以在您创建的任何文档中清楚地强调,并解决所有问题,因为您可以简单地使用isset()
。我认为大多数开发人员都习惯这种方法,因为大多数现有API都是如此。
答案 2 :(得分:0)
您需要在该点使用反射并将找到的反射属性与strtolower进行比较,但仍然使用区分大小写的版本通过isset或您希望使用的任何其他方法调用该属性。
http://www.php.net/manual/en/reflectionclass.getproperties.php