PDO Insert value - php

I have followed some tutorial and I can't understand why this doesn't work.
I have a class Users. It gets a DB connection in the __construct method. Next I have a Create method, that needs to create a user by inserting some data in the table, but it does not execute. I think I have problem with the bindParam function or with MySQL insert code.
I have following error:
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in C:\www\samodel\object\users.php on line 44
Please help me to solve this problem if you know how, Thank you:
<?php
//Was Products, now Users
class Users{
// database connection and table name
private $conn;
private $table_name = "users";
// object properties
public $id;
public $username;
public $first_name;
public $last_name;
public $email;
public $password;
public function __construct($db){
$this->conn = $db;
}
// create user
function create(){
//write query
$query = "INSERT INTO
" . $this->table_name . "
SET
username = ?, first_name = ?, last_name = ?";
$stmt = $this->conn->prepare($query);
$stmt->bindParam("username", $this->username);
$stmt->bindParam("first_name", $this->first_name);
$stmt->bindParam("last_name", $this->last_name);
if($stmt->execute()){
return true;
}else{
return false;
}
}
}
?>

You are mixing two techniques here - you are preparing the statement with positional placeholders, but binding according to names - you should pick one and stick to it.
With positional placeholders:
$query = "INSERT INTO
" . $this->table_name . "
SET
username = ?, first_name = ?, last_name = ?";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(1, $this->username);
$stmt->bindParam(2, $this->first_name);
$stmt->bindParam(3, $this->last_name);
With named placeholders:
$query = "INSERT INTO
" . $this->table_name . "
SET
username = :username, first_name = :first_name, last_name = :last_name";
$stmt->bindParam("username", $this->username);
$stmt->bindParam("first_name", $this->first_name);
$stmt->bindParam("last_name", $this->last_name);

I think you have bad sql
try
$query = "INSERT INTO {$this->table_name} (username, first_name, last_name) VALUES (:username, :first_name, :last_name)";

Related

How do I pass a database connection into a method PHP

I have a class in PHP and one of the methods needs to access a database.How do I correctly pass a database connection variable to a method? Does it get passed as a parameter through the constructor or method? Or is it something completely different?
Check the following updated answer. Tested and working.
<?php
class SomeClass
{
function setDb($servername, $username, $password, $database)
{
// Create the database connection and use this connection in your methods as $this->conn
$this->conn = new mysqli($servername, $username, $password, $database);
if ($this->conn->connect_error) {
die("Connection failed: " . $this->conn->connect_error);
}
echo "New successful connection to myDb \n";
}
public function createTable()
{
// sql to create table
$sql = "CREATE TABLE MyGuests (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)";
if ($this->conn->query($sql) === TRUE) {
echo "New table created successfully \n";
} else {
echo "Error: " . $sql . "<br>" . $this->conn->error;
}
}
public function normalInsertDb()
{
// sql to insert record using normal query
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', 'john#example.com')";
if ($this->conn->query($sql) === TRUE) {
echo "New record inserted successfully using normal sql statement \n";
} else {
echo "Error: " . $sql . "<br>" . $this->conn->error;
}
}
public function preparedInsertDb()
{
// prepare and bind
$stmt = $this->conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
// set parameters and execute
$firstname = "John";
$lastname = "Doe";
$email = "john#example.com";
$stmt->execute();
$firstname = "Mary";
$lastname = "Moe";
$email = "mary#example.com";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie#example.com";
$stmt->execute();
echo "New records inserted successfully using PREPARED STATEMENTS \n";
$stmt->close();
$this->conn->close();
}
}
$obj = new SomeClass();
$obj->setDb('localhost', 'homestead', 'secret', 'myDb'); //we assume the database myDb exists
$obj->createTable();
$obj->normalInsertDb();
$obj->preparedInsertDb();
My Result:
If the database connection is used only by one method of your object, there is nothing wrong about passing it as an argument to this method.
However, mostly this is not the case. So you would be better off, when you establish the db connection at an earlier stage (on top of your script) and then pass it as a constructor argument to all objects that will need it. Then, various objects can use the same connection for various methods and internal, private methods, too.
If you want to optimize further, wrap the connection into a dedicated class and use dependency injection to get it into the consumer objects.

