2

what i want to do is that it checks the input field and after that it will insert the following query or it it gives an error message. My problem is that my query won't insert.

My PHP function that won't work (other file then html file):

function Code($userID) {
require '../conn.php';
    $sql = "SELECT `current_uses` FROM `sub_codes` WHERE `content` = '".$_POST['Code']."'";
    $result = mysqli_query($conn, $sql);
    $row = mysqli_fetch_array($result);
    if ($row['current_uses'] > 0){
        $query = "INSERT INTO `partner_subscriptions` (`id`, `user_id`, `sub_id`, `allowed_users`, `start_date`, `end_date`) VALUES (NULL, ?, ?, ?, ?, ?);";
        $stmt = $conn->prepare($query);
        $_userID = $userID;
        $_subID = '99'; 
        $_allowedUsers = '100';
        $_startDate = date('Y-m-d');
        $sql2 = "SELECT `end_date` FROM `sub_codes` WHERE `content` = '".$_POST['Code']."'";
        $result2 = mysqli_query($conn, $sql2);
        $row2 = mysqli_fetch_array($result2);
        $_endDate = $row2['end_date'];
        $stmt->bind_param("sssiiii", $_userID, $_subID, $_allowedUsers, $_startDate, $_endDate);
        $stmt->execute();
        $lastID = $conn->insert_id;
        $stmt->close();
        return $lastID;
    }else {
        echo "Wrong code";
    }
}

My html file:

<br/><div class="form-group">
  <label title="Required">Free description code:</label>
   <input type="text" name="Code" class="form-control" id="Code"/>
</div><br/>

The rest of my PHP file (that i think you need to know):

if (usedmail($_POST['username'])==true) {
$lastID = saveUser($_POST['fnln'], $_POST['username'], password_hash($_POST['password'], PASSWORD_BCRYPT), 0, 0, 1);
$niv = NULL;
if ($_POST['type'] == "3") { // If the partner is an educational institution look for niveau
    $niv = NivID($_POST['niv']);
}

Code($lastID, $_POST['Code']);
$path = saveImage();
Contact($lastID);
Image($lastID);
Social($lastID);
Story($lastID);
Skill($lastID);
$orgID = saveOrganisation($lastID, $_POST['organisation'], $path, $_POST['type'], $_POST['branche'], $niv);
updateUser($orgID, $lastID);
}
else {
 header('Location: ../../mailerror');
}

every other function works normal except the code function and i don't really know why. I appreciate your help!

