PHP inserting

activeradio

New Member
Messages
18
Reaction score
0
Points
0
I am having more problems with my Admin CP. There is a form on the previous page that sends the data here. I can't figure out why it won't add users into the database.

Code:
<?php
session_start();
if(!isset($_SESSION['username'])){
    header("location:index.php");
}

$host = 'localhost';
$database = 'stencil_access';
$db_username = 'stencil_admin';
$db_password = '<censored>';

if (($db = new PDO("mysql:host=$host;dbname=$database", $db_username, $db_password)) == NULL) {
    echo $db->getMessage();
}

$memberQuery = $db->prepare("SELECT * FROM members WHERE username=:username");
$memberQuery->execute(array(':username' => $_SESSION['username']));

$memberQuery1 = $db->prepare("SELECT * FROM members WHERE username=:username");
$memberQuery1->execute(array(':username' => $username));

$memberQuery2 = $db->prepare("SELECT * FROM members");
$memberQuery2->execute();

$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
$type = $_POST['type'];
$purchased = $_POST['purchased'];
$expiry = $_POST['expiry'];

$today=date("F j, Y");
$file_date=date('Y-m-d');
$file = "Logs/" . $file_date .".txt";

$res_array = $memberQuery->fetchColumn(4);
if ($res_array<'2') {
    header("location:main.php");
    die();
}

if ($memberQuery1->fetchColumn() > 0) {
    header("Location:admin.php");
    die();
}

if  (empty($_POST['username']) || ($_POST['username']) == $memberQuery ||  empty($_POST['password']) || strlen($_POST['password']) != 40 ||  empty($_POST['email']) || intval($_POST['type']) < 0 ||  !is_numeric($_POST['type']) || empty($_POST['purchased']) ||  empty($_POST['expiry']) ) {
    header("Location:admin.php");
    die();
}

$result  = $db->prepare('INSERT INTO members (username, password, email,  type, purchased, expiry) VALUES (:username, :password, :email, :type,  :purchased, :expiry)');
$result->execute(array(':username' =>  $username, ':password' => $password, ':email' => $email, ':type'  => $type, ':purchased' => $purchased, ':expiry' => $expiry));

if($result) {
    file_put_contents($file, "{$_SESSION['username']} has added an user to the database on on $today\n", FILE_APPEND | LOCK_EX);
}

header("Location:admin.php");
?>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
</html>
 

descalzo

Grim Squeaker
Community Support
Messages
9,373
Reaction score
326
Points
83
You get error messages?

Script stop early?

You ever dump out the variables?

Why do you test $result before logging the insertion?
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
In addition to descalzo's questions:

$memberQuery and $memberQuery1 are the same statement. Why have both?

When you execute $memberQuery1, $username doesn't appear to be defined.

Only one file should contain sensitive information, such as database credentials. Otherwise it becomes much harder to secure said information.

If the DB connection fails, script execution continues. This won't be causing the issue you mention, but will cause incorrect behavior in other circumstances.

Don't use SELECT *; select only the columns you need.

$memberQuery2 will return a very large result set. Why do you need every member?

The sample code doesn't salt and hash the password, though I see it tests whether the password is 40 characters long. Is the password hashed before ?

When validating the form input, the script compares the supplied username with the first prepared query (($_POST['username']) == $memberQuery), which will fail, so the script to exit before reaching the INSERT statement.

PHP:
$res_array = $memberQuery->fetchColumn(4);
if ($res_array<'2') {
Why is '2' a string?
 
Last edited:

activeradio

New Member
Messages
18
Reaction score
0
Points
0
Sorry, I forgot to post the var dump.
Code:
var_dump($memberQuery);
var_dump($memberQuery1);
var_dump($_POST['username']);

object(PDOStatement)#2 (1) {
["queryString"]=>
string(46) "SELECT * FROM members WHERE username=:username"
}

object(PDOStatement)#3 (1) {
["queryString"]=>
string(46) "SELECT * FROM members WHERE username=:username"
}

