Setting PDO::ATTR_EMULATE_PREPARES to false not working - php

I've tried disabling emulated prepares in PDO but I cannot get it to work. Everything else works. The query is successful. The reason I believe it's not working is because it does not escape quotes and such so I get syntax errors.
I've tried doing it two different ways.
$this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
and
$insert = $database->$con->prepare($insert, array(PDO::ATTR_EMULATE_PREPARES => false));
I've also noticed that getAttribute does not work.
By doing this...
$emul = $database->$con->getAttribute(PDO::ATTR_EMULATE_PREPARES);
var_dump($emul);
...I get this error
SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute
And here's my database class where the action happens. (I might have left some unneccessary/stupid code in there while I was testing.)
<?php
class Database
{
public $dbh;
public $dbh1;
public $dbh2;
private static $instance;
public $numResults;
private $result = array(); // Results that are returned from the query
public function __construct()
{
try
{
$this->dbh = new PDO(DB_TYPE.':host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8', DB_USER, DB_PASS);
$this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->dbh1 = new PDO(DB_TYPE1.':host='.DB_HOST1.';dbname='.DB_NAME1.';charset=utf8', DB_USER1, DB_PASS1);
$this->dbh1->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->dbh1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->dbh2 = new PDO(DB_TYPE2.':host='.DB_HOST2.';dbname='.DB_NAME2.';charset=utf8', DB_USER2, DB_PASS2);
$this->dbh2->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->dbh2->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
die("Database Error: ". $e->getMessage() . "<br />");
}
}
public static function getInstance()
{
if (!isset(self::$instance))
{
$object = __CLASS__;
self::$instance = new $object;
}
return self::$instance;
}
private function tableExists($table, $con)
{
switch($con)
{
case 'dbh':
$db_name = DB_NAME;
break;
case 'dbh1':
$db_name = DB_NAME1;
break;
case 'dbh2':
$db_name = DB_NAME2;
break;
}
$database = Database::getInstance();
if(is_array($table))
{
for($i = 0; $i < count($table); $i++)
{
$tablesInDb = $database->$con->prepare('SHOW TABLES FROM '.$db_name.' LIKE "'.$table[$i].'"');
$tablesInDb->execute();
$rowCount = $tablesInDb->rowCount();
if($tablesInDb)
{
if($rowCount <> 1)
{
die('Error: Table does not exist'.$table[$i]);
}
}
}
}else
{
$tablesInDb = $database->$con->prepare('SHOW TABLES FROM '.$db_name.' LIKE "'.$table.'"');
$tablesInDb->execute();
$rowCount = $tablesInDb->rowCount();
if($tablesInDb)
{
if($rowCount <> 1)
{
die('Error: Table does not exist'.$table);
}
}
}
return true;
}
public function insert($con, $table, $values, $cols = null)
{
if($this->tableExists($table, $con))
{
$insert = 'INSERT INTO '.$table;
if($cols != null)
{
$cols = implode(',', $cols);
$insert.= '('.$cols.')';
}
for($i = 0; $i < count($values); $i++)
{
if(is_string($values[$i]))
$values[$i] = "'".$values[$i]."'";
}
$values = implode(',', $values);
$insert .= ' VALUES ('.$values.')';
$database = Database::getInstance();
$insert = $database->$con->prepare($insert, array(PDO::ATTR_EMULATE_PREPARES => false));
$insert->execute();
if($insert)
{
return true;
}else
{
return false;
}
}
}
public function getResult()
{
return $this->result;
}
}
?>

As manual states, getAttribute() don't support ATTR_EMULATE_PREPARES
There shouldn't be no escaping with native prepares at all.
To check if you are in emulation mode or not you can use LIMIT clause with lazy binding. It will raise an error if emulation is on.
Your main problem is whatever "syntax error" you mentioned and you have to solve it first.
As Álvaro G. Vicario noted in comments, you are not using prepared statements. It is apparently the root of the problem. PDO doesn't "escape" your data by itself. It can do it only if you are using placeholders to represent your data in the query. You can read more here

Related

Insert multiple data into different tables in a single transaction

