2009/04/23

php simplexml object to array

一般使用simplexml来解析xml文档,比较方便,但有时侯需要把文档转为php的标准数组来操作。

下面写了一个函数用来把simplexml对象转换为数组,支持SimpleXMLElement和SimpleXMLIterator对象。


<?php

//simplexml文档对象转换为标准数组
function simplexml_obj2array($obj)
{   
    if( count($obj) >= 1 )
    {
        $result = $keys = array();
       
        foreach( $obj as $key=>$value)
        {  
            isset($keys[$key]) ? ($keys[$key] += 1) : ($keys[$key] = 1);
           
            if( $keys[$key] == 1 )
            {
                $result[$key] = simplexml_obj2array($value);
            }
            elseif( $keys[$key] == 2 )
            {
                $result[$key] = array($result[$key], simplexml_obj2array($value));
            }
            else if( $keys[$key] > 2 )
            {
                $result[$key][] = simplexml_obj2array($value);
            }
        }
        return $result;
    }
    else if( count($obj) == 0 )
    {
        return (string)$obj;
    }
}
?>


示例:
<?php

$string = '<?xml version="1.0" encoding="UTF-8"?> 
<root>
<name><![CDATA[三叶草]]></name>
<url><![CDATA[http://bloomandkevin.cn]]></url>
<items>
    <product>
        <name><![CDATA[三叶草]]></name>
        <url><![CDATA[http://bloomandkevin.cn]]></url>
    </product>
    <product>
        <name><![CDATA[三叶草]]></name>
        <url><![CDATA[http://bloomandkevin.cn]]></url>
    </product>
</items>
</root>
';

var_dump( simplexml_obj2array(simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA)));

?>


结果:
array(3) {
  ["name"]=>
  string(9) "三叶草"
  ["url"]=>
  string(23) "http://bloomandkevin.cn"
  ["items"]=>
  array(1) {
    ["product"]=>
    array(2) {
      [0]=>
      array(2) {
        ["name"]=>
        string(9) "三叶草"
        ["url"]=>
        string(23) "http://bloomandkevin.cn"
      }
      [1]=>
      array(2) {
        ["name"]=>
        string(9) "三叶草"
        ["url"]=>
        string(23) "http://bloomandkevin.cn"
      }
    }
  }
}


缺点:
丢失了XML节点中的属性值。

2009/04/20

Linux下PHP保持进程唯一运行


<?php

//确认进程唯一,防止死掉
function check_proc() {
    if( $pidfile = @file_get_contents("./my.pid") )
    {
        list($pid, $last_time) = explode(",", $pidfile);       
        if( $link = @readlink("/proc/{$pid}/exe") )
        {
            if( time()-$last_time > 60*60 )//1 hour
            {
                //超时KILL掉那个进程
                system("kill -9 {$pid}");
            }else{
                echo "already exist, process exit.\n";
                exit;
            }
        }
    }
    //写入当前PID信息
    file_put_contents("./my.pid", getmypid().','.time() );
}

?>


getmypid()获取进程的ID。

在PHP程序起始处运行此函数,即可确保进程唯一,且可以踢掉超时的进程。

也可以使用shell_exec("ps aux|grep ".$pid)来判断进程是否存在。对Linux越熟悉就越多方法。