FaaPz/PDO

Help needed on insert statement

christogonus opened this issue · 14 comments

I followed the guide here https://github.com/FaaPz/PDO/blob/2.x/docs/Statement/Insert.md to make an insert page.
$user_insert = new Insert($dsn, $user_attributes)->into('users');

but I get error
Parse error: syntax error, unexpected token "->" in app\includes\functions\auth.php on line 57

I dont know if I have missed anything, but please help me.

Thank you for your help!

kwhat commented

That's a mistake on my part, it should be $user_insert = (new Insert($dsn, $user_attributes))->into('users'); because new has higher precedence than ->. I'll fix it up soon.

kwhat commented

Alternatively, you can use $database->insert($user_attributes)->into('users') which I think is the better approach.

Thanks for your quick help, but I get a different error with that approach
Fatal error: No values set for insert statement in app\vendor\faapz\pdo\src\Statement\Insert.php on line 182

Could this be because of my PHP version 8?

kwhat commented

No, PHP 8 should be fine. I think you forgot to add columns & values.

$user_attributes = [
    'id' => 1234,
    'username' => 'user',
    'password' => 'passwd'
];

Here is the response when I vardump $user_attributes

array(12) { ["username"]=> string(10) "xonihikupo" ["password"]=> string(9) "Pa$$w0rd!" ["passport"]=> string(52) "assets/passports/PDaYhvXOt09LBDJXJkQfneYdlvIyBYE.jpg" ["firstname"]=> string(6) "Quincy" ["lastname"]=> string(6) "Howell" ["gender"]=> string(6) "Female" ["dob"]=> string(11) "28-Apr-1989" ["country"]=> string(12) "South Africa" ["address"]=> string(20) "Velit cupiditate at " ["email"]=> string(20) "qafaj@mailinator.com" ["phone"]=> string(17) "+1 (126) 826-4219" ["occupation"]=> string(20) "Omnis mollit eveniet" }

Maybe I will sleep and get back to my code when I wake up. Maybe I spelt a field name wrongly.

@kwhat Here is the result of the insert statement

Screenshot_1

But when I add the ->execute(), it now fails with the error
Fatal error: No values set for insert statement in app\vendor\faapz\pdo\src\Statement\Insert.php on line 182

But...

when I use the PDO directly, it works!

