4

UPDATED - SEE THE ADDITION BELOW

OK, straight away, I'm not a developer (maybe someday), I know almost nothing, classes, functions, methods, wrappers, foos, bars, and most of all OOP confuse the ever-loving-S out of me. That being said, I'm sure there are lots of things I could do better, and invite your criticism and knowledge. However...

My specific question is this: Am I missing some vital condition of the interaction between the WSDL I'm receiving the data from, and the PHP+PDO, MySQL combo, and everything is going to fall apart as soon as I push?

The three tables in the code below must normalize a rather large dataset received via a clients Web Service, this portion is an automated process (cron job) that pulls code from 6 other files. I had to make some changes to the database to accommodate a new client, and I figured WTH, let's give PDO a try again. Only now I don't feel like I'm nearly confused enough by the code I see for it to possibly be doing it right (yes I've tested it many times today, multiple imports, all went off without a hitch) I'm getting ready to push the latest update sometime tomorrow, and I'm honestly a little worried I missed something major, and will wind up with a bunch of corrupt data while I'm out of town this week. Sorry if it seems unimportant, but I've spent alot of time on sites like these, and knowing as little as I do, most of the info either assumes too much, or dives into things I'm not competent in yet (see list at top).

Did I do something wrong here, or is this exactly why PDO is awesome? If no, can I do this more eloquently? Am I missing some circumstance in which ON DUPLICATE KEY UPDATE is not going to keep doing it's job etc...?

FYI: The last table has no unique data in it except my autonumber primary. There is a composite unique key made from 3 fields including a foreign from the previous insert. Business rules allow for this type of reasoning. All 3 are related, table1 is the ultimate parent of them, 2 the next etc...

<pre><code><?php

// connect to db Mysqli style
require_once 'MysqliCurrentLoginQuery.file'; //get the variables not supplied below

/*~~~~~~~~~~~~~~~~SET YOUR VARIABLES HERE~~~~~~~~~~~~~~~~~*/
/*A bunch of soap variables to be passed to MySOAPReq.file*/
/*~~~~~~~~~~~~~~~~SET YOUR VARIABLES HERE~~~~~~~~~~~~~~~~~*/

 require_once 'MySOAPRequest.file'; //This is where $soapresult is passed from

 //convert array to ph objects for use in prepared stmt
 $xmlResponse = new SimpleXMLElement($soapresult);
    foreach ($xmlResponse->xmlWorkOrders->workOrder as $order) {       
        try {
            require 'MyPDOdbConfigAndConnection.file'; //where $conn is passed from
            $conn->beginTransaction();
                    try {
                        $query1 = "INSERT INTO table(`id`,`b`,`c`,`d`) 
                            VALUES ('" . "','". 1 . "','". 1 . "','". $order->D . "')
                            ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id),d=$order->D";
                        $result1 = $conn->prepare($query1);
                        $result1->execute();
                        $lastid = $conn->lastInsertID();
                    } catch(PDOExecption $e) {
                        $conn->rollback();
                        print "Error!: " . $e->getMessage() . "</br>";
                    }
                    try {                                
                        $query2 = "INSERT INTO table2(`id`, `f`, `g`) 
                            VALUES ('" . "','" . $order->F . "','" . $lastid . "')
                            ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), f=$order->F";
                        $result2 = $conn->prepare($query2);
                        $result2->execute();
                        $lastid = $conn->lastInsertID();
                        print "<br />" . $conn->lastInsertID() . "<br />";
                    } catch(PDOExecption $e) {
                        $conn->rollback();
                        print "Error!: " . $e->getMessage() . "</br>";
                    }
                    try {
                        $dnsdateparts=explode(' ',$order->H);
                        $query3 = "INSERT INTO table3(`id`, `g`, `h`, `i`) 
                            VALUES ('" . "','" . $order->G . "', STR_TO_DATE('" . $dateparts[0] . "','%m/%d/%Y'),'" . $dateparts[1] . "')
                            ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), g=G, h=H, i=$lastid";
                        $result3 = $conn->prepare($query3);
                        $result3->execute();
                        $conn->commit();                        
                    } catch(PDOExecption $e) {
                        $conn->rollback();
                        print "Error!: " . $e->getMessage() . "</br>";

                    }                   
        } catch( PDOExecption $e ) {
            print "Error!: " . $e->getMessage() . "</br>";                 
        }                     
    }
?><code><pre>

ADDITION

UPDATE To appease the Gods of forumland, here is what I learned. Also for the 1 guy 3 years from now who will actually read this, and be mad it was never answered! This is for you dude!

First of all, I still can't do classes right, OOP is a difficult jump for my brain for some reason, but if they will change my code-life as much as functions did, I can't wait (yes I did finally wrap my simple mind around functions, sort of).

PDO IS AWESOME!!!

Un-escaped, or improperly escaped data sucks! Wore my X for hat for a week because of a person named O'malley, and a street named CRS'Road. If you don't know what it means, WASTE YOUR TIME AND READ ABOUT IT! Wish I slowed down and did from the start.

