我从API获得一个XML响应,并使用simplexml_load_string将其转换为PHP中的对象。然后,我将对象直接存储到mongo数据库中,它非常完美。问题是因为它来自XML,所以mongo中所有的节点都是"字符串"类型。有没有一种奇特或简单的方法可以遍历PHP对象中的所有节点并转换为integer、float或boolean?如果我手动拉出所有节点,我可以使用"intval"one_answers"floatval",但我想看看是否有可能根据内容自动完成。ie.不管深度如何,循环遍历所有节点,并对0-9执行preg_match,将项设置为类型"int"。如果0-9 w/。设置为浮动。如果true/false/0/1设置为bool。把剩下的绳子留着。有什么想法吗?
$this->response_object = simplexml_load_string($xml);
SimpleXMLElement
类的神奇特性,您无法通过扩展它来改变这一点
但是,您可以从SimpleXMLElement
进行扩展,并添加一个名为typecastValue()
(示例)的函数来完成这项工作。然后可以使用simplexml_load_string
指定要使用该类而不是默认的SimpleXMLElement
类。
class MyElement extends SimpleXMLElement
{
public function typecastValue() {
$value = trim($this);
// check if integer, set as float
if (preg_match('/^[0-9]{1,}$/', $value)){
return floatval($value);
}
// check if float/double
if (preg_match('/^[0-9.]{1,}$/', $value)){
return floatval($value);
}
// check if boolean
if (preg_match('/(false|true)/i', $value)){
return (boolean)$value;
}
// all else leave as string
return $value;
}
}
正如您所看到的,该代码与上面的typecast函数非常相似,它只是使用$this
来获得原始值。
像xml_object_to_array
这样的函数通常仍然是多余的,因为解析已经完成,您更关心的是访问XML中的日期并将其序列化为数组(我怀疑这是由于Mongodb的JSON需求,但我不知道)。如果是这样的话,PHP JSON序列化会更合适,因为对于SimpleXMLElement
,我们已经在网站上有了现有的材料。
- Json对XML进行编码或序列化
我想我找到了自己的答案(除非你有更优雅的方式)。。。
function xml_object_to_array($xml) {
if ($xml instanceof SimpleXMLElement) {
$children = $xml->children();
$return = null;
}
foreach ($children as $element => $value) {
if ($value instanceof SimpleXMLElement) {
$values = (array)$value->children();
if (count($values) > 0) {
$return[$element] = xml_object_to_array($value);
} else {
if (!isset($return[$element])) {
$return[$element] = typecast_value($value);
} else {
if (!is_array($return[$element])) {
$return[$element] = array($return[$element], typecast_value($value));
} else {
$return[$element][] = typecast_value($value);
}
}
}
}
}
if (is_array($return)) {
return $return;
} else {
return false;
}
}
// auto typecast value for mongo storage
function typecast_value($value){
$value = trim($value);
// check if integer, set as float
if(preg_match('/^[0-9]{1,}$/', $value)){
return floatval($value);
}
// check if float/double
if(preg_match('/^[0-9.]{1,}$/', $value)){
return floatval($value);
}
// check if boolean
if(preg_match('/(false|true)/i', $value)){
return (boolean)$value;
}
// all else leave as string
return $value;
}