$new_user_statement = $pdo->prepare("INSERT INTO users (username, password, passport, firstname, lastname, gender, dob, country, address, email, phone, occupation) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$new_user_statement->execute([$username, $password, $passport_link, $firstname, $lastname, $gender, $dob, $country, $address, $email, $phone, $occupation]);
$user_id = $pdo->lastInsertId();

I am really confused!

kwhat commented

Can you send me the snippet for the code you are using?

Sorry for the delayed response. This is a freelance project and I had to deliver with what worked first - to avoid late delivery penalty from the platform.

Here's the form content - styled in bootstrap4 css

<form action="signup.php" method="POST" class="margin-bottom-0" enctype="multipart/form-data">
                                <div class="lm-top-options">
                                    First Name <font color="#FF0000"><b>*</b></font><br>
                                    <input type="text" class="form-control" name="firstname" id="firstname"
                                           placeholder="First name"  style="width:90% !important;"  required />
                                </div>
                                <!-- PARTNER / REFERRAL -->
                                <div class="lm-top-options" id="lm-partners-selection">
                                    Last Name <font color="#FF0000"><b>*</b></font><br>
                                    <input type="text" class="form-control" name="lastname" id="lastname"
                                           placeholder="Last name" style="width:90% !important;" required />
                                </div>
                                <div class="lm-top-options" id="div-email">
                                    Email Address <font color="#FF0000"><b>*</b></font><br>
                                    <input type="email" class="form-control" name="email" id="email" onblur="checkEmailExists(this)"
                                           placeholder="email address" style="width:90% !important;" required />
                                </div>
                                <fieldset class="field-set">
                                    <!---- BORROWER INFORMATION ------>
                                    <div class="title">Personal Information</div>
                                    <div class="form-col">
                                        <p>
                                            <label for="loanapp_borrower_firstname">Gender</label>
                                            <select class="form-control selectpicker" name="gender" id="gender" required>
                                                <option value="">Select Gender</option>
                                                <option value="Male">Male</option>
                                                <option value="Female">Female</option>
                                            </select>
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                        <p>
                                            <label for="datepicker-autoClose">Date of birth</label>
                                            <input type="text" class="form-control" id="dob" name="dob" placeholder="DD/MM/YYYY" required>
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                        <p class="loanapp_address">
                                            <label for="address">Full Address</label>
                                            <input type="text" class="form-control" name="address" id="address" placeholder="Address" required />
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                        <p class="loanapp_borrower_city">
                                            <label for="loanapp_borrower_city">Country</label>
                                            <select class="form-control selectpicker" name="country"
                                                    data-size="10" data-live-search="true"
                                                    data-style="btn-white" required>
                                                <option value="United Kingdom">United Kingdom</option>
                                                <option value="United States of America">United States of America</option>
                                                <option value="Virgin Islands (USA)">Virgin Islands (USA)</option>
                                            </select>
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                        <p class="p-occupation">
                                            <label for="occupation">Occupation</label>
                                            <input type="text" class="form-control" id="occupation" name="occupation"  placeholder="Occupation" required />
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                    </div>
                                    <div class="form-col">
                                        <p>
                                            <label for="loanapp_acc_type">Account Type</label>
                                            <select class="form-control selectpicker" name="acc_type" id="acc_type" data-size="10"
                                                    data-live-search="true" data-style="btn-white" required>
                                                <option value=''>Select Account Type</option>
                                                <option value="Savings">Savings</option>
                                                <option value="Current">Current</option>
                                                <option value="Credit">Credit</option>
                                            </select>
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                        <p>
                                            <label for="loanapp_currency">Account Currency</label>
                                            <select class="form-control selectpicker" name="acc_currency"  id="acc_currency" data-size="10"
                                                    data-live-search="true" data-style="btn-white" required>
                                                <option value="&euro;">&euro; - Euro</option>
                                                <option value="$">$ - USD</option>
                                            </select>
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                        <p>
                                            <label for="phone">Phone Number</label>
                                            <input type="text" class="form-control" name="phone" id="phone"
                                                   pattern="[+][0-9]{9,}" placeholder="eg: +1475743647" required />
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                        <p>
                                            <label for="username">Login Username</label>
                                            <input type="text" name="username" id="username" placeholder="login username"
                                                   onblur="checkUsernameExists(this)" required>
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                        <p class="loanapp_ssn">
                                            <label for="loanapp_borrower_ssn">Account Password</label>
                                            <input type="password" name="password" id="password"
                                                   placeholder="password" class="form-control m-b-5" required>
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                        <p class="loanapp_birthdate">
                                            <label for="passport">Passport Photo</label>
                                            <input type="file" class="form-control" name="passport"
                                                   id="passport" accept="image/*" required />
                                            <font color="#FF0000"><b>*</b></font>
                                        </p>
                                    </div>
                                    <div class="clear"></div>
                                </fieldset>
                                <br>
                                <div class="lm-top-options">
                                    By clicking <u>Submit Application</u> button below, you agree to the terms and conditions, privacy policy, and cookie policy that govern this website.
                                </div>
                                <div class="register-buttons">
                                    <button type="submit" class="btn btn-primary btn-block btn-lg" style="width: 100% !important;" >Submit Application</button>
                                </div>
                            </form>

Here is the processor page

use FaaPz\PDO\Clause\Conditional;

$upload_dir = 'assets/passports/';
$ext = strtolower(pathinfo($_FILES["passport"]["name"],PATHINFO_EXTENSION));
$new_file_name = $upload_dir . generate_string(32) . ".$ext";
move_uploaded_file($_FILES["passport"]["tmp_name"], $new_file_name);

$user_attributes = [
'username' = $_POST["username"];
'password' = $_POST["password"];
'passport' = $new_file_name;
'firstname' = $_POST["firstname"];
'lastname' = $_POST["lastname"]
'gender' = $_POST["gender"];
'dob' = $_POST["dob"];
'country' = $_POST["country"];
'address' =  $_POST["address"];
'email' = $_POST["email"];
'phone' = $_POST["phone"];
'occupation' = $_POST["occupation"]
];

$insertStatement = $pdo->insert($user_attributes)
                       ->into("users");
$insertStatement->execute();

Here is a fresh installation made just to find out if I did something wrong in the previous code... and it shows same error.

<?php
require_once 'vendor/autoload.php';

$dsn = 'mysql:host=localhost;dbname=faapz;charset=utf8';
$pdo = new \FaaPz\PDO\Database($dsn, 'root', '');

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	extract($_POST);
	$users = array(
		'name' => $name,
		'email' => $email,
		'phone' => $phone
	);
	$insertStatement = $pdo->insert($users)->into("users");
	$insertId = $insertStatement->execute();
	dd($insertId);
}
?>
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
    <title>Faapz test!</title>
  </head>
  <body>

    <div class="row">
    	<div class="col-md-6 mx-auto">
    		<h1>Hello, world!</h1>
		    <form method='post'>
			  <div class="form-group">
			    <label for="name">Name</label>
			    <input type="text" class="form-control" id="name" name="name" required>
			  </div>
			  <div class="form-group">
			    <label for="email">Email address</label>
			    <input type="email" class="form-control" id="email" name="email" required>
			  </div>
			  <div class="form-group">
			    <label for="phone">Phone</label>
			    <input type="text" class="form-control" id="phone" name='phone' required>
			  </div>
			  <button type="submit" class="btn btn-primary mb-2">Save</button>
			</form>
		</div>
	</div>

    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
  </body>