How to use PHP prepared statements in OOP

I am saving my data using this code (pasting my code)
Connection.php:
<?php
namespace Database;
use Mysqli;
class Connection {
public $con;
function __construct() {
$this->con = new mysqli(connection strings here);
}
function save($sql) {
$this->con->query($sql);
}
}
?>
then my Save.php is like this:
<?php
require 'config.php';
class Save {
function __construct($username, $password) {
$connect = new Database\Connection;
$sql = "INSERT INTO sample(string1, string2) VALUES ('$test1', '$test2')";
$connect->save($sql);
}
}
$save = new Save("last", "last");
?>
my question is how do I implement bind params here and prepared statement for PHP?
and also I would like to ask what are the best way to do this and best practices that I should implement for my code
thanks guys
Your classes are structured in a weird way, I am guessing you want some sort of ORM like class?
If so, you may want to rename your Save class to User (that's a guess since you are trying to save a username and password) and move your constructor logic, e.g.
class User {
function save($username, $password) {
$sql = "INSERT INTO users (username, password) VALUES (?,?)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
}
}
This example explain how you can do it .
<?php
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
$stmt->bind_param('sssd', $code, $language, $official, $percent);
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
/* execute prepared statement */
$stmt->execute();
printf("%d Row inserted.\n", $stmt->affected_rows);
/* close statement and connection */
$stmt->close();
/* Clean up table CountryLanguage */
$mysqli->query("DELETE FROM CountryLanguage WHERE Language='Bavarian'");
printf("%d Row deleted.\n", $mysqli->affected_rows);
/* close connection */
$mysqli->close();
?>
And you can find more info in this link : http://php.net/manual/tr/mysqli-stmt.bind-param.php
And i suggest you to use PDO its better way to connect with the
database .
Use like this.
public function insert_new_user($username, $email, $password){
$mysqli = $this->link;
$sql = "INSERT INTO users"
. " (user_name, user_email, user_pass)"
. " VALUES (?, ?, ?)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("sss", $username, $email, $password);
if ($stmt->execute()) {
return "success";
} else {
return "failed: " . $mysqli->error;
}
}

mysqli function doesn't insert values

I'm trying to connect to a database by mysqli in an object oriented way. I had a few errors, and solved them, but now I just can solve this one. I've got my code here, and all the names (database name, user, password, host, and table names) are correct (actually, copied and pasted), but the query still returns 0.
<?php
class DbConnection
{
public $link;
public function __construct()
{
$this->link = new mysqli("localhost","root","","todo");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
}
function RegisterUsers($username, $password, $ip, $name, $email)
{
$stmt = $this->link->prepare("INSERT INTO users (Username, `Password`, ip, Name, Email) VALUES (?,?,?,?)");
$stmt->bind_param("sssss", $username, $password, $ip, $name, $email);
$stmt->execute();
$stmt->store_result();
$count = $stmt->num_rows;
return $count;
}
}
$dbConn = new DbConnection();
echo $dbConn->RegisterUsers("a","a","a","a", "a");
?>
Edit: With this code, i get an
Call to a member function bind_param() on boolean
error.
Password and name are keywords in mysql. You have to put it in backticks to escape it, if you will use it as column name
$stmt = $this->link->prepare("INSERT INTO users (Username, `Password`, ip, `Name`) VALUES (?,?,?,?)");

Mysqli commit in other function

I have a PHP class with many functions and this is my problem:
In function A i do some steps for prepare an insert into database
But I DON'T commit because I want do it in an other function (B function) like this code.
But in the data base no one row is inserted.
Any idea?
Thanks to all, this is my sample code:
public static function functionA($id, $email, $password, $name, $surname) {
global $mysqli;
$mysqli = self::getDb(); //with $mysqli->autocommit(FALSE);
if (!($stmt = $mysqli->prepare('INSERT INTO User (Id, mail, Password, Name, Surname) VALUES (?,?,?,?,?)'))){
self::closeDatabase($mysqli, $stmt);
die;
}
if (!$stmt->bind_param("sssss", $id, $email, $password, $name, $surname)) {
self::closeDatabase($mysqli, $stmt);
die;
}
if (!$stmt->execute()) {
self::closeDatabase($mysqli, $stmt);
die;
}
}
public static function functionB() {
global $mysqli;
$mysqli->commit();
self::closeDatabase($mysqli, $stmt);
}
Change this code
if (!($stmt = $mysqli->prepare('INSERT INTO User (Id, mail, Password, Name, Surname) VALUES (?,?,?,?,?)'))){
self::closeDatabase($mysqli, $stmt);
die;
}
to this one:
$sql = 'INSERT INTO User (Id, mail, Password, Name, Surname) VALUES (?,?,?,?,?)';
if (!($stmt = $mysqli->prepare($sql)))
{
throw new Exception($mysqli->error." [$sql]");
}
for ALL your queries.
Then make sure you can see PHP errors.
Then run your code again.

Having an error with executing my query

Well, I'm creating a registration system for my website but I'm having trouble executing my query. I've tried to troubleshoot the problem, but I've had no success. Kind of confused :(
Here is my code:
public function registerUser($username, $password, $email) {
global $core;
if(empty($username) || empty($password) || empty($email)) {
throw new Exception ('A required field was left blank');
} else {
//SQL Query Data
$data['username'] = $username;
$data['password'] = $core->encrypt($password);
$data['email'] = $email;
$data['userKey'] = rand(999999, 100000);
$data['ip'] = $_SERVER['REMOTE_ADDR'];
$data['date'] = time();
//SQL Query
$sql = "INSERT INTO `u_userdata` ('user-key', 'username', 'password', 'email', 'register-ip', 'register-date') VALUES (:userKey, :username, :password, :email, :ip, :date)";
$STH = $this->DBH->query($sql);
$STH->execute($data);
}
}
and here is the error I'm getting:
Fatal error: Call to a member function execute() on a non-object in C:\xampp\htdocs\community\inc\user.inc.php on line 33
I'm guessing it's an error with the query, but I'm not sure what!
I think you have got PDO::prepare() mixed up with PDO::query():
It should be either:
$result = $this->DBH->query($sql);
Or:
$STH = $this->DBH->prepare($sql);
$STH->execute($data);
From the docs:
PDO::query() executes an SQL statement in a single function call,
returning the result set (if any) returned by the statement as a
PDOStatement object.
You would normally use PDO::prepare() if you are going to issue the same statement repeatedly, or if you need to bind parameters. As far as I am aware, it is not possible to bind parameters to your query prior to using PDO::query().
Note that with PDO::prepare() you can either use PDOStatement::bindParam() to bind parameters prior to calling PDOStatement->execute(), or you can pass the parameters as an array to PDOStatement->execute().
You also need to prefix your array keys with a colon. So the final result would be:
$data[':username'] = $username;
$data[':password'] = $core->encrypt($password);
$data[':email'] = $email;
$data[':userKey'] = rand(999999, 100000);
$data[':ip'] = $_SERVER['REMOTE_ADDR'];
data[':date'] = time();
//SQL Query
$sql = "INSERT INTO `u_userdata` ('user-key', 'username', 'password', 'email', 'register-ip', 'register-date') VALUES (:userKey, :username, :password, :email, :ip, :date)";
$STH = $this->DBH->prepare($sql);
$STH->execute($data);
You should use ` quote instead of ' in insert query.
"INSERT INTO u_userdata (user-key, username, password, email, register-ip, register-date) VALUES (:userKey, :username, :password, :email, :ip, :date)
the query() function executes the sql statement. you should use the prepare() function.
i'm assuming that you are using pdo, because of the pdo tag
$data[':username'] = $username;
$data[':password'] = $core->encrypt($password);
$data[':email'] = $email;
$data[':userKey'] = rand(999999, 100000);
$data[':ip'] = $_SERVER['REMOTE_ADDR'];
$data[':date'] = time();
//SQL Query
$sql = "INSERT INTO `u_userdata` ('user-key', 'username', 'password', 'email', 'register-ip', 'register-date') VALUES (:userKey, :username, :password, :email, :ip, :date)";
$stmt = $this->DBH->prepare($sql);
$stmt->execute($data);

Categories