0

I have one table called users (id, username, password), second table called profiles (id, user_id, username, name, lastname, age, gender, country, company_name), third table called companies (id, user_id, name, resources_id) and fourth table called resources (id, user_id, company_id, money). When users register their account, they need to create their profile. Now when they fill profile data, profiles and companies tables are filled just fine.

My problem is in resources table:

Error: Incorrect integer value: '' for column 'company_id' at row 1

When I refresh that page with error, resources table is filled fine, but now I got double rows for profiles and companies tables.

My Code :

<?php
    session_start();

    $dbserver                    = "localhost";
    $dbusername                  = "root";
    $dbpassword                  = "1234512345";
    $db                          = "game";

    $conn = new mysqli($dbserver, $dbusername, $dbpassword, $db);

    if ($conn->connect_error)
    {
        die("Connection failed: ".$conn->connect_error);
    }

    if(isset($_SESSION['loggedin']))

    $username = $_SESSION['loggedin'];

    $query = "SELECT id FROM users WHERE username = '$username'";
    $result = mysqli_query($conn, $query);
    $row = mysqli_fetch_assoc($result);

    $userId = $row['id'];
    $_POST['id'] = $userId;

    $name = $_POST['name'];
    $lastname = $_POST['lastname'];
    $age = $_POST['age'];
    $gender = $_POST['gender'];
    $country = $_POST['country'];
    $company_name = $_POST['company_name'];
    $_POST['loggedin'] = $username;

    $query = "SELECT id FROM companies WHERE name = '$company_name'";
    $result = mysqli_query($conn, $query);
    $row = mysqli_fetch_assoc($result);

    $companyId = $row['id'];
    $_POST['id'] = $companyId;

    //INSERT DATA INTO PROFILES
    $sql = "INSERT INTO profiles (user_id, username, name, lastname, age, gender, country, company_name)
    VALUES ('$userId', '$username', '$name', '$lastname', '$age', '$gender', '$country', '$company_name')";

    //INSERT DATA INTO COMPANIES
    $sql2 = "INSERT INTO companies (user_id, name)
    VALUES ('$userId', '$company_name')";

    //INSERT DATA INTO RESOURCES
    $sql3 = "INSERT INTO resources (user_id, company_id)
    VALUES ('$userId', '$companyId')";

    if($conn->query($sql) && $conn->query($sql2) && $conn->query($sql3) === TRUE)
    {
        header("Location: ../../index.php?page=profile");
        die();
    }
    else
    {
        echo "Error: ".$conn->error;
    }
?>

What should I do differently? I'm still beginner into this, sorry for long post.

EDIT: One guy helped me out with this code, it's more error proof than last version. Deleted companies table, merged it with profiles, now everything works correctly!

<?php
session_start();

$dbserver                    = "localhost";
$dbusername                  = "root";
$dbpassword                  = "1234512345";
$db                          = "game";

$conn = new mysqli($dbserver, $dbusername, $dbpassword, $db);

if ($conn->connect_error)
{
    die("Connection failed: ".$conn->connect_error);
}

if(isset($_SESSION['loggedin']))

$username = $_SESSION['loggedin'];

$query = "SELECT id FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);

$userId = $row['id'];
$_POST['id'] = $userId;

$name = $_POST['name'];
$lastname = $_POST['lastname'];
$age = $_POST['age'];
$gender = $_POST['gender'];
$country = $_POST['country'];
$company_name = $_POST['company_name'];
$_POST['loggedin'] = $username;

$query = "SELECT id FROM companies WHERE name = '$company_name'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result); 

$sql1 = "INSERT INTO profiles (user_id, username, name, lastname, age, gender, country, company_name) VALUES (?,?,?,?,?,?,?,?)";
$sql2 = "INSERT INTO resources (user_id) VALUES (?)";
try {
  $conn->autocommit(false);
  $statement = $conn->prepare($sql1);
  $statement->bind_param("dsssdsss", $userId, $username, $name, $lastname, $age, $gender, $country, $company_name);
  $statement->execute();


  $statement = $conn->prepare($sql2);
  $statement->bind_param("d", $userId);
  $statement->execute();

  // COMMIT THE CHANGES
  $conn->commit();
  header("Location: ../../index.php?page=profile");
}
catch(Exception $e){
    // undo everything that was done in the try block in the case of a failure.
    $conn->rollback();
    echo "Error: ".$conn->error;
}?>
  • for integer type fields don't quote the value, php consider it as a string. use $companyId without quotes, not like '$companyId' – Simrat Pal Singh Nov 27 '17 at 13:30
  • @SimratSingh Didn't work. Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 2 – Boban Gogic Nov 27 '17 at 13:41
  • Can you print the query and paste here? – Simrat Pal Singh Nov 27 '17 at 13:43
  • @SimratSingh Everything I have in that code is above. – Boban Gogic Nov 27 '17 at 13:47
  • Your code is vulnerable to SQL injection attacks. You should use parameterised queries and prepared statements to help prevent attackers from compromising your database by using malicious input values. http://bobby-tables.com gives an explanation of the risks, as well as some examples of how to write your queries safely using PHP / mysqli. **Never** insert unsanitised data directly into your SQL. – ADyson Nov 27 '17 at 14:06
  • Also, **Never** get your web app to login to the database as root. Root can do whatever it likes, so on top of the SQL injection vulnerabilities this just leaves your database an open book for hackers. Instead create a separate user account specifically for this application which has only the permissions it actually _needs_ in order to work properly. – ADyson Nov 27 '17 at 14:06
  • Anyway, it looks like you're trying to read a company ID from the "companies" table (using the name, which is likely to be brittle due to spelling, spacing issues etc etc), but then later you insert a record into the "companies" table using the company name and the user ID. It's not clear what the data structure is here. What info is the "companies" table supposed to represent? A company itself, or the relationship between the user and the company? And why are you trying to select from the table before you insert into it? What record are you trying to get? It doesn't seem to make much sense. – ADyson Nov 27 '17 at 14:11
  • @ADyson I will secure my code when I learn how to make it work first. I'm beginner, I know there is still much to learn. I'm still stuck without an answer. – Boban Gogic Nov 27 '17 at 14:12
  • @boban-gogic $companyId you don't want to generate after inserting companies? – Amit Gupta Nov 27 '17 at 14:14
  • @ADyson Companies table represents what type of resources and how much of them company has, there's also buildings_id and production_id. Also users can have multiple companies. – Boban Gogic Nov 27 '17 at 14:18
  • But each company has only one user? I still don't understand why you select from companies, and then later insert a new row into it as well? Also, "SELECT id FROM users WHERE username = '$username'" could easily return multiple rows (or no rows at all) if the same company is listed twice, or the spelling entered by the user is slightly wrong. You're assuming it returns exactly one row, but this is far from guaranteed. You should select by the ID. If the user needs to choose the company, then give them a drop-down list of names, which sends back the ID. – ADyson Nov 27 '17 at 14:28
  • Then after that I don't see that you would need to insert a new row into companies? If you're doing that then I think maybe your data structure is a little screwy, it's hard to tell. – ADyson Nov 27 '17 at 14:29
  • @ADyson Yes, one user only, that will be a browser game (I hope so). I think that you are right, I could do it without companies table. And for now I'll stick to one company only, I will optimise it later on for multiple companies. – Boban Gogic Nov 27 '17 at 14:46

0 Answers0