Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Monday, 24 September 2018

PHP – Fix “Input is not proper UTF-8, indicate encoding” error when loading xml

When loading xml files in php through simplexml_load_string or domDocument class, sometimes an error like this might popup

Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding !
OR
Warning: simplexml_load_string(): Entity: line 93: parser error : Input is not proper UTF-8, indicate encoding !
The error occurs when the xml has some invalid characters that do not fit in the utf-8 character set. The solution to fix this error is quite simple. Just convert the entire xml string to ut8 first and then load.
1
$xml = simplexml_load_string( utf8_encode($rss) );
The utf8_encode function will convert the string to proper utf8 and invalid characters would be fixed, making the xml parseable by simplexml or domdocument.

Monday, 3 September 2018

PHP Mysql Cleaning xml data using the str_ireplace function

When I ran the Script, it stores blanks in the database. Where am I going wrong. Below is the php script:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$request= <<<XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:c2b="http://cps.huawei.com/cpsinterface/c2bpayment">
<soapenv:Header/>
<soapenv:Body>
  <c2b:C2BPaymentValidationRequest>
     <TransactionType>PayBill</TransactionType>
     <TransID>1234560000007031</TransID>
     <TransTime>20140227082020</TransTime>
     <TransAmount>123.00</TransAmount>
     <BusinessShortCode>12345</BusinessShortCode>
<BillRefNumber></BillRefNumber>
     <InvoiceNumber></InvoiceNumber>
<MSISDN>254722703614</MSISDN>
     <KYCInfo>
  <KYCName>[Personal Details][First Name]</KYCName>
  <KYCValue>Hoiyor</KYCValue>
</KYCInfo>
<KYCInfo>
  <KYCName>[Personal Details][Middle Name]</KYCName>
  <KYCValue>G</KYCValue>
</KYCInfo>
<KYCInfo>
  <KYCName>[Personal Details][Last Name]</KYCName>
  <KYCValue>Chen</KYCValue>
</KYCInfo>
  </c2b:C2BPaymentValidationRequest>
</soapenv:Body>
</soapenv:Envelope>
 XML;
//clean the soap input received from Mpesa so that you can parse it as raw XML

$clean_xml = str_replace(['soapenv:','c2b:' ],'', $request);
$xml = simplexml_load_string($clean_xml);
//you can extract any payment details using the below code
$server = '';
$user = '';
$pass = '';
$db  = ''; 

 foreach ($xml as $key => $cur)

 {
 //VALUES
  $AccountNo = $cur->BillRefNumber;
   $TransAmount = $cur->TransAmount;
  $TransID = $cur->TransID;
  $KYCInfo = $cur->KYCInfo;
  $MSISDN = $cur->MSISDN;                                                                                       

//SAVE TO DATABASE
$link= mysql_connect($server,$user,$pass) or die (mysql_error());
$conn= mysql_select_db($db) or die (mysql_error($link));
$query = "INSERT INTO c2b(TransID,MSISDN,BillRefNumber,KYCInfo,Amount) VALUES('$TransID','$MSISDN','$AccountNo','$KYCInfo','$TransAmount')";

if (!mysql_query($query))
{
die('Error: ' . mysql_error());
}
else
{
echo "New Records added successfully ! <br /><br />";
}
}                                                                                                                  

?>

I suspect that the error is in parsing the xml data using the str_ireplace function. I have looked at the PHP documentation and it seems that I have done everything by the book.

I suggest you use PDO at these points:
$link= mysql_connect($server,$user,$pass) or die (mysql_error());
$conn= mysql_select_db($db) or die (mysql_error($link));

I suggest this
class systemConfigs{
     public $conn;

     private $DBhost = 'localhost';
     private $DBname = 'mydbname';
     private $DBuser = 'dbuser';
     private $DBpwd  = 'dbpass';

     function __construct(){
        $this->dbConnect();
     }

     private function dbConnect(){
        $conn = null;
        try{
              $this->conn = new PDO("mysql:host=" . $this->DBhost  .";port=3306; dbname=" . $this->DBname, $this->DBuser, $this->DBpwd);
              $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
           }
           catch(PDOException $e){
              $conn = $e->getMessage();
           }

           return $conn;
       }

       /**
       * @param $sql
       * @return PDOStatement
       */
       public function runQuery($sql){
          $stmt = $this->conn->prepare($sql);
          return $stmt;
       }

       /**
       * @return string
       */
       public function lastID(){
         $stmt = $this->conn->lastInsertId();
         return $stmt;
       }