xmaster
  • 1,042
  • 7
  • 20
  • 4
    You have `$stmt->bind_param("sssiiii"` and only 5 parameters. – Nigel Ren Mar 13 '19 at 07:55
  • As an optimisation, consider adding `end_date` to your first query (`$sql`), there's no real penalty to fetching that value even if you don't use it. Then you won't need `$sql2` – Nick Mar 13 '19 at 08:00
  • @NigelRen because `$id` is NULL and autoincrement – xmaster Mar 13 '19 at 08:09
  • The idea of `bind_param()` is that you link the values you have a `?` in your SQL with a variable in your PHP code. As you only have 5 `?`'s and 5 parameters, the `"sssiiii"` should relate to just the fields you want to bind. – Nigel Ren Mar 13 '19 at 08:11
  • @NigelRen i have 5 parameters and `"sssiiii"` – xmaster Mar 13 '19 at 08:14
  • Each letter represents the type of the particular parameter, so you should have 5 letters which correspond to the data types of the parameters. – Nigel Ren Mar 13 '19 at 08:15
  • @NigelRen i don't know what you mean – xmaster Mar 13 '19 at 08:20
  • Try the [manual](http://php.net/manual/en/mysqli-stmt.bind-param.php) then. – Nigel Ren Mar 13 '19 at 08:22
  • Beside the wrong usage of types parameter of the `mysqli_stmt::bind_param()` method, there are some more issues in this code. You 're already using prepared statements. Why this line of code `"SELECT `current_uses` FROM `sub_codes` WHERE `content` = '".$_POST['Code']."'";` is present? This is vulnerable for sql injections. Consider using prepared statements for this select statement as well. – Marcel Mar 13 '19 at 08:24
  • @Marcel i will but what is wrong? i mean the exact things – xmaster Mar 13 '19 at 08:31
  • 1
    You 've been told what is wrong. Please have a look at the [manual](http://de2.php.net/manual/en/mysqli-stmt.bind-param.php) for the right use of the `$type` parameter for the `mysqli_stmt::bind_param()` method. Every single character of your `'sssiiii'` stands for a single value that is bound to the statement. You 've got seven single characters but only five values. Beside that every single character defines the type of the bound variable. A 's' stands for string, an 'i' for integer and so on. – Marcel Mar 13 '19 at 08:36
  • @Marcel Okay thanks! – xmaster Mar 13 '19 at 08:37
  • @Marcel does the consecution matter – xmaster Mar 13 '19 at 08:38
  • @Marcel it works! Thanks for your help – xmaster Mar 13 '19 at 08:44

2 Answers2

1

Well, for explanation reasons how to use mysqli the right way. First of all, you have to keep control of your code. Always check what happens and catch any mistakes. You don 't do that and that 's the reason you don 't know, why your insert statement is not executed.

Error Handling for the win!

Use the results, which are explained in detail in the manual. Nearly every mysqli method returns a false value, when something went wront. Use it!

$sql = "SELECT current_uses FROM sub_codes WHERE content = ?";
$stmt = mysqli_prepare($connection, $sql);

// Is there a prepared statement?
if (!$stmt) {
    die(printf('Something went wrong: %s.', mysqli_error($connection)));
}

// use the mysqli statement (one type definition per used variable)
$result = mysqli_stmt_bind_param($stmt, "s", $_POST['code']);
if (!$result) {
    die(printf('Something went wrong: %s.', mysqli_stmt_error($stmt)));
} 

// execute the statement
$result = mysqli_stmt_execute($stmt);
if (!$result) {
    die(printf('Something went wrong: %s.', mysqli_stmt_error($stmt)));
}

As you can see it is necessary to check what the result of each mysqli function call is to avoid unpredictable behavior of your script. Always keep in mind not to use post variables directly in sql statements. This is a huge mistake and opens your script for several vulnerabilities via sql injection.

Please read one of the many sql injection topics here on stack overflow to understand what sql injection is and how you can prevent it: How can I prevent SQL injection in PHP?

Marcel
  • 4,854
  • 1
  • 14
  • 24
  • Thanks! was just reading the [How can I prevent SQL injection in PHP?](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) – xmaster Mar 13 '19 at 09:06
  • but i get this error now `Fatal error: Uncaught Error: Call to a member function bind_param() on boolean in C:\xampp\htdocs\new-sc\functions\save\savePartner.php:60 Stack trace: #0 C:\xampp\htdocs\new-sc\functions\save\savePartner.php(11): Code(385, 'ZazC5cKDW1S3eQA...') #1 {main} thrown in C:\xampp\htdocs\new-sc\functions\save\savePartner.php on line 60` – xmaster Mar 13 '19 at 09:13
  • so i fixed that error but now it won't insert the data anymore – xmaster Mar 13 '19 at 09:19
  • I don 't know the changes you 've made. Debug your code and evaluate every return value of your mysqli_* functions as I 've shown in the example above. Yeah, this is a lot of work because your code isn 't good at all. Anyway ... debug your code and evaluate every return value! – Marcel Mar 13 '19 at 09:27
  • i fixed it. thank you for your help – xmaster Mar 13 '19 at 09:35
0

I had to change "sssiiii" to "iiiss" because Every single character of your 'sssiiii' stands for a single value that is bound to the statement.

xmaster
  • 1,042
  • 7
  • 20