LASTLY AND MOST IMPORTANT - I'm still a student, a very green and hungry one at that. So once again, I'M SURE I have done some things here that are not good, or not-best. I invite your criticism, and in fact look forward to it!

<pre><code>
<?php

// I actually got some functions to work!!
// So everything necesary self-requires from one required file
require_once ('/path/to/this/file/some.functions.php');


/*~~~~~~~~~~~~~~~~SET YOUR VARIABLES HERE~~~~~~~~~~~~~~~~~*/
/*A bunch of soap variables to be passed to MySOAPReq.file*/
/*~~~~~~~~~~~~~~~~SET YOUR VARIABLES HERE~~~~~~~~~~~~~~~~~*/

// Uses function from some.functions.php
$soapresult = mySoapClientMaker($avariable, $anothervariable);


 //convert array to ph objects for use in prepared stmt
 $xmlResponse = new SimpleXMLElement($soapresult);
    foreach ($xmlResponse->xmlWorkOrders->workOrder as $order) {       
        try {
            //$conn is now already there from some.functions.php
            $conn->beginTransaction();
                    try {
                        // Create the query string and store it in a variable
                        $query1 = "INSERT INTO table(`id`,`b`,`c`,`d`) "
                            . "VALUES (:col1, :col2, :col3, :col4)"
                            . "ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id),d=" . $order->D;

                        // Prepare the query i.e. assemble the pieces of the string 
                        $result1 = $conn->prepare($query1);

                        // Bind Values/Params
                        // PDO will not properly escape everything in the inserts without this
                        // This was the source of the broken import, lesson learned
                        $result1 ->bindValue(':col1', NULL, PDO::PARAM_NULL);
                        $result1 ->bindValue(':col2', 1, PDO::PARAM_INT);
                        $result1 ->bindValue(':col3', 1, PDO::PARAM_INT);
                        $result1 ->bindValue(':col4', $order->D, PDO::PARAM_STR);

                        // Execute (still in try mode) the now prepared/escaped query
                        $result1->execute();

                        // Remember the primary key from this insert to use as
                        // the foreign key in the next insert
                        $lastid = $conn->lastInsertID();

                    } catch(PDOExecption $e) {
                        // If your insert breaks, here everything
                        // goes back to its pre-insert state. 
                        $conn->rollback();
                        print "Error!: " . $e->getMessage() . "</br>";
                    }
                    // Repeat as above
                    try {                                
                        $query2 = "INSERT INTO table2(`id`, `f`, `g`) "
                            . "VALUES (:col1, :col2, :col3) "
                            . "ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), f=" . $order->F;

                        $result2 = $conn->prepare($query2);

                        $result2 ->bindValue(':col1', NULL, PDO::PARAM_NULL);
                        $result2 ->bindValue(':col2', 1, PDO::PARAM_INT);   
                        $result2 ->bindValue(':col3', $order->D, PDO::PARAM_INT);

                        $result2->execute();
                        $lastid = $conn->lastInsertID();

                    } catch(PDOExecption $e) {
                        $conn->rollback();
                        print "Error!: " . $e->getMessage() . "</br>";
                    }
                    // Repeat as above again
                    try {
                        $dateparts=explode(' ',$order->H);
                        $query3 = "INSERT INTO table3(`id`, `g`, `h`, `i`) "
                            . "VALUES (:col1, :col2, :col3, :col4) "
                            . "ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), g=G, h=H, i=" . $lastid;

                            VALUES ('" . "','" . $order->G . "', STR_TO_DATE('" . $dateparts[0] . "','%m/%d/%Y'),'" . $dateparts[1] . "')                           
                        $result3 = $conn->prepare($query3);

                        $result3 ->bindValue(':col1', NULL, PDO::PARAM_NULL);
                        $result3 ->bindValue(':col2', $order->G, PDO::PARAM_INT);
                        $result3 ->bindValue(':col3', "STR_TO_DATE(" . $dnsdateparts[0] . "','%m/%d/%Y')", PDO::PARAM_STR);
                        $result3 ->bindValue(':col4', $dateparts[1], PDO::PARAM_STR);

                        $result3->execute();

                        // NOW if everything made it this far without error
                        // it will all be committed to the db
                        $conn->commit();

                    } catch(PDOExecption $e) {
                        $conn->rollback();
                        print "Error!: " . $e->getMessage() . "</br>";
                    }                   
        } catch( PDOExecption $e ) {
            print "Error!: " . $e->getMessage() . "</br>";                 
        }                     
    }
?>
<code><pre>

P.S. Thanks to Mike Purcell for the quick and simple answer he offered someone else, to my latest question. PDO not escaping quotes

Community
  • 1
  • 1
Michael Chad
  • 425
  • 4
  • 14
  • **UPDATE** The sun came up every day while I was OOT, I still have a heartbeat, and earth still revolves around the sun! I think that means no major corruption event! I did however run a few log reports and found that there was one import that completed the insert into table1 and table2, but not table 3, the problems were resolved by a backup process that queries the 3 for a frequently used report, and also looks for specific empty fields and attempts to resolve the nulls. So no harm done! I will post updated code once I figure out why the transaction didn't roll back. – Michael Chad May 14 '12 at 12:24

0 Answers0