      public function insertC2B($TransID, $MSISDN, $AccNo, $KYCInfo, $Amount){
         $result = null;
         try{
               $sql = "INSERT INTO c2b(TransID,MSISDN,BillRefNumber,KYCInfo,Amount) VALUES(':TransID',':MSISDN',':AccountNo',':KYCInfo',':TransAmount')";
               $stmt = $this->runQuery($sql);
               $stmt->bindParam(':TransID', $TransID);
               $stmt->bindParam(':MSISDN', $MSISDN);
               $stmt->bindParam(':AccountNo', $AccountNo);
               $stmt->bindParam(':KYCInfo', $KYCInfo);
               $stmt->bindParam(':TransAmount', $Amount);
               $stmt->execute();

               $result = $this->lastID();
            } catch (PDOException $e){
               $result = $e->getMessage();
            }
            return $result;
         }
      }

Friday, 31 August 2018

Problem of building an associative array from xml

I'm trying to build an associative array from XML. Here is what xml looks like (total of about 70 'item' entries):

<xmldata>
<source>source</source>
<release>release</release>
 <item>
  <name>Name</name>
  <date>1/1/2015</date>
  <time>10AM</time>
  <value>24</value>
 </item>
 <item>
  <name>Name</name>
  <date>1/1/2015</date>
  <time>10AM</time>
  <value>24</value>
 </item>
etc
...
</xmldata>

Here is what I've tried so far:
$data = file_get_contents("xml url");
$xml = simplexml_load_string($data);
$counter = 1;
$new_array = array();
foreach($xml->children() as $item)
{
  if($counter > 2)
  {
    $temp_array = array('name' => $item->name, 'value' => $item->value);
    array_push($newArray, $temp_array);
  }
}

I'm trying to build an associative array that looks like this:
$new_array = array(array("name"=>name, "value"=>value),array("name"=>name,  "value"=>value),array("name"=>name, "value"=>value), etc);

It's not working. I try to print the array to see if it is formed but I get a list of 0-array, 1-array, etc.
I've also tried array_merge(), and $new_array[] = $item, and array_push($new_array, array("name"=>name, "value"=>value));
Is there a preferred way to append associative arrays onto an array? i.e. like array.append(dict) in python? Thanks much!

try like that
$data = file_get_contents("xml url");
$xml = simplexml_load_string($data);
$counter = 1;
$new_array =[];
foreach($xml->children() as $item)
{
    $new_array[$counter]['name'] = $item->name;
    $new_array[$counter]['value'] = $item->value;
    $counter += 1;
}

Tuesday, 14 August 2018

Backup Your Database into an XML File Using PHP

Backing up data is extremely important. Most of the time the database is the most important piece of the puzzle. Imagine losing all of the data in your database -- it would be tragic. Here's a PHP snippet that outputs your database as XML.


The PHP
//connect
$link = mysql_connect($host,$user,$pass);
mysql_select_db($name,$link);

//get all the tables
$query = 'SHOW TABLES FROM '.$name;
$result = mysql_query($query,$link) or die('cannot show tables');
if(mysql_num_rows($result))
{
//prep output
$tab = "\t";
$br = "\n";
$xml = '<?xml version="1.0" encoding="UTF-8"?>'.$br;
$xml.= '<database name="'.$name.'">'.$br;

//for every table...
while($table = mysql_fetch_row($result))
{
//prep table out
$xml.= $tab.'<table name="'.$table[0].'">'.$br;

//get the rows
$query3 = 'SELECT * FROM '.$table[0];
$records = mysql_query($query3,$link) or die('cannot select from table: '.$table[0]);

//table attributes
$attributes = array('name','blob','maxlength','multiple_key','not_null','numeric','primary_key','table','type','default','unique_key','unsigned','zerofill');
$xml.= $tab.$tab.'<columns>'.$br;
$x = 0;
while($x < mysql_num_fields($records))
{
$meta = mysql_fetch_field($records,$x);
$xml.= $tab.$tab.$tab.'<column ';
foreach($attributes as $attribute)
{
$xml.= $attribute.'="'.$meta->$attribute.'" ';
}
$xml.= '/>'.$br;
$x++;
}
$xml.= $tab.$tab.'</columns>'.$br;

//stick the records
$xml.= $tab.$tab.'<records>'.$br;
while($record = mysql_fetch_assoc($records))
{
$xml.= $tab.$tab.$tab.'<record>'.$br;
foreach($record as $key=>$value)
{
$xml.= $tab.$tab.$tab.$tab.'<'.$key.'>'.htmlspecialchars(stripslashes($value)).'</'.$key.'>'.$br;
}
$xml.= $tab.$tab.$tab.'</record>'.$br;
}
$xml.= $tab.$tab.'</records>'.$br;
$xml.= $tab.'</table>'.$br;
}
$xml.= '</database>';

//save file
$handle = fopen($name.'-backup-'.time().'.xml','w+');
fwrite($handle,$xml);
fclose($handle);
}
You probably don't NEED to add column nodes but I like including as much data as possible and they don't add very much to the total file size.

