Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
My INSERT statement is not working. The number of rows affected is affected is 0. Here is my code :
<?php
require_once('class.config.php');
class userActions{
public $link;
function __construct(){
$db_connection = new dbConnection();
$this->link = $db_connection->connect();
return $this->link;
}
function registerUsers($username, $password, $ip_address){
$query = $this->link->prepare("INSERT INTO users (user_name,password,ip_address) VALUES (?,?,?)");
$values = array($username, $password, $ip_address);
$query->execute($values);
$counts = $query->rowCount();
return $counts;
}
}
$users = new userActions();
echo $users->registerUsers('bob', 'dave123','127.0.0.1');
?>
What have I done wrong?
EDIT : this is my class.config.php:
class dbConnection{
protected $db_conn;
public $db_host = "localhost:8080";
public $db_user = "root";
public $db_pass = "";
public $db_name = "facebook";
function connect(){
try{
$this->db_conn = new PDO("mysql:host = $this->db_host; dbname = $this->db_name",
$this->db_user, $this->db_pass);
$this->db_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $this->db_conn;
}
catch(PDOException $e){
return "MySQL error : " . $e->getMessage();
}
}
}
Change your registerUsers function code to below
If you are using mysqli then use below
function registerUsers($username, $password, $ip_address){
$query = $this->link->prepare("INSERT INTO users (user_name,password,ip_address) VALUES (?,?,?)");
$query->bind_param("sss", $username, $password, $ip_address);
$query->execute();
}
EDIT
As I see you are using PDO.
Try to use like anyone of below
function registerUsers($username, $password, $ip_address){
$query = $this->link->prepare("INSERT INTO users (user_name,password,ip_address) VALUES (:username,:password,:ip_address)");
$query->bindParam(':username', $username);
$query->bindParam(':password', $password);
$query->bindParam(':ip_address', $ip_address);
$query->execute();
}
OR
function registerUsers($username, $password, $ip_address){
$query = $this->link->prepare("INSERT INTO users (user_name,password,ip_address) VALUES (:username,:password,:ip_address)");
$query->execute(array('username' => $username, 'password' => $password, 'ip_address' => $ip_address));
}
I would prefer to use bindParam as it is secure and it replaces my_real_escape_string.
this below can can help you to understand how to insert to database via oop programming
databse class:
public static $con;
public static function connect($hostname , $username , $password , $database)
{
self::$con = mysqli_connect($hostname , $username , $password , $database) or die('Error: '.mysqli_connect_error());
}
public static function disconnect()
{
mysqli_close(self::$con);
}
public static function insert($sql , $values)
{
$values = self::safeValues($values);
$sql = self::$con->prepare($sql);
mysqli_set_charset(self::$con , 'UTF8');
self::bindValues($sql , $values);
$save = $sql->execute();
return $save;
}
public function safeValues($values = null)
{
if($values != null)
{
for($i = 0 ; $i < count($values) ; $i++)
{
$values[$i] = trim($values[$i]);
$values[$i] = strip_tags($values[$i]);
mysqli_real_escape_string(self::$con , $values[$i]);
}
}
return $values;
}
public function bindValues($sql, $values = null)
{
if ($values != null)
{
// Generate the Type String (eg: 'issisd')
$types = '';
foreach($values as $value)
{
if(is_int($value))
$types .= 'i';
elseif (is_float($value))
$types .= 'd';
elseif (is_string($value))
$types .= 's';
else
$types .= 'b';
}
// Add the Type String as the first Parameter
$bind_names[] = $types;
// Loop thru the given Parameters
for ($i = 0 ; $i < count($values) ; $i++)
{
// Create a variable Name
$bind_name = 'bind'.$i;
// Add the Parameter to the variable Variable
$$bind_name = $values[$i];
// Associate the Variable as an Element in the Array
$bind_names[] = &$$bind_name;
}
// Call the Function bind_param with dynamic Parameters
call_user_func_array(array($sql,'bind_param') , $bind_names);
}
return $sql;
}
and in your home class you can insert like this:
home class:
DB::connect('localhost' , 'username' , 'password' , 'database');
DB::insert("INSERT INTO table(field1, field2) VALUES (? , ?)" , [ $val1 , $val2 ] );
i hope this can be helpful for you.
So I have solved my code by removing localhost:8080 with 127.0.0.1 in my class.config.php.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm using this class code to insert data into the database:
<?php
Class User
{
private $error = "";
public function signup($post)
{
$data = array();
$data['name'] = trim($_POST['name']);
$data['email'] = trim($_POST['email']);
$data['pass'] = trim($_POST['pass']);
$pass2 = trim($_POST['pass2']);
if(empty($data['email']) || !preg_match("/^[0-9a-zA-Z_-]+#[0-9a-zA-Z_-]+.[0-9a-zA-Z_-]+$/", $data['email']))
{
$this->error .= "Please enter a valid Email <br>";
}
if(empty($data['name']) || !preg_match("/^[a-zA-Z]+$/", $data['name']))
{
$this->error .= "Please enter a valid Name <br>";
}
if($data['pass'] !== $pass2)
{
$this->error .= "Password dont match <br>";
}
if(strlen($data['pass']) < 4)
{
$this->error .= "Password must be at least 4 character long <br>";
}
if($this->error == "")
{
$data['rank'] = "customer";
$data['url_address'] = $this->get_random_string_max(60);
$data['date'] = date("Y-m-d H:i:s");
$query = "INSERT INTO users (url_address, name, email, pass, date, rank) VALUES (:url_address, :name, :email, :pass, :date, :rank)";
$db = Database::getInstance();
$result = $db->write($query, $data);
if ($result) {
header("Location:" . ROOT . "login");
die();
}
}
}
private function get_random_string_max($length)
{
$array = array(0,1,2,3,4,5,6,7,8,9,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
$text = "";
$length = rand(4, $length);
for ($i=0; $i>$length;$i++) {
$random = rand(0, 61);
$text .= $array[$random];
}
return $text;
}
}
this is the database Class:
<?php
Class Database
{
public static $con;
public function __construct()
{
$dsn = 'mysql:hostname=localhost;dbname='. DB_NAME;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
return $db = new PDO($dsn, DB_USER, DB_PASS, $options);
} catch (PDOException $e) {
die($e->getMessage());
}
}
public static function getInstance()
{
if(self::$con) {
return self::$con;
}
return $instance = new self();
}
public function read($query, $data = array())
{
$stmt = self::$con->prepare($query);
$result = $stmt->excute($data);
if ($result) {
$data = $stmt->fetchAll(PDO::FETCH_OBJ);
if(is_array($data)) {
return $data;
}
}
return false;
}
public function write($query, $data = array())
{
$stmt = self::$con->prepare($query);
$result = $stmt->excute($data);
if ($result) {
return true;
}
return false;
}
}
I'm using MVC and this is the signup controller page and database class.
pass2 is retyped password in the form.
but the data not inserting into the database and not redirecting to the login page.
and
PDO::ERRMODE_EXCEPTION
not showing any errors.
what is the problem?
In Database Class You have an error in writing the function excute() in line:
$result = $stmt->excute($data);
it should be execute()
$result = $stmt->execute($data);
Good day everyone:
I'd like to parametrize my queries, creating a function that receive my query, connection and array with parameters expressed as "?".
My function is:
receiveQuery($query, $mysqli1, $array1)
I have read about sql injection I would like to know that if this is a proper way to avoid these.
I am planning to use this this function for INSERT, DELETE, UPDATE and SELECT.
Also I would like you to guide me how could I create some better handling for more than 1 parameter, because currently I am using a switch.
But every time I require more parameters, I am increasing the switch and I would like to create it dinamically.
SWITCH ($array1Length)
Any comments is helpful, regards.
Felipe
<?php
$mysqli1 = openConn();
$query = "INSERT INTO tblTest (field1 , field2 ) VALUES (?,?)";
$array1 = array($value1, $value2);
$result = receiveQuery($query, $mysqli1, $array1);
if($stmt->affected_rows == 1)
{
$success = "Success.";
}
if($stmt->affected_rows == -1)
{
$error = "Error.";
}
closeConn($stmt);
closeConn($mysqli1);
function openConn()
{
$mysqli1 = new mysqli('localhost', 'userTest', '123', 'dbTest');
if ($mysqli1->connect_error) {
die('Connect Error (' . $mysqli1->connect_errno . ') '
. $mysqli1->connect_error);
}
return $mysqli1;
}
function receiveQuery($query, $mysqli1, $array1)
{
global $stmt;
$stmt = $mysqli1->prepare($query);
if (false===$stmt)
{
echo $mysqli1->error;
die('Error');
}
$array1Length = count($array1);
SWITCH ($array1Length)
{
CASE 0: break;
CASE 1: $stmt->bind_param("s" , $array1[0]) ;break;
CASE 2: $stmt->bind_param("ss" , $array1[0],$array1[1]) ;break;
CASE 3: $stmt->bind_param("sss" , $array1[0],$array1[1],$array1[2]) ;break;
CASE 4: $stmt->bind_param("ssss", $array1[0],$array1[1],$array1[2],$array1[3]);break;
DEFAULT : echo "Error";
}
$stmt->execute();
$result = $stmt->get_result();
return $result;
}
function closeConn($mysqli1)
{
$mysqli1->close();
}
?>
You should be able to use the splat operator on your array.
$s = '';
for ($x = 0; $x < count($params); $x ++) {
$s .= 's';
}
$stmt->bind_param($s, ...$params);
https://secure.php.net/manual/en/migration56.new-features.php
I'd like to parametrize my queries, creating a function that receive
my query, connection and array with parameters expressed as "?"
My suggestion is that you rather use PDO than, the current mysqli that you using at the moment. PDO is easier to learn and can work easy with your current requirements.
Here's how you would do this with PDO.
page.php
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'dbTest');
define('DB_USER', 'userTest');
define('DB_PASS', '123');
define('DB_CHAR', 'utf8');
class conn
{
protected static $instance = null;
protected function __construct() {}
protected function __clone() {}
public static function instance()
{
if (self::$instance === null)
{
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => FALSE,
);
$dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR;
self::$instance = new PDO($dsn, DB_USER, DB_PASS, $opt);
}
return self::$instance;
}
public static function __callStatic($method, $args)
{
return call_user_func_array(array(self::instance(), $method), $args);
}
public static function receiveQuery($sql, $args = [])
{
if (!$args)
{
return self::instance()->query($sql);
}
$stmt = self::instance()->prepare($sql);
$stmt->execute($args);
return $stmt;
}
}
anotherpage.php
<?php
require 'page.php';
$params = array($value1, $value2);
$sql = "INSERT INTO tblTest (field1 , field2 ) VALUES (?,?)";
$stmt = conn::receiveQuery($sql, $params);
if($stmt->rowCount() > 0){
$success = "Success.";
}else{
$error = "Error.";
}
?>
To learn more about PDO you can follow this site : https://phpdelusions.net/pdo
I created a function to grab data from my database. I want this function to be reusable just by placing correct arguments for different tables. Here's what I've done :
public function selectdata($table, $arguments='*', $where = null){
if($this->isconnect){
//check whether users put column names in the select clause
if(is_array($arguments)){
$new_args = implode(',', $arguments);
$sql = 'SELECT '.$new_args.' FROM '.$table;
} else {
$sql = 'SELECT '.$arguments.' FROM '.$table;
}
//check whether users use the where clause
if($where != null && is_array($where)){
$where = implode(' ', $where);
$sql .= ' WHERE '.$where ;
}
$query = $this->db->query($sql);
$query -> SetFetchMode(PDO::FETCH_NUM);
while($row = $query->fetch()){
print_r($row);
}
} else {
echo 'failed, moron';
}
}
And this is the way to run the function :
$columnname = array('bookname');
$where = array('bookid','=','2');
echo $database-> selectdata('buku', $columnname, $where);
The code worked quite decently so far, but I'm wondering how I want to use $where but without $columnname in the function. How do I pass the arguments in the function?
And could you point to me the better way to create a function to grab data using PDO?
Just use a PDO class which can look like this:
<?php
class DB_Connect{
var $dbh;
function __construct(){
$host = "xxx";
$db = "xxx";
$user = "xxx";
$password = "xxx";
$this -> dbh = $this -> db_connect($host, $db, $user, $password);
}
public function getDBConnection(){
return $this -> dbh;
}
protected function db_connect($host, $db, $user, $password){
//var_dump($host, $db, $user, $password);exit();
try {
$dbh = new PDO("mysql:host=$host;dbname=$db", $user, $password);
}
catch(PDOException $err) {
echo "Error: ".$err->getMessage()."<br/>";
die();
}
return $dbh;
}
public function query($statement){
$keyword = substr(strtoupper($statement), 0, strpos($statement, " "));
$dbh = $this->getDBConnection();
if($dbh){
try{
$sql = $dbh->prepare($statement);
$exe = $sql->execute();
}
catch(PDOException $err){
return $err->getMessage();
}
switch($keyword){
case "SELECT":
$result = array();
while($row = $sql->fetch(PDO::FETCH_ASSOC)){
$result[] = $row;
}
return $result;
break;
default:
return $exe;
break;
}
}
else{
return false;
}
}
}
?>
Now you can include that class and create an object with $dbh = new DB_Connect; and call every statement you want just with the reference on $dbh->query($statement)
This is my prefered way to do this.
EDIT: If you want to use a statement on another Database, just use the __construct($db) method to pass your database name on object creation
I have this code:
class mysql {
public $mysql;
function __construct($host, $user, $pass, $db){
$this->mysql = new mysqli($host, $user, $pass, $db);
if($this->mysql->connect_errno)
exit('Error connecting to the database');
}
public function replace(array $var){
$str = "";
foreach($var as $k => $v){
$str .= substr_replace($v, "'", 0) . substr_replace ($v, "',", -1);
}
$str[strlen($str)-1] = "";
return $str;
}
public function insert($table, array $kv){
$p1 = implode(',', array_keys($kv));
$p2 = $this->replace($kv);
$q = "INSERT INTO $table ($p1) VALUES ($p2)";
echo $q;
echo $this->mysql->query($q);
}
}
And I use the function and no data is inserted to database I cant se anything on DB
Output of echo:
INSERT INTO users (username,password,email) VALUES ('Hi','Hwghrwhw','WREHRWWRWRGH')
I think the problem of your code is the missing escaping of your colnames
INSERT INTO `users` (`username`,`password`,`email`) VALUES ('Hi','Hwghrwhw','WREHRWWRWRGH')
PASSWORD is a protected keyword. Here your changed code:
public function insert($table, array $kv){
$p1 = implode('`,`', array_keys($kv));
$p2 = $this->replace($kv);
$q = "INSERT INTO `$table` (`$p1`) VALUES ($p2)";
echo $q;
echo $this->mysql->query($q);
}
I am trying to establish a data connection to the MySql and create prepared statements, where the query_f function takes in any number of parameters, where the first parameter is the sql statement, and the other parameters are the values that would be substituted in the prepared statement.
Here is what I have. The first error I got is when I am trying to bind the values to the statement.
function query_f(/* query, [...] */){
$user = "root";
$pass = "root";
$host = "localhost";
$database = "mcnair";
$conn = mysqli_connect($host,$user,$pass);
if(!$conn)
{
echo "Cannot connect to Database";
}
else
{
mysqli_select_db($conn, $database);
}
// store query
$query = func_get_arg(0);
$parameters = array_slice(func_get_args(), 1);
$param = "'".implode("','",$parameters)."'";
// Prepare the statement
$stmt = mysqli_prepare($conn, $query);
if ($stmt == false)
{
echo "The statement could not be created";
exit;
}
// Bind the parameters
$bind = mysqli_stmt_bind_param($stmt, 's', $param);
echo mysqli_stmt_error($stmt);
if ($bind == false)
{
echo "Could not bind";
}
else
{
echo "Bind successful";
}
// Execute the statement
$execute = mysqli_stmt_execute($stmt);
if ($execute = false)
{
echo "Could not execute";
}
// fetch the data
$fetch = mysqli_stmt_fetch($stmt)
if ($fetch == false)
{
echo "Could not fetch data";
}
else
{
return $fetch;
}
}
And the function call I am using is:
query_f("SELECT Hash FROM alumni WHERE Username = '?'", "zm123");
How about using a class (instead of a function) and using mysqli in the OO way and not in the procedural way?
This is a simplified version of what I use. Not perfect, so if anyone would like to suggest improvements, I'm all ears.
class Connection {
private $connection;
public function __construct()
{
//better yet - move these to a different file
$dbhost = '';
$dbuname = '';
$dbpass = '';
$dbname = '';
$this->connection = new mysqli($dbhost, $dbuname, $dbpass, $dbname);
}
/*
* This is the main function.
*
* #param $arrayParams = array (0 => array('s' => 'Example string'), 1 => array('s' => 'Another string'), 2 => array('i' => 2), 3 => array('d' => 3.5) )
*/
public function executePrepared($sql, $arrayParams)
{
$statement = $this->prepareStatement($sql);
if ($statement) {
$this->bindParameter($statement, $arrayParams);
$this->executePreparedStatement($statement);
$result = $this->getArrayResultFromPreparedStatement($statement);
//only close if you are done with the statement
//$this->closePreparedStatement($statement);
} else {
$result = false;
}
return $result;
}
public function prepareStatement($sql)
{
$statement = $this->connection->prepare($sql) or $this->throwSqlError($this->connection->error);
return $statement;
}
public function bindParameter(&$statement, $arrayTypeValues)
{
$stringTypes = '';
$arrayParameters = array();
$arrayParameters[] = $stringTypes;
foreach ($arrayTypeValues as $currentTypeVale) {
foreach ($currentTypeVale as $type => $value) {
$stringTypes .= $type;
$arrayParameters[] = &$value;
}
}
$arrayParameters[0] = $stringTypes;
call_user_func_array(array($statement, "bind_param"), $arrayParameters);
}
public function getArrayResultFromPreparedStatement(&$statement)
{
$statement->store_result();
$variables = array();
$data = array();
$meta = $statement->result_metadata();
while($field = $meta->fetch_field())
$variables[] = &$data[$field->name]; // pass by reference
call_user_func_array(array($statement, 'bind_result'), $variables);
$i = 0;
$arrayResults = array();
while($statement->fetch())
{
$arrayResults[$i] = array();
foreach($data as $k=>$v)
{
$arrayResults[$i][$k] = $v;
}
$i++;
}
return $arrayResults;
}
public function executePreparedStatement($statement)
{
$result = $statement->execute() or $this->throwSqlError($statement->error);
return $result;
}
public function closePreparedStatement($statement)
{
$statement->close();
}
public function throwSqlError()
{ ... }
}