</html>

Please review and help.

Downgrading to version 2,1,0 makes the code work!

So, here is what I have come up with:

  • the documentation may not have shown exactly how to implement "insert" with the latest version, or
  • there is a bug

I am not able to help check the source code haha as I am just migrating from procedural PHP to OOP and everything is still looking foreign to me.

kwhat commented

It is def a documentation problem:

include_once 'vendor/autoload.php';

$pdo = new FaaPz\PDO\Database('mysql:host=127.0.0.1; port=3307; dbname=testing', 'root', 'testing');

$insertA = $pdo->insert([
        'username',
        'password',
        'firstname',
        'lastname'
    ])
    ->into("users")
    ->values(
        'testing',
        'passw@rd1',
        'Alex',
        'Barker'
    );

// INSERT INTO users (username, password, firstname, lastname) VALUES (?, ?, ?, ?)
echo $insertA->__toString();
echo "\n\n";

$insertB = $pdo->insert()
    ->into("users")
    ->columns(
        'username',
        'password',
        'firstname',
        'lastname'
    )
    ->values(
        'testing',
        'passw@rd1',
        'Alex',
        'Barker'
    );

// INSERT INTO users (username, password, firstname, lastname) VALUES (?, ?, ?, ?)
echo $insertB->__toString();
echo "\n\n";
kwhat commented

What ended up happening is that instead of taking in pairs, I had to take in columns to support adding multiple inserts in a single query and I totally spaced on updating the docs.

kwhat commented

I just updated the docs, I'm wondering if I should have kept it backward compatible with 2.1 now.

I just updated the docs, I'm wondering if I should have kept it backward compatible with 2.1 now.

Thanks for updating the docs. Making it backward compatible is nice, but just keeping a copy of the docs for the older version will do as well ~ my thoughts.