The Sample Output
<database name="my_database">
<table name="wp_comments">
<columns>
<column name="comment_ID" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="1" primary_key="1" table="wp_comments" type="int" default="" unique_key="0" unsigned="1" zerofill="0" />
<column name="comment_post_ID" blob="0" maxlength="" multiple_key="1" not_null="1" numeric="1" primary_key="0" table="wp_comments" type="int" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_author" blob="1" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="blob" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_author_email" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_author_url" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_author_IP" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_date" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="datetime" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_date_gmt" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="datetime" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_content" blob="1" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="blob" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_karma" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="1" primary_key="0" table="wp_comments" type="int" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_approved" blob="0" maxlength="" multiple_key="1" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_agent" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_type" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_comments" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="comment_parent" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="1" primary_key="0" table="wp_comments" type="int" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="user_id" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="1" primary_key="0" table="wp_comments" type="int" default="" unique_key="0" unsigned="0" zerofill="0" />
</columns>
<records>
<record>
<comment_ID>2</comment_ID>
<comment_post_ID>4</comment_post_ID>
<comment_author>Ryan</comment_author>
<comment_author_email>ryantastad@hotmail.com</comment_author_email>
<comment_author_url></comment_author_url>
<comment_author_IP>66.84.199.242</comment_author_IP>
<comment_date>2007-12-06 10:10:38</comment_date>
<comment_date_gmt>2007-12-06 16:10:38</comment_date_gmt>
<comment_content>Roethlisberger is coming to town!?  Sorry, Fred.</comment_content>
<comment_karma>0</comment_karma>
<comment_approved>1</comment_approved>
<comment_agent>Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322)</comment_agent>
<comment_type></comment_type>
<comment_parent>0</comment_parent>
<user_id>0</user_id>
</record>
</records>
</table>
<table name="wp_links">
<columns>
<column name="link_id" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="1" primary_key="1" table="wp_links" type="int" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_url" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_links" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_name" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_links" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_image" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_links" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_target" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_links" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_category" blob="0" maxlength="" multiple_key="1" not_null="1" numeric="1" primary_key="0" table="wp_links" type="int" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_description" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_links" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_visible" blob="0" maxlength="" multiple_key="1" not_null="1" numeric="0" primary_key="0" table="wp_links" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_owner" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="1" primary_key="0" table="wp_links" type="int" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_rating" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="1" primary_key="0" table="wp_links" type="int" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_updated" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_links" type="datetime" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_rel" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_links" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_notes" blob="1" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_links" type="blob" default="" unique_key="0" unsigned="0" zerofill="0" />
<column name="link_rss" blob="0" maxlength="" multiple_key="0" not_null="1" numeric="0" primary_key="0" table="wp_links" type="string" default="" unique_key="0" unsigned="0" zerofill="0" />
</columns>
<records>
<record>
<link_id>1</link_id>
<link_url>http://codex.wordpress.org/</link_url>
<link_name>Documentation</link_name>
<link_image></link_image>
<link_target></link_target>
<link_category>0</link_category>
<link_description></link_description>
<link_visible>Y</link_visible>
<link_owner>1</link_owner>
<link_rating>0</link_rating>
<link_updated>0000-00-00 00:00:00</link_updated>
<link_rel></link_rel>
<link_notes></link_notes>
<link_rss></link_rss>
</record>
<record>
<link_id>2</link_id>
<link_url>http://wordpress.org/development/</link_url>
<link_name>Development Blog</link_name>
<link_image></link_image>
<link_target></link_target>
<link_category>0</link_category>
<link_description></link_description>
<link_visible>Y</link_visible>
<link_owner>1</link_owner>
<link_rating>0</link_rating>
<link_updated>0000-00-00 00:00:00</link_updated>
<link_rel></link_rel>
<link_notes></link_notes>
<link_rss>http://wordpress.org/development/feed/</link_rss>
</record>
</records>
</table>
</database>
XML isn't the easiest format to restore a table with so you may prefer to export the table as SQL statements. I enjoy the additional XML backup because it's easy to read.