PHP:如何解析多层次对象的动态属性
我已经编写了一个helper函数来“清理”回调变量,以便输入MySQL。这是我写的函数:PHP:如何解析多层次对象的动态属性,php,mysql,string,object,amazon-web-services,Php,Mysql,String,Object,Amazon Web Services,我已经编写了一个helper函数来“清理”回调变量,以便输入MySQL。这是我写的函数: 公共函数字符串($object,$objectPath){ 如果(!empty($object->$objectPath)| |$object->$objectPath!=''){ $value=$object->$objectPath; }否则{ 返回'NULL'; } 如果(!empty($value)| |$value!=''){ 返回“'”。str_replace(“'”,“'',$value)。“
公共函数字符串($object,$objectPath){
如果(!empty($object->$objectPath)| |$object->$objectPath!=''){
$value=$object->$objectPath;
}否则{
返回'NULL';
}
如果(!empty($value)| |$value!=''){
返回“'”。str_replace(“'”,“'',$value)。“'”;
}否则{
返回'NULL';
}
}
现在,$object
始终是调用返回的对象,$objectPath
始终是指向给定值的字符串。这就是问题所在。这项工作:
$value = $this->db->string($object, 'foo');
但是,这不起作用:
$value = $this->db->string($object, 'foo->bar->foo1->bar1');
每当$objectPath
的深度超过“一层”时,我就会从(Amazon的)客户端库中得到以下错误:
Fatal error: Call to undefined method MarketplaceWebServiceOrders_Model_Order::getFoo->Bar() in /path/to/Model.php on line 63
错误引用的代码块如下所示:
public函数\uuuu get($propertyName)
{
$getter=“获取$propertyName”;
返回$this->$getter();//这是第63行
}
$object
不是XML,所以我不能使用simplexmlement
和XPath
我的代码有什么问题?是我连接了一个对象和一个字符串吗?如果是,我怎样才能做到这一点?我怎样才能让这个函数达到我想要的效果
顺便说一句,我使用的是PHP5.4.27。PHP不会像您尝试的那样自动将包含多个路径级别的字符串解析为对象的子对象 即使
$obj
包含您期望的子层次结构,这也将不起作用:
$obj = ...;
$path = 'level1->level2->level3';
echo $obj->$path; // WRONG!
您需要拆分路径并“漫游”对象,以尝试解析最终属性。
以下是一个基于您的示例:
<?php
$obj = new stdClass();
$obj->name = 'Fred';
$obj->job = new stdClass();
$obj->job->position = 'Janitor';
$obj->job->years = 4;
print_r($obj);
echo 'Years in current job: '.string($obj, 'job->years').PHP_EOL;
function string($obj, $path_str)
{
$val = null;
$path = preg_split('/->/', $path_str);
$node = $obj;
while (($prop = array_shift($path)) !== null) {
if (!is_object($obj) || !property_exists($node, $prop)) {
$val = null;
break;
}
$val = $node->$prop;
// TODO: Insert any logic here for cleaning up $val
$node = $node->$prop;
}
return $val;
}
在@itsmejodie的帮助下,我终于找到了一个可行的解决方案:
公共函数字符串($node,$objectPath){
$value=NULL;
$path=分解('->',$objectPath);
while(($prop=array\u shift($path))!==NULL){
如果(!$node->$prop){
打破
}
$value=$node->$prop;
$node=$node->$prop;
}
如果(是字符串($value)){
返回“'”。str_replace(“'”,“'',$value)。“'”;
}否则{
返回'NULL';
}
}
对我来说,关键是要看到,正如@itsmejodie所说,“PHP不会自动将包含多个路径级别的字符串解析为对象的子对象。”在类似于'foo->bar->foo1->bar2'
的字符串中,PHP不会将->
转换为t\u object\u操作符,从而将字符串附加到对象,例如。,$object->foo->bar->foo1->bar2
,就是不起作用 嗨,对不起,这对你不起作用。正如您可以从我提供的链接中看到的,它在标准对象上工作。您可以尝试更改!属性存在($node,$prop)
到isset($node->$prop)