philishake
javascript enthusiast
Hey Community,
ich versuche mich gerade an MySQLi Transaktionen mit PHP. Hier mal erst mal mein Setup:
PHP 5.6.12
MySQL 5.6.19
Alle meine Tabellen sind mit InnoDB Engine.
Ich habe einen endpoint /api/account/get.php. Dieser endpoint schickt ein Account objekt zurueck. Sollte kein Account existieren, dann wird automatisch ein neuer erstellt. Mein Databasemanager mapped eigentlich nur die Funktionen, die es im mysqli Objekt gibt. Der unten aufgefuehrte Code ist fuer einen Prototyp, kein echter Produktionscode, daher ist er vielleicht nicht ganz optimal. Die ganzen printf sind zum testen, dadurch weiss ich auch, dass der Code nicht doppelt ausgefuehrt wird.
NUR der INSERT in die accounts Tabelle wird doppelt ausgefuehrt, alle anderen nur einmal, so wie es auch sein sollte.
Hier mal ein bisschen Code:
/api/account/get.php
Account class
ich versuche mich gerade an MySQLi Transaktionen mit PHP. Hier mal erst mal mein Setup:
PHP 5.6.12
MySQL 5.6.19
Alle meine Tabellen sind mit InnoDB Engine.
Ich habe einen endpoint /api/account/get.php. Dieser endpoint schickt ein Account objekt zurueck. Sollte kein Account existieren, dann wird automatisch ein neuer erstellt. Mein Databasemanager mapped eigentlich nur die Funktionen, die es im mysqli Objekt gibt. Der unten aufgefuehrte Code ist fuer einen Prototyp, kein echter Produktionscode, daher ist er vielleicht nicht ganz optimal. Die ganzen printf sind zum testen, dadurch weiss ich auch, dass der Code nicht doppelt ausgefuehrt wird.
NUR der INSERT in die accounts Tabelle wird doppelt ausgefuehrt, alle anderen nur einmal, so wie es auch sein sollte.
Hier mal ein bisschen Code:
/api/account/get.php
PHP:
<?php
require_once '../../php/bootstrap.php';
require_once '../../php/config/database.php';
require_once '../../php/DatabaseManager.php';
require_once '../../php/Account.php';
printf("Receive request data<br />");
$username = $_REQUEST['username'];
$externalId = $_REQUEST['externalId'];
printf("Setup database<br />");
$dbms = new DatabaseManager();
$dbms->setHostname($config->database->hostname);
$dbms->setUsername($config->database->username);
$dbms->setPassword($config->database->password);
$dbms->setTable($config->database->table);
printf("Account handler<br />");
$account = new Account($externalId, $username);
$account->setDBMS($dbms);
$account->fetchAccountId();
printf("create account if not already there<br />");
$message = "";
if ($account->hasAccount()) {
$message = "Account Found";
printf("Account found<br />");
} else {
$message = "No Account Found. New one was created";
printf("Account not found<br />");
$account->createAccount();
}
printf("create resopnse<br />");
$response = new stdClass();
$response->username = $account->getUsername();
$response->userId = $account->getAccountId();
$response->externalId = $account->getExternalId();
$response->message = $message;
die(json_encode($response));
?>
Account class
PHP:
<?php
require_once '../../php/bootstrap.php';
require_once '../../php/DatabaseManager.php';
require_once '../../php/config/game.php';
class Account {
private $id = null;
private $externalId;
private $username;
private $dbms;
function __construct($externalId, $username) {
printf("Account->__construct<br/>");
$this->externalId = $externalId;
$this->username = $username;
}
public function setDBMS($dbManager) {
printf("Account->setDBMS<br/>");
$this->dbms = $dbManager;
}
public function hasAccount() {
printf("Account->hasAccount<br/>");
return $this->id != null;
}
public function fetchAccountId() {
printf("Account->fetchAccountId<br/>");
$this->dbms->connect();
$accountRows = $this->dbms->query(
"SELECT id FROM accounts WHERE externalId='" .
$this->externalId . "'"
);
if ($accountRows->num_rows == 0) {
printf("Account->fetchAccountId: not found<br/>");
}
else if ($accountRows->num_rows == 1) {
printf("Account->fetchAccountId: found<br/>");
$account = $accountRows->fetch_object();
$this->id = $account->id;
}
else {
//TODO: Handle error somehow
printf("Account->fetchAccountId: weird stuff just happend<br/>");
}
$this->dbms->disconnect();
}
public function createAccount() {
printf("Account->createAccount<br/>");
$this->dbms->connect();
$this->dbms->autocommit(FALSE);
$this->dbms->beginTransaction(
DatabaseManager::$TRANSACTION_READ_WRITE,
"CREATE_NEW_ACCOUNT_" . time()
);
// Add to base tables
$this->addToAccountTable();
$this->addToCountryTable();
$this->addToResearchTable();
$this->addToResourcesTable();
$this->addToSettingsTable();
$this->addToStatsTable();
$this->addToUnitsTable();
// Complete transactions
$this->dbms->commit();
$this->dbms->disconnect();
}
private function addToAccountTable() {
printf("Account->addToAccountTable<br/>");
$currentTime = time();
$protection = $currentTime + $gameConfig->newbieProtection;
$this->dbms->query(
"INSERT INTO accounts (externalId, username, login, protection, registered) VALUES (
'{$this->externalId}', '{$this->username}', '{$currentTime}', '{$protection}', '{$currentTime}'
)"
);
// Receive account id after creating
$accountRow = $this->dbms->query("SELECT id FROM accounts WHERE externalId='{$this->externalId}'");
$account = $accountRow->fetch_object();
// Update accountId
$this->id = $account->id;
}
private function addToCountryTable() {
//TODO: TBD
}
private function addToResearchTable() {
$this->dbms->query(
"INSERT INTO research (userId, ironMining, silverMining, coining, espionage) VALUES (
'{$this->id}', 0, 0, 0, 0
)"
);
}
private function addToResourcesTable() {
$this->dbms->query(
"INSERT INTO resources (userId, iron, silver, gold) VALUES (
'{$this->id}',
'{$gameConfig->startingResources->iron}',
'{$gameConfig->startingResources->silver}',
'{$gameConfig->startingResources->gold}'
)"
);
}
private function addToSettingsTable() {
$this->dbms->query(
"INSERT INTO settings (userId) VALUES ('{$this->id}')"
);
}
private function addToStatsTable() {
$this->dbms->query(
"INSERT INTO stats (userId, points, general) VALUES (
'{$this->id}', 0, 0
)"
);
}
private function addToUnitsTable() {
$this->dbms->query(
"INSERT INTO units (userId, workers, soldiers, rocketeers, tanks, tigertanks, engineers) VALUES (
'{$this->id}', 0, 0, 0, 0, 0, 0
)"
);
}
public function getAccountId() {
return $this->id;
}
public function getExternalId() {
return $this->externalId;
}
public function getUsername() {
return $this->username;
}
}
?>