Что мне не хватает? - PDO + транзакция + несколько запросов -
ОБНОВЛЕНО - СМОТРИТЕ ДОПОЛНЕНИЕ
Хорошо, прямо сейчас, я не разработчик (может быть, когда-нибудь), я почти ничего не знаю, классы, функции, методы, обертки, foos, бары и, прежде всего, ООП, сбивают с толку вечно любящих меня. При этом я уверен, что есть много вещей, которые я мог бы сделать лучше, и пригласить вашу критику и знания. Тем не мение...
Мой конкретный вопрос заключается в следующем: я упускаю некоторые жизненно важные условия взаимодействия между WSDL, из которого я получаю данные, и PHP+PDO, MySQL combo, и все будет разваливаться, как только я нажму?
Три таблицы в приведенном ниже коде должны нормализовать довольно большой набор данных, полученный через клиентскую веб-службу. Эта часть представляет собой автоматизированный процесс (задание cron), который извлекает код из 6 других файлов. Мне пришлось внести некоторые изменения в базу данных, чтобы приспособить нового клиента, и я решил, что WTH, давайте попробуем PDO еще раз. Только теперь я не чувствую, что меня почти смущает код, который я вижу, чтобы он, возможно, делал все правильно (да, я проверял это много раз сегодня, многократный импорт, все прошло без проблем) Я готовлюсь выпустить последнее обновление завтра, и, честно говоря, я немного волнуюсь, что пропустил что-то серьезное, и получу кучу поврежденных данных, пока меня не будет на этой неделе. Извините, если это кажется неважным, но я провел много времени на сайтах, подобных этим, и, зная, как мало, большая часть информации либо предполагает слишком много, либо углубляется в вещи, в которых я еще не компетентен (см. Список наверху).
Я сделал что-то здесь не так, или это именно то, почему PDO является удивительным? Если нет, могу ли я сделать это более красноречиво? Я пропускаю некоторые обстоятельства, при которых ON DUPLICATE KEY UPDATE
не собирается продолжать делать свою работу и т.д...?
К вашему сведению: в последней таблице нет уникальных данных, кроме моего основного номера автонумерации. Существует составной уникальный ключ, сделанный из 3 полей, включая иностранный из предыдущей вставки. Бизнес-правила допускают такие рассуждения. Все 3 связаны между собой, table1 является их конечным родителем, 2 следующие и т.д.
<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>
Сложение
ОБНОВЛЕНИЕ Чтобы успокоить богов форумной земли, вот что я узнал. Также для 1 парня через 3 года, который на самом деле будет читать это, и злиться, на него никогда не отвечали! Это для тебя чувак!
Во-первых, я до сих пор не могу делать уроки правильно, ООП по какой-то причине является трудным прыжком для моего мозга, но если они изменят мою жизнь кода так же, как и функции, я не могу ждать (да, наконец-то я это сделал обернуть мой простой ум вокруг функций, вроде).
ЗОП УДИВИТЕЛЬНЫЙ!!!
Нераскрытые или неправильно экранированные данные - отстой! Носил мою X для шляпы в течение недели из-за человека по имени O'malley и улицы с именем CRS'Road. Если вы не знаете, что это значит, ТРАТИТЕ ВРЕМЯ И ПРОЧИТАЙТЕ ОБ ЭТОМ! Жаль, что я замедлился и сделал с самого начала.
ПОСЛЕДНО И НАИБОЛЕЕ ВАЖНО - я все еще студент, очень зеленый и голодный. Итак, еще раз, я уверен, что я сделал некоторые вещи здесь, которые не являются хорошими или не самыми лучшими. Я приглашаю вашу критику, и на самом деле с нетерпением жду этого!
<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>
PS Спасибо Майку Перселлу за быстрый и простой ответ, который он предложил кому-то еще, на мой последний вопрос. ЗОП не уклоняется от кавычек