This has nothing to do with Frameworks because it is an external project, I am currently developing to learn, some things about database management or how databases behave...
I need help with some php and PDO... Previously I dev this script:
<?php
class DataBaseManager
{
public function GetData($query, $user, $pass)
{
try {
$db_result = [];
$conn = new PDO("mysql:host=localhost;dbname=test", $user, $pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec("set names utf8");
reset($query);
$db_name = key($query);
$conn->exec('USE ' . $db_name);
$db_result['r'] = $conn->query($query[$db_name], PDO::FETCH_ASSOC);
$count = $db_result['r']->rowCount();
$db_result['c'] = $count;
if (0 == $count) {
$db_result['r'] = null;
} elseif (1 == $count) {
$db_result['r'] = $db_result['r']->fetch();
}
return $db_result;
} catch (PDOException $e) {
echo $e->getMessage();
return false;
}
}
public function DeleteData($query, $user, $pass)
{
try {
$conn = new PDO("mysql:host=localhost;dbname=test", $user, $pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->beginTransaction();
$conn->exec("set names utf8");
foreach ($query as $db_name => $query_arr) {
$conn->exec('USE ' . $db_name);
foreach ($query_arr as $key => $query_string) {
$conn->exec($query_string);
++$ct;
}
}
$conn->commit();
$conn = null;
return '<b>' . $ct . ' Records Deleted Successfully.</b>';
} catch (PDOException $e) {
$conn->rollback();
echo $e->getMessage();
return false;
}
}
public function SetData($query, $user, $pass)
{
try {
$db_result = [];
$conn = new PDO("mysql:host=localhost;dbname=test", $user, $pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->beginTransaction();
$conn->exec("set names utf8");
$count = ['u' => 0, 'i' => 0];
foreach ($query as $db_name => $query_arr) {
$conn->exec('USE ' . $db_name);
foreach ($query_arr as $key => $query_string) {
$cq = $conn->exec($query_string);
if (strpos($query_string, 'UPDATE') !== false) {
$count['u'] += $cq;
}
if (strpos($query_string, 'INSERT') !== false) {
$count['i'] += $cq;
}
}
}
$conn->commit();
$db_result['r'] = true;
$db_result['t'] = 'Updates: ' . $count['u'] . ', Inserts: ' . $count['i'];
return $db_result;
} catch (PDOException $e) {
$conn->rollback();
echo $e->getMessage();
return false;
}
}
}
I would like to be able to insert data by volumes in multiple tables in a single commit...
The idea of doing it that way is because if something fails I want it to be automatically rolled back in all table instances...
So I have a data structure in an array with the following content in my new class:
$dbquery =[
'test'=>[
'0' =>[
0 => 'INSERT INTO table_name_1(column1,column2) VALUES (?,?)', //mean it is the query
1 =>[value11,value12], // mean it is a row
2 =>[value21,value22], // mean it is a row
],
'1' =>[
0 => 'INSERT INTO table_name_2(column1,column2,column3,column4) VALUES (?,?,?,?)', //mean it is the query
1 =>[value11,value12,value13,value14], // mean it is a row
2 =>[value21,value22,value23,value24], // mean it is a row
],
],
];
but i have my first try with bindValue, this is my new class mentioned:
<?php
class DataBase
{
private static ?DataBase $instance = null;
public static function getInstance(): DataBase
{
if (!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
private array $config;
public function __construct()
{
$this->config = ['DB_HOST'=>'test','DB_NAME'=>'test','DB_USER'=>'test','DB_PASSWORD'=>''];
$this->setConnection(new PDO("mysql:host=" . $this->config['DB_HOST'] . ";dbname=" . $this->config['DB_NAME'], $this->config['DB_USER'], $this->config['DB_PASSWORD']));
}
private PDO $connection;
/**
* #return PDO
*/
private function getConnection(): PDO
{
return $this->connection;
}
/**
* #param PDO $connection
*/
private function setConnection(PDO $connection): void
{
$this->connection = $connection;
}
public function changeConnectionServer(string $host, string $db_name, string $user, string $password): void
{
$this->setConnection(new PDO("mysql:host=" . $host . ";dbname=" . $db_name, $user, $password));
}
private array $query;
public function setDataBaseTarget(string $db_name)
{
if (empty($this->query)) {
$this->query = [];
}
$this->query[$db_name] = [];
}
public function buildQuery(string $query)
{
if (empty($this->query)) {
$this->query = [];
$this->query[$this->config['DB_NAME']] = [];
}
$target = array_key_last($this->query);
$this->query[$target][] = [$query];
}
public function addQueryData($data)
{
$target = array_key_last($this->query);
$key = array_key_last($this->query[$target]);
$this->query[$target][$key][] = $data;
}
private function getQuery(): array
{
return $this->query;
}
/**
* #throws Exception
*/
public function setData(): array
{
try {
$time = -microtime(true);
$con = $this->getConnection();
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$con->beginTransaction();
$con->exec("set names utf8;");
foreach ($this->getQuery() as $db_name => $query_arr) {
$con->exec('USE `' . $db_name . '`;');
$ct = 0;
// on this section have proble with code and logic .... i dont know what i need to dev to insert the data
foreach ($query_arr as $query_structure) {
foreach ($query_structure as $key => $raw) {
if ($key === 0) {
$ct++;
$stmt[$ct] = $con->prepare($raw);
} else {
if (is_array($raw)) {
$c = 0;
foreach ($raw as $value) {
$c++;
$stmt[$ct]->bindValue($c, $value, $this->getParamType($value));
}
}
}
}
$stmt[$ct]->execute();
}
//end section
}
//$con->commit();
return true;
} catch (PDOException $e) {
$con->rollback();
echo $e->getMessage();
return false;
}
}
private function getParamType($value)
{
if (is_int($value)) {
return PDO::PARAM_INT;
} elseif (is_bool($value)) {
return PDO::PARAM_BOOL;
} elseif (is_null($value)) {
return PDO::PARAM_NULL;
} elseif (is_string($value)) {
return PDO::PARAM_STR;
} else {
return false;
}
}
}
$db_handler = DataBase::getInstance();
$db_handler->buildQuery("INSERT INTO `client_list`(`email`,`mobile`) VALUES ('?','?');");
$db_handler->addQueryData(['mail1#test.com', '35634634636546']);
$db_handler->addQueryData(['mail2#test.com', '35634634636546']);
$db_handler->addQueryData(['mail3#test.com', '35634634636546']);
$db_handler->setData();
I can't figure out, develop the part that allows me to package everything in a single transaction... what I have is a stm[] ...
Can someone help me with this development?
I can't make heads or tails of all the things your class is doing, but here's a generalized version according to the bits that seem obvious:
public function runMultipleQueries() {
$dbh = $this->getConnection();
// ... setup stuff
$dbh->beginTransaction();
try {
foreach($this->queries as $query) {
$stmt->prepare($query->queryString);
$param_id = 1;
foreach($query->params as $param) {
$stmt->bindValue($param_id++, $param);
}
$stmt->execute();
}
} catch( \Exception $e ) {
$dbh->rollback();
throw $e;
// IMO if you cannot fully/meaningfully recover, just re-throw and let it kill execution or be caught elsewhere where it can be
// otherwise you're likely having to maintain a stack of if(foo() == false) { ... } wrappers
}
$dbh->commit();
}
Additionally, singleton DB classes have the drawbacks of both being limiting if you ever need a second DB handle, as well as boiling down to being global state, and subject to the same "spooky action at a distance" problems.
Consider using dependency inversion and feeding class dependencies in via constructor arguments, method dependencies via method arguments, etc. Eg:
interface MyWrapperInterface {
function setQueries(array $queries);
function runQueries();
}
class MyDbWrapper implements MyWrapperInterface {
protected $dbh;
public function __construct(\PDO $dbh) {
$this->dbh = $dbh;
}
public function setQueries(array $queries) { /* ... */ }
public function runQueries() { /* ... */ }
}
class MyOtherThing {
protected $db;
public function __construct( MyWrapperInterface $db ) {
$this->db = $db;
}
// ...
}
$wrapper1 = new MyDbWrapper(new PDO($connstr1, $options));
$wrapper2 = new MyDbWrapper(new PDO($connstr2, $options));
$thing1 = new MyOtherThing($wrapper1);
$thing2 = new MyOtherThing($wrapper2);
$thing1_2 = new MyOtherThing($wrapper1);
// etc

PHP sql Injection and custom numbers of parameters in function

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

Fixing max_user_connections in PHP class using PDO

I have been adapting an older abstraction layer to use PDO but I am running into user x has more than 'max_user_connections' active connections SQLSTATE[HY000] [1203] errors when looping through large sets. I have been reading on http://php.net/manual/en/pdo.connections.php but all of my attempts to unset the $dbh from within the loops result in errors from having ended the connection.
Base class looks like
class DB {
public $pdo;
private $host = DB_HOST;
private $user = DB_USER;
private $pass = DB_PASS;
private $dbname = DB_NAME;
public function __construct()
{
$this->connect();
}
private function connect()
{
$options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
$this->pdo = new PDO("mysql:host=$this->host;dbname=$this->dbname;charset=utf8;", $this->user, $this->pass, $options);
} catch(PDOException $e) {
echo $e->getMessage();
}
}
public function __sleep()
{
return array('dsn', 'username', 'password');
}
public function __wakeup()
{
$this->connect();
}
public function __destruct()
{
$this->connection = null;
$this->pdo = null;
unset($this->pdo);
}
// CRUD methods follow including
function retrieve($where, $groupBy='', $order_by='') {
$query = "SELECT * FROM `$this->table` $where $groupBy $order_by";
$q = $this->pdo->prepare($query);
$q->execute();
$result = $q->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE,get_class($this));
// was $result = $q->fetchAll(PDO::FETCH_CLASS,get_class($this));
$this->query_log($query);
$q = null;
if ($result == 'NULL') {
return false;
} else {
return $result;
}
} // retrieve()
And an example that has the errors would be
if (in_array($_GET['type'], $types)) {
$type = $_GET['type'];
$rsObj = new ReservedSlug;
if ($type == 'artist') {
$obj = new CalendarArtist;
$slugfield = 'urlSlug';
$namefield = 'name';
} else if ($type == 'event') {
$obj = new CalendarEvent;
$slugfield = 'urlSlug';
$namefield = 'name';
} else if ($type == 'location') {
$obj = new Location;
$slugfield = 'UrlSlug';
$namefield = 'LocationName1';
}
$needslug = $obj->retrieve("TRIM(`$namefield`) != '' AND (`$slugfield` = '' OR `$slugfield` IS NULL) LIMIT 0,400");
if ($needslug) {
foreach ($needslug as $ns) {
$testslug = slugify($ns->$namefield);
list($reserved) = $rsObj->retrieve("`slug` = '$testslug' AND `type` = '$type'");
if (!$reserved) {
list($test) = $obj->retrieve("`$slugfield` = '$testslug'");
if ($test) {
for ($i = 2; $i < 26; $i++) {
list($test) = $obj->retrieve("`$slugfield` = '$testslug-$i'");
if (!$test) {
$slug = $testslug . '-' . $i;
}
}
} else { // not found in table
$slug = $testslug;
}
} else { // was reserved
$slug = false;
}
echo $ns->$namefield . " gets $slug<p>";
} // foreach needslug
} // if needslug
} // type found in array
So I need to understand how to not create new connections when an active connection is available and how to properly __destruct() these child objects. Where am I going wrong?

Unable to get error info with PDO in PHP

I am in the process of learning PDO and am trying to implement it in my current project. When I used mysqli, I could get detailed info about any error using mysqli_error($connection). I googled at what the comparable for PDO would be and found this post, and decided to implement it in my code. However, I am unable to get any error messages even when I know there is an obvious error in the sql statement.
Relevant code:
class Database {
public $connection;
function __construct() {
$this->open_database_connection();
}
public function open_database_connection() {
try {
$this->connection = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASSWORD);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->setAttribute( PDO::ATTR_EMULATE_PREPARES, false);
} catch(PDOException $e) {
echo $e->getMessage();
die('Could not connect');
}
} // end of open_database_connection method
public function query($sql, $params = []) {
try {
$query = $this->connection->prepare($sql);
} catch (Exception $e) {
var_dump('mysql error: ' . $e->getMessage());
}
foreach($params as $key => $value) {
if ($key === ':limit') {
$query->bindValue($key, $value, PDO::PARAM_INT);
} else {
$query -> bindValue($key, $value);
}
}
try {
$query->execute();
} catch(Exception $e) {
echo 'Exception -> ';
var_dump($e->getMessage());
}
/*
DID NOT WORK:
if (!$query->execute()) {
print_r($query->errorinfo());
}*/
$result = $query->fetchAll(PDO::FETCH_ASSOC);
$this->confirm_query($result);
return $result;
} // end of query method
function confirm_query($query) {
if (!$query) {
die('mysql error: ');
}
}
When I run the code, I do get the "mysql error", but I do not get any details about it. What am I doing wrong?
Update: As requested, I am providing additional details below.
What I am trying to do is get the user's login detail to be verified. To that end, once the user inputs his credentials , this code runs:
if (isset($_POST['submit'])) {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
//check the database for the user
$user_found = User::verify_user($username, $password);
Relevant code from the User class:
public static function verify_user($username, $password) {
global $db;
$username = $db->escape_string($username);
$password = $db->escape_string($password);
$values = [ ":username" => $username,
":password" => $password,
":limit" => 1
];
$result_array = self::find_this_query("SELECT * FROM users WHERE username=:username AND password=:password LIMIT :limit", true, $values);
return !empty($result_array)? array_shift($result_array) : false;
}
public static function find_this_query($sql, $prepared = false, $params = []) {
global $db;
$the_object_array = array();
$result = $db->query($sql, $params);
$arr_length = count($result);
for ($i = 0; $i < $arr_length; $i++) {
$the_object_array[] = self::instantiation($result[$i]);
}
return $the_object_array;
}
public static function instantiation($the_record) {
$the_object =new self; //we need new self because $the_record corresponds to one user!
foreach($the_record as $the_attribute => $value) {
if ($the_object->has_the_attribute($the_attribute)) {
$the_object->$the_attribute = $value;
}
}
return $the_object;
}
public function has_the_attribute($attribute) {
$object_properties = get_object_vars($this);
return array_key_exists($attribute, $object_properties);
}
You have to use PDO::errorInfo():
(...)
public function query($sql, $params = []) {
try {
$query = $this->connection->prepare($sql);
if( !$query )
{
$error = $this->connection->errorInfo();
die( "mysql error: {$error[2]}" );
}
} catch (Exception $e) {
var_dump('mysql error: ' . $e->getMessage());
}
(...)
}
PDO::errorInfo returns an array:
Element 0: SQLSTATE error code (a five characters alphanumeric identifier defined in the ANSI SQL standard);
Element 1: Driver-specific error code;
Element 2: Driver-specific error message.

Trouble with php (call to a member function on a non-object)

I am getting this php error and I can't seem to fix it.
Fatal error: Call to a member function prepare() on a non-object in C:\xampp\htdocs\mlrst\database.php on line 26
here is the line that is calling function prepare.
$this->statement->prepare($strQuery);
and here is it being declared.
protected $statement;
any ideas?
Edit: Here is my full code (don't mind the testing dummies)
<?php
$d = new database(); // test
class database {
protected $db_connect;
protected $statement;
function database() {
$db_connect = new MySQLi("localhost", "root" ,"", "test") or die("Could not connect to the server.");
$statement = $db_connect->stmt_init();
$this->preparedQuery("INSERT INTO feedback (name, feedback) VALUES ('?', '?')");
$this->close();
echo "Done!";
}
protected function cleanString($strLine) {
$strCleansedLine = preg_replace("/[^a-zA-Z0-9\s]/", "", $strLine);
return $strCleansedLine;
}
public function preparedQuery($strQuery, $parameters = NULL) {
try {
$this->statement->prepare($strQuery);
$statement->bind_param("ss", $name, $feedback);
for ($i = 0; $i < count($parameters); $i++) {
}
$name = $this->cleanString("this is my name");
$feedback = $this->cleanString("this is some feedback");
$query = $statement->execute();
} catch(Exception $e) {
echo $e->getMessage();
}
}
protected function close() {
try {
if ($this->statement != NULL)
$this->statement->close();
if ($this->db_connect != NULL)
$this->db_connect->close();
} catch (Exception $e) {
$e->getMessage();
}
}
}
?>
You assigned the local variable $statement. You need to set the instance's property using $this->statement.
In other words, change this:
$statement = $db_connect->stmt_init();
To this:
$this->statement = $db_connect->stmt_init();
And this:
$statement->bind_param("ss", $name, $feedback);
To this:
$this->statement->bind_param("ss", $name, $feedback);
...and this:
$query = $statement->execute();
To this:
$query = $this->statement->execute();

Categories