I am attempting to set up a class for the simplification of MySQLi queries using the mysqli class. However, when I set up my class to accept an instance of mysqli, I receive this error:
Undefined variable: dbobj in C:\wamp\www\inc\classes\ezsql.class.php on line 93
I've never really done dependency injection before, plus my coding skills aren't with me today, so syntax mistakes might be plentiful.
Here's the class I've created:
<?php
/*/////////////////////////////////////////////////////////////////////////////////////////////
EZSQL
A PHP class that utilizes the PDO MySQLi DB class to make database querying easier and quicker.
/////////////////////////////////////////////////////////////////////////////////////////////*/
class EZSQL {
public $dbobj;
public function __construct( mysqli $dbobject ) {
echo "var_dunp before making this->dbobj\n";
var_dump( $dbobj );
if ( is_object( $dbobject ) ) {
$this->dbobj = $dbobject;
} else {
// Just in case...
die( "EZSQL Error #0: EZSQL must be initialized with a PDO MySQLi DB instance." );
}
echo "var_dunp after making this->dbobj\n";
var_dump( $this->dbobj );
}
public function select( $exp, $table, $where ) {
// Make $where optional
if ( isset( $where ) ) {
$queryString = "SELECT {$exp} FROM {$table} WHERE {$where}";
} else {
$queryString = "SELECT {$exp} FROM {$table}";
}
if ( $returnObj = $this->dbobj->query( $queryString ) ) {
$return = $returnObj->fetch_assoc();
return $return;
} else {
// Some error handling
die( "[EZSQL]: SQL SELECT query error #{$this->dbobj->errno}: {$this->dbobj->error}" );
}
}
public function insert( $tab, $cols, $values ) {
// Create the general query string format
$queryString = "INSERT INTO {$tab} (";
$colsCt = count( $cols );
foreach ( $cols as $key=>$col ) {
if ( $key != ( $colsCt - 1 ) ) {
$queryString .= "{$col}, ";
} else {
$queryString .= "{$col})";
}
}
// More general formatting
$queryString .= " VALUES (";
$valCt = count( $values );
foreach( $values as $key=>$value ) {
if ( $key != ( $valCt - 1 ) ) {
$queryString .= "{$value}, ";
} else {
$queryString .= "{$value})";
}
}
if ( $query = $this->dbobj->prepare( $queryString ) ) {
$query->execute();
} else {
die( "[EZSQL]: SQL INSERT query prepare error #{$this->dbobj->errno}: {$this->dbobj->error}" );
}
}
public function createTable( $name, $ino, $colData ) {
// Create the general query string format
$queryString = "CREATE TABLE";
if ( $ino ) {
$queryString .= " IF NOT EXISTS";
}
$queryString .= " {$name}";
$colCt = count( $colData );
$queryString .= " (";
$iter = 1;
foreach ( $colData as $name=>$type ) {
$iter++;
if ( $iter != ( $colCt ) ) {
$queryString .= " {$name} {$type},";
} else {
$queryString .= " {$name} {$type});";
}
}
if ( !$this->dbobj->query( $queryString ) ) {
die( "[EZSQL]: SQL CREATE TABLE query error #{$this->dbobj->errno}: {$this->dbobj->error}" );
}
}
}
?>
Line 93 is contained inside the function createTable, specifically this if statement:
if ( !$this->dbobj->query( $queryString ) ) {
die( "[EZSQL]: SQL CREATE TABLE query error #{$this->dbobj->errno}: {$this->dbobj->error}" );
}
Any and all help will be greatly appreciated, as I can't quite tell what is wrong.
Again, keep in mind I am new to dependency injection. Syntax errors in PHP are not a rarity for me.
Thanks.
Edit 1: Here's the connection I'm using in my index.php page:
<?php
require( "inc/classes/ezsql.class.php" );
// require( "inc/config.php" );
// require( "inc/proc/db.php" );
$host = "127.0.0.1";
$user = "root";
$pass = "";
$db = "testdb";
$port = "3306";
$db = new mysqli( $host, $user, $pass, $db, $port );
echo "var_dunp before creating instance of EZSQL\n";
var_dump( $db );
if ( !$db ) {
die( "error" );
}
$ezsql = new EZSQL( $db );
$cols = array(
"int" => "int",
"text" => "varchar(255)"
);
$ezsql->createTable( "test1", TRUE, $cols );
?>
Edit 2: Added var_dump()s to certain locations. See this Pastebin for what they return.
Use a pdo wrapper such as this:
http://pastebin.com/AHdJkCBz
Then in the same directory, add settings.ini.php like this http://pastebin.com/cu1kY8kL
Do not commit this settings file to your repository. Copy and paste it always.
The way to call this would be:
function checkPassword($email, $password)
{
$db = new db();
$binding = array('emailId'=>$email, 'hashed_password'=>md5($password));
return $db->single("SELECT id FROM members WHERE pc_address = :emailId AND hashed_password = :hashed_password", $binding);
}
Check the whole class for detailed methods.
I have also made two general purpose functions to add/update database.
function assetsUtilInsert($table, $params, $debug=false){
$db = new db();
if($table && is_array($params)){
$bindings = $params;
if(!empty($bindings)) {
$fields = array_keys($bindings);
$fieldsvals = array(implode(",",$fields),":" . implode(",:",$fields));
$sql = "INSERT INTO ".$table." (".$fieldsvals[0].") VALUES (".$fieldsvals[1].")";
}
if($debug==true)
echo $sql;
$result = $db->query($sql,$bindings);
return $db->lastInsertId();
} else {
assetsUtilInvokeError($this->registry->log, "Could not insert because either table does not exist or parameters is not an array");
}
}
function assetsUtilUpdate($table, $params, $where, $exit=0){
$db = new db();
$sql = '';
if($table && is_array($params) && is_array($where)){
$sql = "UPDATE $table SET ";
foreach($params as $key => $val){
$sql .= $key ."=:$key, ";
}
unset($key); unset($val);
$sql = substr($sql, 0, (strlen($sql)-2));
$sql .= " WHERE ";
foreach($where as $key => $val){
$sql .= $key ."=:$key AND ";
}
unset($key); unset($val);
$bindings = array_merge($params, $where);
unset($params); unset($where);
$sql = substr($sql, 0, (strlen($sql)-4));
if($exit==1){
echo $sql; exit;
}
return $db->query($sql, $bindings);
} else {
assetsUtilInvokeError($this->registry->log, "Could not insert because either table does not exist or params is not an array or where condition is not an array");
}
}
I have used log4php for logging. You could adapt with this code.
Just changing the settings.ini.php for driver can help you use the same code for different databases supported by PDO.
Fixed.
I am an idiot, apparently, and screwed up a few things.
Thanks for the suggestions, but I'm not doing this professionally, so I don't care about injection attacks at this point in time. All of this is hosted locally and not port forwarded, so none of this data really matters.
Input sanitization is next on my list, though.
Check if you have enabled mysqli extension or just test if you can instance outside your class.
Also can we see how you instance and use your class when you get this error.
EDIT
Check mysqli object with var_dump() when you pass to your constructor.
Related
I am trying to write prepared statement for user input. parameter numbers are variable depends on user input. Oam trying this code
PHP code:
$string = "my name";
$search_exploded = explode( " ", $string );
$num = count( $search_exploded );
$cart = array();
for ( $i = 1; $i <= $num; $i ++ ) {
$cart[] = 's';
}
$str = implode( '', $cart );
$inputArray[] = &$str;
$j = count( $search_exploded );
for ( $i = 0; $i < $j; $i ++ ) {
$inputArray[] = &$search_exploded[ $i ];
}
print_r( $inputArray );
foreach ( $search_exploded as $search_each ) {
$x ++;
if ( $x == 1 ) {
$construct .= "name LIKE %?%";
} else {
$construct .= " or name LIKE %?%";
}
}
$query = "SELECT * FROM info WHERE $construct";
$stmt = mysqli_prepare( $conn, $query );
call_user_func_array( array( $stmt, 'bind_param' ), $inputArray );
if ( mysqli_stmt_execute( $stmt ) ) {
$result = mysqli_stmt_get_result( $stmt );
if ( mysqli_num_rows( $result ) > 0 ) {
echo $foundnum = mysqli_num_rows( $result );
while( $row = mysqli_fetch_array( $result, MYSQLI_ASSOC ) ) {
echo $id = $row['id'];
echo $name = $row['name'];
}
}
}
When I print_r($inputArray), the output is:
Array ( [0] => ss [1] => my [2] => name )
There is no error showing in error log.
What is wrong?
The % wrapping goes around the parameters, not the placeholders.
My snippet will be using object-oriented mysqli syntax instead of the procedural syntax that your code demonstrates.
First you need to set up the necessary ingredients:
the WHERE clause expressions -- to be separated by ORs
the data types of your values -- your values are strings, so use "s"
the parameters to be bound to the prepared statement
I am going to combine #2 and #3 into one variable for simpler "unpacking" with the splat operator (...). The data type string must be the first element, then one or more elements will represent the bound values.
As a logical inclusion, if you have no conditions in your WHERE clause, there is no benefit to using a prepared statement; just directly query the table.
Code: (100% Tested / Successful Code)
$string = "my name";
$conditions = [];
$parameters = [''];
foreach (array_unique(explode(' ', $string)) as $value) {
$conditions[] = "name LIKE ?";
$parameters[0] .= 's';
$parameters[] = "%{$value}%";
}
// $parameters now holds ['ss', '%my%', '%name%']
$query = "SELECT * FROM info";
if ($conditions) {
$stmt = $conn->prepare($query . ' WHERE ' . implode(' OR ', $conditions));
$stmt->bind_param(...$parameters);
$stmt->execute();
$result = $stmt->get_result();
} else {
$result = $conn->query($query);
}
foreach ($result as $row) {
echo "<div>{$row['name']} and whatever other columns you want</div>";
}
For anyone looking for similar dynamic querying techniques:
SELECT with dynamic number of values in IN()
INSERT dynamic number of rows with one execute() call
Write a generic query handler and pass it your query, the array of parameters, and the list of parameter types. Get back an array of results or messages. Here's my own personal version for mysqli (I mostly use PDO, but have a similar function set up for that as well). Do the same for inserts, updates, and deletes. Then simply maintain your one library and use it for everything you do :) Note that if you start with this, you'll probably want to do a better job of dealing with connection errors, etc.
<?php
// this is normally in an include() file
function getDBConnection(){
// your DB credentials
$hostname="127.0.0.1";
$username="ausername";
$password="supersecret";
$database="some_db_name";
$con = new mysqli($hostname, $username,$password, $database);
if($con->connect_error) {
return false;
}
return $con;
}
// generic select function.
// takes a query string, an array of parameters, and a string of
// parameter types
// returns an array -
// if $retVal[0] is true, query was successful and returned data
// and $revVal[1...N] contain the results as an associative array
// if $retVal[0] is false, then $retVal[1] either contains the
// message "no records returned" OR it contains a mysql error message
function selectFromDB($query,$params,$paramtypes){
// intitial return;
$retVal[0]=false;
// establish connection
$con = getDBConnection();
if(!$con){
die("db connection error");
exit;
}
// sets up a prepared statement
$stmnt=$con->prepare($query);
$stmnt->bind_param($paramtypes, ...$params);
$stmnt->execute();
// get our results
$result=$stmnt->get_result()->fetch_all(MYSQLI_ASSOC);
if(!$result){
$retVal[1]="No records returned";
}else{
$retVal[0]=true;
for($i=0;$i<count($result);$i++){
$retVal[]=$result[$i];
}
}
// close the connection
$con->close();
return $retVal;
}
$myusername=$_POST['username'];
$mypassword=$_POST['password'];
// our query, using ? as positional placeholders for our parameters
$q="SELECT useridnum,username FROM users WHERE username=? and password=?";
// our parameters as an array -
$p=array($myusername,$mypassword);
// what data types are our params? both strings in this case
$ps="ss";
// run query and get results
$result=selectFromDB($q,$p,$ps);
// no matching record OR a query error
if(!$result[0]){
if($result[1]=="no records returned"){
// no records
// do stuff
}else{
// query error
die($result[1]);
exit;
}
}else{ // we have matches!
for($i=1;$i<count($result);$i++){
foreach($result[$i] as $key->$val){
print("key:".$key." -> value:".$val);
}
}
}
?>
Forgive me if the question is a little odd
I can clarify if needed:
I have the code that can connect to a mysql database as normal, however i have encapsulated it as a class:
<?php
define("HOST", "127.0.0.1"); // The host you want to connect to.
define("USER", "phpuser"); // The database username.
define("PASSWORD", "Secretpassword"); // The database password.
class DBConnection{
function conn($sql, $database){
$DB = new mysqli(HOST,USER,PASSWORD,$database);
if ($DB->connect_error){
die("Connection failed: " . $DB->connect_error);
exit();
}
if ($result = $DB->query($sql)){
return TRUE;
$DB->close();
}
else{
echo "Error: " . $sql . "<br>" . $DB->error;
$DB->close();
}
}
}
?>
I have done it this way so i can include this class in any subsequent php page and allow them to send it an sql statment and the database, see below as an example:
$sql = ("INSERT INTO users (first_name, last_name, username, email, password, group_level) VALUES ('John', 'Doah','JDoah', 'example#email', 'password', 'user')");
$DB = new DBConnection;
$result = $DB->conn($sql,"members");
if ($result ==TRUE){
return "Record added sucessfully";
}
This works fine.
however, im looking to send other sql statments to DBConnection.
How do i do that and to have it pass back any results that it recives? errors, boolean, row data etc. The caller will worry about parsing it.
Hopefully that makes sense.
This is an old class I used to use way back in the days of mysql still works but will need to be updated for mysqli or newer
class DBManager{
private $credentials = array(
"host" => "localhost",
"user" => "",
"pass" => "",
"db" => ""
);
function DBManager(){
$this->ConnectToDBServer();
}
function ConnectToDBServer(){
mysql_connect($this->credentials["host"],$this->credentials["user"],$this->credentials["pass"]) or die(mysql_error());
$this->ConnectToDB();
session_start();
}
function ConnectToDB(){
mysql_select_db($this->credentials["db"]) or die(mysql_error());
}
function Insert($tableName,$data){
$parameters = '';
$len = count($data);
$i = 0;
foreach($data as $key => $value){
if(++$i === $len){
$parameters .= $key . "='$value'";
}else{
$parameters .= $key . "='$value'" . ", ";
}
}
$query = "INSERT INTO $tableName SET $parameters";
mysql_query($query) or die(mysql_error());
return true;
}
function GetRow($tableName,$select,$where){
$selection = '';
$len = count($select);
$i = 0;
foreach($select as $key){
if(++$i === $len){
$selection .= $key;
}else{
$selection .= $key . ",";
}
}
$whereAt = '';
foreach($where as $key => $value){
$whereAt .= $key . "='$value'";
}
$query = "SELECT $selection FROM $tableName WHERE $whereAt";
$result = mysql_query($query);
while($row = mysql_fetch_array($result)){
return $row;
}
}
}
The key things here is you can create a persistent connection to your database without rewriting a bunch of code
Example
global $DB;
$DB = new DBManager();
Since the connection happens in the constructor you will now have a connection on the page you call this code and can begin getting and setting to the database through use of $DB->GetRow() and $DB->Insert() which makes things much easier and was modeled after the $wpdb instance which is a class that manages the database in wordpress sites
Examples
For these examples we will assume you have a table as such
Insert new student
//create an associative array
$data = array(
"student_id" => 1,
"birth_date" => "02/06/1992",
"grade_level" => 4
);
//Send Call
$dm->Insert("student",$data);
Get data
//Create selection
$selection = array("grade_level");
//Create associative array for where we want to find the data at
$where = array(
"id" => 1
);
//Get Result
$result = $dm->GetRow("student",$selection,$where);
//do something with result
echo $result->grade_level;
I have a custom class that takes a sql connection as a parameter. I use that to populate the class, and then I'm trying to use it again to modify the results on screen. But after the first use, I can't use it anymore.
connection.php:
$conn = new mysqli('localhost', 'root', '', 'loveConnections');
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
personalityProfile.php (front end)
if (!isset($_SESSION['interests'])) {
$interests = new Interests($conn, $_SESSION['id']);
$_SESSION['interests'] = $interests;
} else {
$interests = $_SESSION['interests'];
}
interestsObject.php
class Interests {
// properties
public $conn;
public $id;
public $interestsArray = [];
public function __construct($conn, $memberId = null, $intArray = [
'basketball' => false,
'bowling' => false,
'movies' => false,
]) {
$this->conn = $conn;
$this->id = $memberId;
$this->interestsArray = $intArray;
$this->popArraySql();
}
public function popArraySql() {
$memInterests = [];
$sql = "SELECT i.interest
FROM memberInfo m
Join MemberInterestLink mi on (mi.memberID_FK = m.memberID_PK)
Join interests i on (mi.interestID_FK = i.interestID_PK)
WHERE memberID_PK = $this->id";
$result = $this->conn->query($sql);
$this->conn works perfectly here
foreach ($result as $row) {
array_push($memInterests, $row['interest']);
}
foreach ($this->interestsArray as $key => $value) {
for ($i=0; $i<sizeof($memInterests); $i++) {
if ($memInterests[$i] === $key) {
$this->interestsArray[$key] = true;
}
}
}
}
public function insertUpdateQuery() {
var_dump($this->conn);
foreach ($this->interestsArray as $key => $val) {
echo $key . "<br>";
$select = "SELECT interestID_PK from interests where interest = '" . $key . "'";
echo $select;
$result = $this->conn->query($select);
when I try and use it later though, I get a Warning: mysqli::query(): Couldn't fetch mysqli. Additionally, if I try and var_dump it, I get Warning: var_dump(): Property access is not allowed yet
var_dump($result);
if ($val === true) {
$insert = "INSERT INTO MemberInterestLink (memberID_FK, interestID_FK) VALUES ($this->id, $interestKey)";
$this->conn->query($insert);
} else {
$delete = "DELETE FROM MemberInterestLink WHERE interestID_FK = $interestKey";
$this->conn->query($delete);
}
}
}
}
I never close the connection, which is what most of the related answers suggested the cause may be. It's like my $conn variable just stops working after the first use.
I am trying to build a class to select records from table defined on user input.
my plan is to make a class that read user input conditions as an array, because there is a lot of other forms for other tables with different number of conditions. therefore I want to make one class that works with all.
basically am trying to achieve this statement:
select * from table_name where condition1=value1 AND condition2=value2
where the number of conditions varies depends on user input.
what I have done is this class:
class SelectQuery {
private $Error;
public $conn;
public $table;
public function __construct($conn){ //establish connection
$this->conn = $conn;
}
public function SelectData($table,$cols,array $conds){
$this->table = $table;
if($cols)
{
if($conds)
{
$i=0; $cond='';
foreach ($conds as $key => $value){
if($i==0)
{
$cond .= $key. '=' .$value;
}
else
{
$cond .= ' AND ' .$key. '=' .$value;
}
$i++;
}
$sql = 'SELECT '.$cols.' FROM '.$table.' WHERE '.$cond.'';
$stmt = oci_parse($this->conn, $sql);
oci_execute($stmt);
$rows = oci_fetch_all($stmt, $data, null, null, OCI_FETCHSTATEMENT_BY_COLUMN);
if($rows)
{
return $rows['0']['0'];
}
else
{
return NULL;
}
}
else
{
$sql = 'SELECT {$cols} FROM {$table}';
$stmt = oci_parse($this->conn, $sql);
oci_execute($stmt);
$rows = oci_fetch_all($stmt, $data, null, null, OCI_FETCHSTATEMENT_BY_COLUMN);
if($rows)
{
return $rows['0']['0'];
}
else
{
return NULL;
}
}
}
}
and this is how the data is sent from form:
$manager = new OracleConnectManager();
$conn = $manager->establishConnection(); //establish connection
if( $conn ){
$table = 'MAIN';
$cols= '*';
$conds = array(
'id_number' => $_POST['id_number'],
'firstname' => $_POST['firstname'],
'secondname' => $_POST['secondname'],
'thirdname' => $_POST['thirdname'],
'familyname' => $_POST['familyname'],
'department' => $_POST['department'],
);
$sel = new SelectQuery($conn);
$dth = $sel->SelectData($table,$cols,$conds);
echo $dth;
}
when I run the code i get this error:
Warning: oci_execute(): ORA-00936: missing expression
(in the SelectQuery class, line: oci_execute($stmt); )
Warning: oci_fetch_all(): ORA-24374: define not done before fetch or execute and fetch
(in the SelectQuery class, line: $rows = oci_fetch_all($stmt, $data, null, null, OCI_FETCHSTATEMENT_BY_COLUMN); )
and there is no output.
any help would be appreciated.
thanks
There are two things:
You need to validate all the $_POST values and build $conds array for values that are set in $_POST.
Update:
i.e. if you have only one or two post values then the $conds array should be:
$conds = array(
'id_number' => $_POST['id_number'],
'firstname' => $_POST['firstname']
)
In your foreach loop, $value needs to be quoted if it is varchar type as:
foreach ($conds as $key => $value){
if($i==0)
{
$cond .= "$key='$value'";
}
else
{
$cond .= " AND $key='$value'";
}
$i++;
}
Update:
if you have int and varchar fields then do formatting when building array itself:
$conds = array(
'id_number' => $_POST['id_number'], // int type
'firstname' => "'".$_POST['firstname']."'" // string type
)
else
{
$sql = 'SELECT ' . $cols . ' FROM ' . $table;
// Other Statements
}
Hope the ELSE part for $sql should be framed like above?
I'm having trouble finding good documentation on pdo update prepared statements and even more trouble finding documentation on dynamically updating the database with pdo prepared statements. I've gotten my dynamic insert to work but am having trouble with the update. The error I'm getting is:
Warning: PDOStatement::execute() [pdostatement.execute]:
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
in
/Users/scottmcpherson/Sites/phpsites/projectx/application/models/db.php
on line 91 error
Here is the class I created minus a couple of methods that are irrelevant to this problem:
<?php
require_once("../config/main.php");
class Database{
protected static $dbFields = array('username', 'password');
public $db;
public $tableName = 'users';
public $id = 1;
public $username = "Jonny";
public $password = "Appleseed";
public function __construct() {
$this->connect();
}
public function connect(){
try {
$this->db = new PDO("mysql:host=".DB_SERVER."; dbname=".DB_NAME, DB_USER, DB_PASS);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
public function properties() {
$properties = array();
foreach (self::$dbFields as $field) {
if (isset($this->field) || property_exists($this, $field)) {
$properties[$field] = $this->$field;
}
}
return $properties;
}
public function propertyValues() {
$property = $this->properties();
$propertyValues = array();
foreach ($property as $key => $value) {
$propertyValues = ":" . implode(", :", array_keys($property));
}
return $propertyValues;
}
public function polishedVals(){
// The end result of this function is:
// username=:username, password=:password
$props = $this->properties();
$phaseOne = array();
foreach ($props as $key => $value) {
$phaseOne[$key] = ":".$key;
}
$phaseTwo = array();
foreach ($phaseOne as $key => $value) {
$phaseTwo[] = "{$key}={$value}";
}
$polishedVals = implode(", ", $phaseTwo);
return $polishedVals;
}
public function update(){
$stmt = "UPDATE ". $this->tableName." SET ";
$stmt .= $this->polishedVals();
$stmt .= "WHERE id=" . $this->id;
$stmt = $this->db->prepare($stmt);
if($stmt->execute($this->properties())) {
echo "yes";
} else {
echo "error ";
}
}
}
$database = new Database();
echo$database->update();
?>
With all the variables replaced with the actual values, the result I'm going for with the update() method would look like this:
public function update(){
$stmt = "UPDATE users SET ";
$stmt .= "username=:username, password=:password ";
$stmt .= "WHERE id=1";
$stmt = $this->db->prepare($stmt);
if($stmt->execute($this->properties())) {
echo "yes";
} else {
echo "error ";
}
}
In addition to spotting this problem, please let me know if you see any other issues with this code. I'm still kind of new to PHP.
Edit: I've now created a new method that adds a : to the beginning of each key in the properties array:
public function colProperties(){
$properties = $this->properties();
$withCols = array();
foreach($properties as $key => $value){
$withCols[":".$key] = $value;
}
return $withCols;
}
So my update() method now looks like:
public function update(){
$stmt = "UPDATE ". $this->tableName." SET ";
$stmt .= $this->polishedVals();
$stmt .= "WHERE id=" . $this->id;
$stmt = $this->db->prepare($stmt);
if($stmt->execute($this->colProperties())) {
echo "yes";
} else {
echo "error ";
}
}
and if I var_dump($this->colProperties) I get:
array(2) { [":username"]=> string(5) "Jonny" [":password"]=> string(9) "Appleseed" }
And still getting the same error.
I don't think that passing parameters to an UPDATE query requires a different method than a SELECT one. The information in the PDOStatement->execute() manual page should apply:
<?php
/* Execute a prepared statement by passing an array of insert values */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->execute(array(':calories' => $calories, ':colour' => $colour));
?>
You are using named parameters so execute() expects an associative array. Use var_dump() to display $this->properties() right before execute():
var_dump($this->properties())
Make sure you keys match exactly.
The error is that in between
$stmt .= $this->polishedVals();
$stmt .= "WHERE id=" . $this->id;
There needs to be a space in between the WHERE clause as the polishedVals() method does not add a space after the implode. So, you'll have something like
UPDATE User SET city=:city, location=:locationWHERE User.id=28
Which causes the error.
Simple bug.