将PHP对象转换为XML的类

Lee*_*Tee 3 php xml oop

我有以下课程.似乎可以使用具有一个级别的简单对象,但是当对象具有多个级别(多个数组)并且XML全部搞砸时不能正常工作.任何人都可以帮我改进这个,这样它可以用于任何对象吗?

class XMLGenerator
{ 
       function __construct($obj,$root, $element, $fullXML = true) {     

          $array = $this->object_2_array($obj);
          $this->output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
          $this->output .= $this->make($array, $root, $element, $fullXML);

       }

        //convert objects into arrays
        function object_2_array($result){

            $array = array();

            foreach ($result as $key => $value){

                if (is_object($value)){
                    $array[$key]=XMLGenerator::object_2_array($value);
                } elseif (is_array($value)){
                    $array[$key]=XMLGenerator::object_2_array($value);
                } else {
                    $array[$key]=$value;
                }
            }
            return $array;
        }   

       //make XML
       function make($array, $root, $element, $fullXML) {
          if (is_numeric($root)) {
             $xml = "<{$element}>\n";
          } else {
              $xml = "<{$root}>\n";
          }

          foreach ($array as $key => $value) {
             if (is_array($value)) {
                 if ($element == 'options'){  //workaround for orders 3 level problem, need to rethink this - LT
                    $xml .= $this->make($value, $key, $key, $fullXML); 
                 } else {
                    $xml .= $this->make($value, $element, $key, $fullXML);  
                 }              
             } else {

                 //any fields with HTML need wrapping in CDATA
                 if (($key === 'Description')||( $key === 'productDescription' )){
                    $value = '<![CDATA['. $value .']]>';
                 //remove any chars XML doesnt like  
                 } else {
                    $value = htmlentities($value,ENT_QUOTES, 'UTF-8');
                    $value = functions::xml_entities($value);    
                 }
                 //decide on node name

                if (is_numeric($key)) {
                   $xml .= "<{$root}>{$value}</{$root}>\n";
                } else {
                   $xml .= "<{$key}>{$value}</{$key}>\n";
                }           
             }
          }

          if (is_numeric($root)) {
             $xml .= "</{$element}>\n";
          } else {
              $xml .= "</{$root}>\n";
          } 

          return $xml;
       } 


       //save XML to file
       function saveFile($file){
            //create DOM to ensure all XML is valid before writing to file
            $doc = new DOMDocument();
            $doc->loadXML($this->output);

            if ($doc->save("$file")){
                return TRUE;
            } else {
                return FALSE;
            }
       }

}
Run Code Online (Sandbox Code Playgroud)

下面是一个简单的对象,适用于上面的类.

产品对象([db_connection:protected] => 3779074 [prod_id:protected] => 0 [店主:protected] => 0 [fields] =>数组(

        [productDescription] => Test
        [productName] => Test
        [UPC] => 123
    )
Run Code Online (Sandbox Code Playgroud)

)

以下根本不适用.

订单对象([db_connection:protected] => msSqlConnect对象([con] => [dbName] =>)

[skID:protected] => 89137
[orderID:protected] => 482325
[order] => Array
    (
        [id] => 482325
        [customer] => 491936
        [net] => 1565.98
        [vat] => 274.05
        [billing_address] => Address Object
            (
                [db_connection:protected] => msSqlConnect Object
                    (
                        [con] => 
                        [dbName] => 
                    )

                [custID:protected] => 491936
                [addID:protected] => 156928
                [fields] => Array
                    (
                        [id] => 156928
                        [surname] => test
                        [forename] => test
                        [add1] => 89 testRoad
                        [add2] => 
                        [city] => City
                        [country] => GB
                        [postcode] => POSTCODE
                    )

            )
        [items] => Array
            (
                [0] => Array
                    (
                        [id] => 716549
                        [headerID] => 482325
                        [productID] => 4084620
                        [net] => 22.99
                        [vat] => 4.0233
                        [qty] => 1
                        [options] => Array
                            (
                                [0] => Array
                                    (
                                        [id] => 
                                        [orderDetailsID] => 716549
                                        [optionid] => 763217
                                        [optionCost] => 100
                                        [optionVAT] => 17.5
                                    )

                                [1] => Array
                                    (
                                        [id] => 
                                        [orderDetailsID] => 716549
                                        [optionid] => 763241
                                        [optionCost] => 10
                                        [optionVAT] => 1.75
                                    )

                            )

                    )

                [1] => Array
                    (
                        [id] => 716551
                        [headerID] => 482325
                        [productID] => 3779074
                        [net] => 1400
                        [vat] => 245
                        [qty] => 1
                        [options] => 
                    )
            )
    ) )
Run Code Online (Sandbox Code Playgroud)

非常感谢您的帮助.

hak*_*kre 6

多个级别需要递归处理 - 因为您不知道前期级别的数量.在进行递归时,您还需要注意打开XML元素等等.

您所做的是将PHP对象序列化为XML.你不是第一个需要这个的人,PHP附带了一个遵循WDDX规范的XML序列化程序,例如使用以下wddx_serialize_value函数:

$object = (object) array('hello' => (object) array('value' => 'world') );

echo wddx_serialize_value($object);
Run Code Online (Sandbox Code Playgroud)

这将给出这个XML(演示):

<wddxPacket version='1.0'>
  <header/>
  <data>
    <struct>
      <var name='php_class_name'>
        <string>stdClass</string>
      </var>
      <var name='hello'>
        <struct>
          <var name='php_class_name'>
            <string>stdClass</string>
          </var>
          <var name='value'>
            <string>world</string>
          </var>
        </struct>
      </var>
    </struct>
  </data>
</wddxPacket>
Run Code Online (Sandbox Code Playgroud)

如果需要不同的输出,则需要自己编写序列化.在symfony2(Symfony2 Serializer Component)和Pear(XML_Serializer)中,您可以找到使用XML输出进行序列化的现有PHP代码.

  • 或使用XSLT更改wddxPacket XML (2认同)