string(5) "steve"

$memberQuery and $memberQuery1 are not the same statement. The first query checks the username in the session, and the second query checks the username written on the previous page.

$username is defined with $username = $_POST['username'];

Unless I can remember why I needed $memberQuery2, I'll put it back in. The password is hashed before they are able to add users to the database. It just needs to be 40 characters in length.

2 isn't a string on all my other files, I fixed it.
 
Last edited:

descalzo

Grim Squeaker
Community Support
Messages
9,373
Reaction score
326
Points
83
Again, where does it fail? Error messages? Why are you testing $result before logging the update?
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
$memberQuery and $memberQuery1 are not the same statement. The first query checks the username in the session, and the second query checks the username written on the previous page.
You use them for different purposes, but they are the same statement:

Code:
SELECT * FROM members WHERE username=:username
SELECT * FROM members WHERE username=:username

If you execute $memberQuery->queryString === $memberQuery1->queryString, the result will be true. You don't need $memberQuery1. Instead, you can execute $memberQuery twice, which is one of the main reasons for prepared statements.

PHP:
$memberQuery = $db->prepare("SELECT id, type FROM members WHERE username=:username");

$memberQuery->execute(array(':username' => $_SESSION['username']));
if ($memberQuery->fetchColumn(1) < 2) {
    header("location:main.php");
    die();
}

$memberQuery->execute(array(':username' => $username));
if ($memberQuery1->fetchColumn() > 0) {
    header("Location:admin.php");
    die();
}

However, the different use suggests these two statements should be separated into different modules. The first should be refactored into a module that handles whatever the test concerns (authorization?). Similarly, the second should be refactored into another module (user management?), along with the INSERT. That way, you can test each module separately (unit testing) before testing that they work together (integration testing). Also, whatever you're testing with the < 2 comparison is very opaque. There, "2" is a magic number. By moving the test to a module and replacing the "2" with a named constant, the code will be much more readable.

$username is defined with $username = $_POST['username'];
In the posted code, that happens after you execute the prepared statement, which means it's undefined when the prepared statement is executed.

What about the other issues I brought up? The comparison of $_POST['username'] with $memberQuery alone will prevent the INSERT statement from ever being executed.

As descalzo says, you still haven't said how it fails. When asking for help, you need to state precisely what behavior you want/expect and the behavior you get, which includes error messages.
 
Last edited:

resty_rizal99

New Member
Messages
2
Reaction score
0
Points
0
How about testing your code first if its reaching the insertion by modifying some line temporarily like this.

PHP:
$res_array = $memberQuery->fetchColumn(4);
if ($res_array<'2') {
    //header("location:main.php");
    die('Cant reach insert because ($res_array<\'2\') is true');
}

if ($memberQuery1->fetchColumn() > 0) {
    //header("Location:admin.php");
    die('Cant reach insert because ($memberQuery1->fetchColumn() > 0) is true');
}

if  (empty($_POST['username']) || ($_POST['username']) == $memberQuery ||  empty($_POST['password']) || strlen($_POST['password']) != 40 ||  empty($_POST['email']) || intval($_POST['type']) < 0 ||  !is_numeric($_POST['type']) || empty($_POST['purchased']) ||  empty($_POST['expiry']) ) {
    //header("Location:admin.php");
    die('Cant reach insert because (empty($_POST[\'username\']) || ($_POST[\'username\']) == $memberQuery.....) is true');
}

$result  = $db->prepare('INSERT INTO members (username, password, email,  type, purchased, expiry) VALUES (:username, :password, :email, :type,  :purchased, :expiry)');
$result->execute(array(':username' =>  $username, ':password' => $password, ':email' => $email, ':type'  => $type, ':purchased' => $purchased, ':expiry' => $expiry));

if($result) {
    file_put_contents($file, "{$_SESSION['username']} has added an user to the database on on $today\n", FILE_APPEND | LOCK_EX);
}

//header("Location:admin.php");
die('pass the insertion code');
?>
 
Top