I'm playing around with MySQLi at the moment, trying to figure out how it all works. In my current projects I always like to echo out a query string while coding, just to make sure that everything is correct, and to quickly debug my code. But... how can I do this with a prepared MySQLi statement?
Example:
$id = 1;
$baz = 'something';
if ($stmt = $mysqli->prepare("SELECT foo FROM bar WHERE id=? AND baz=?")) {
$stmt->bind_param('is',$id,$baz);
// how to preview this prepared query before acutally executing it?
// $stmt->execute();
}
I've been going through this list (http://www.php.net/mysqli) but without any luck.
EDIT
Well, if it's not possible from within MySQLi, maybe I'll stick with something like this:
function preparedQuery($sql,$params) {
for ($i=0; $i<count($params); $i++) {
$sql = preg_replace('/\?/',$params[$i],$sql,1);
}
return $sql;
}
$id = 1;
$baz = 'something';
$sql = "SELECT foo FROM bar WHERE id=? AND baz=?";
echo preparedQuery($sql,array($id,$baz));
// outputs: SELECT foo FROM bar WHERE id=1 AND baz=something
Far from perfect obviously, since it's still pretty redundant — something I wanted to prevent — and it also doesn't give me an idea as to what's being done with the data by MySQLi. But I guess this way I can quickly see if all the data is present and in the right place, and it'll save me some time compared to fitting in the variables manually into the query — that can be a pain with many vars.
I don't think you can - at least not in the way that you were hoping for. You would either have to build the query string yourself and execute it (ie without using a statement), or seek out or create a wrapper that supports that functionality. The one I use is Zend_Db, and this is how I would do it:
$id = 5;
$baz = 'shazam';
$select = $db->select()->from('bar','foo')
->where('id = ?', $id)
->where('baz = ?', $baz); // Zend_Db_Select will properly quote stuff for you
print_r($select->__toString()); // prints SELECT `bar`.`foo` FROM `bar` WHERE (id = 5) AND (baz = 'shazam')
I have struggled with this one in the past. So to get round it I wrote a little function to build the SQL for me based on the SQL, flags and variables.
//////////// Test Data //////////////
$_GET['filmID'] = 232;
$_GET['filmName'] = "Titanic";
$_GET['filmPrice'] = 10.99;
//////////// Helper Function //////////////
function debug_bind_param(){
$numargs = func_num_args();
$numVars = $numargs - 2;
$arg2 = func_get_arg(1);
$flagsAr = str_split($arg2);
$showAr = array();
for($i=0;$i<$numargs;$i++){
switch($flagsAr[$i]){
case 's' : $showAr[] = "'".func_get_arg($i+2)."'";
break;
case 'i' : $showAr[] = func_get_arg($i+2);
break;
case 'd' : $showAr[] = func_get_arg($i+2);
break;
case 'b' : $showAr[] = "'".func_get_arg($i+2)."'";
break;
}
}
$query = func_get_arg(0);
$querysAr = str_split($query);
$lengthQuery = count($querysAr);
$j = 0;
$display = "";
for($i=0;$i<$lengthQuery;$i++){
if($querysAr[$i] === '?'){
$display .= $showAr[$j];
$j++;
}else{
$display .= $querysAr[$i];
}
}
if($j != $numVars){
$display = "Mismatch on Variables to Placeholders (?)";
}
return $display;
}
//////////// Test and echo return //////////////
echo debug_bind_param("SELECT filmName FROM movies WHERE filmID = ? AND filmName = ? AND price = ?", "isd", $_GET['filmID'], $_GET['filmName'], $_GET['filmPrice']);
I have also build a little online tool to help.
Mysqli Prepare Statement Checker
I recently updated this project to include composer integration, unit testing and to better handle accepting arguments by reference (this requires updating to php 5.6).
In response to a request I received on a project I created to address this same issue using PDO, I created an extension to mysqli on github that seems like it addresses your issue:
https://github.com/noahheck/E_mysqli
This is a set of classes that extend the native mysqli and mysqli_stmt classes to allow you to view an example of the query to be executed on the db server by interpolating the bound parameters into the prepared query then giving you access to resultant query string as a new property on the stmt object:
$mysqli = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName);
$query = "UPDATE registration SET name = ?, email = ? WHERE entryId = ?";
$stmt = $mysqli->prepare($query);
$stmt->bindParam("ssi", $_POST['name'], $_POST['email'], $_POST['entryId']);
$stmt->execute();
echo $stmt->fullQuery;
Will result in:
UPDATE registration SET name = 'Sue O\'reilly', email = 'sue.o#example.com' WHERE entryId = 5569
Note that the values in the fullQuery are escaped appropriately taking into account the character set on the db server, which should make this functionality suitable for e.g. log files, backups, etc.
There are a few caveats to using this, outlined in the ReadMe on the github project, but, especially for development, learning and testing, this should provide some helpful functionality.
As I've outlined in the github project, I don't have any practical experience using the mysqli extension, and this project was created at the request of users of it's sister project, so any feedback that can be provided from devs using this in production would be greatly appreciated.
Disclaimer - As I said, I made this extension.
Just set it to die and output the last executed query. The Error handling should give you meaningful information which you can use to fix up your query.
You can turn on log queries on mysql server.
Just execute command:
sql> SHOW VARIABLES LIKE "general_log%";
sql> SET GLOBAL general_log = 'ON';
And watch queries in the log file.
After testing turn log off:
sql> SET GLOBAL general_log = 'OFF';
I was able to use var_dump() to at least get a little more info on the mysqli_stmt:
$postmeta_sql = "INSERT INTO $db_new.wp_postmeta (post_id, meta_key, meta_value) VALUES (?, ?, ?)";
$stmt = $new_conn->prepare($postmeta_sql);
$stmt->bind_param("sss", $post_id, $meta_key, $meta_value);
echo var_dump($stmt);
$stmt->execute();
$stmt->close();
Related
Im new to database and i have written a LOT of PHP code that accesses a database using MySQL.
I didnt take into account SQL injection attacks so i have to re-write all that PHP code to use mysql prepared statements.
After looking at videos on how to used prepared SQL statements, to perform just ONE SQL command requires a whole lot of "prepared" statements. My existing code has lots of different SQL statements all over the place, it would be a nightmare to change all that code to pack and unpack all the required preparation for each "prepared" statement command.
Is there some kind of wrapper i can use to prevent turning one line of regular SQL into 6 or 7 lines of prepared statements?
For example use to do this line line of SQL
SELECT * from users where userid=10
needs many more lines of prepared SQL statements, especially if there are lots of other SQL statements too it now becomes very complex.
Is there was some sort of one line wrapper that i can call that accepts the template SQL string, plus the parameters, which also executes the command and returns the result in just one line of wrapper for different types of MYSQL statements it would be great and the code would be much less confusing looking and error prone.
For example
$users=WrapAndExecute($db,"SELECT * from users where userid=?","s",$userid);
$data=WrapAndExecute($db,"UPDATE table SET username=?,city=?","ss",$name,$city);
$result=WrapAndExecute($db,"DELETE from table where id=?","s",$userid);
$result=WrapAndExecute($db,"INSERT into ? (name,address) VALUES(?,?)","ss","users",$name,$address);
Each of those lines above would create a prepared statement template, do the bind, execute it and return the result that a regular MYSQL statement would. This would create minimal impact on existing code.
Anybody knows how to do this or if some easy php library or class already exists to do this, that i can just import and start using it?
Thanks
You don't need to change a query to a prepared statement if it has no PHP variables in it. If it has just constant expressions, it's safe from SQL injection.
$sql = "SELECT * from users where userid=10"; // Safe!
$stmt = $pdo->query($sql);
$data = $stmt->fetchAll();
You don't need to change a query that contains PHP variables, as long as the value of that variable is a constant specified in your code. If it doesn't take its value from any external source, it's safe.
$uid = 10;
$sql = "SELECT * from users where userid=$uid"; // Safe!
$stmt = $pdo->query($sql);
$data = $stmt->fetchAll();
You don't need to change a query that contains PHP variables, as long as you can filter the value to guarantee that it won't risk an SQL injection. A quick and easy way to do this is to cast it to an integer (if it's supposed to be an integer).
$uid = (int) $_GET['uid'];
$sql = "SELECT * from users where userid=$uid"; // Safe!
$stmt = $pdo->query($sql);
$data = $stmt->fetchAll();
That leaves cases where you are using "untrusted" values, which may have originated from user input, or reading a file, or even reading from the database. In those cases, parameters are the most reliable way to protect yourself. It's pretty easy:
$sql = "SELECT * from users where userid=?"; // Safe!
// two lines instead of the one line query()
$stmt = $pdo->prepare($sql);
$stmt->execute([$_GET['uid']]);
$data = $stmt->fetchAll();
In a subset of cases, you need one additional line of code than you would normally use.
So quit your whining! ;-)
Re your comment about doing prepared statements in mysqli.
The way they bind variables is harder to use than PDO. I don't like the examples given in http://php.net/manual/en/mysqli.prepare.php
Here's an easier way with mysqli:
$sql = "SELECT * from users where userid=?"; // Safe!
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $_GET['uid']);
$stmt->execute();
$result = $stmt->get_result();
$data = $result->fetch_all();
I don't like the stuff they do in their examples with bind_result(), that's confusing and unnecessary. Just use get_result(). So with mysqli, you need two more lines of code than you would with PDO.
I've written query wrappers for mysqli that emulate the convenience of PDO's execute() function. It's a PITA to get an array mapped to the variable-arguments style of bind_param().
See the solution in my answers to https://stackoverflow.com/a/15933696/20860 or https://stackoverflow.com/a/7383439/20860
I were in the same boat, and I wrote such a wrapper that works exactly the way you want, save for it's being a class, not a function.
$user = $sdb->getRow("SELECT * from users where userid=?s", $userid);
$sdb->query("UPDATE table SET username=?s, city=?s", $name, $city);
$sdb->query("DELETE from table where id=?s", $userid);
$sdb->query("INSERT into ?n (name,address) VALUES(?s,?s)","users", $name, $address);
The above is a working code, as long as you have somewhere in your bootstrap file
$db = mysqli_connect(...);
...
require 'safemysql.class.php';
$sdb = new SafeMySQL('mysqli' => $db);
Note that none of the other suggestions could do anything like that.
Also note that if I were writing it today, I would have used PDO, as this class is duplicating a lot of functionality already exists in PDO.
Take a look at the PDO extension in PHP - http://php.net/manual/en/intro.pdo.php: it it secure against injections thanks to prepared statements; also, it allows you to connect to many different databases (e.g. MySQL, MSSQL, etc.).
You can then build your own wrapper as you wish to keep it clean; for example your own wrapper could be as follows:
(following example will return user rows as objects)
// connect to DB
$GLOBALS['default_db'] = new DB('localhost','db_name','username','password') ;
// Get users and output results
$query = new DBQuery('SELECT * FROM users WHERE userid = ?',array(10)) ;
var_dump($query -> results()) ;
var_dump($query -> num_rows()) ;
// DB connection
class DB {
public $connection;
public function __construct($host , $dbname , $username , $password) {
$this->connection = new \PDO('mysql:host=' . $host . ';dbname=' . $dbname , $username , $password);
}
}
// Wrapper
class DBQuery {
private $num_rows = 0;
private $results = array();
public function __construct($query , $params = null , $class_name = null , DB $db = null) {
if ( is_null($db) ) {
$db = $GLOBALS['default_db'];
}
$statement = $db->connection->prepare($query);
$statement->execute($params);
$errors = $statement->errorInfo();
if ( $errors[2] ) {
throw new \Exception($errors[2]);
}
$fetch_style = ($class_name ? \PDO::FETCH_CLASS : \PDO::FETCH_OBJ);
$this->results = $class_name ? $statement->fetchAll($fetch_style , $class_name) : $statement->fetchAll($fetch_style);
$this->num_rows += $statement->rowCount();
while ( $statement->nextrowset() ) {
$this->results = array_merge($this->results,$class_name ? $statement->fetchAll($fetch_style , $class_name) : $statement->fetchAll($fetch_style));
$this->num_rows += $statement->rowCount();
}
}
public function num_rows() {
return $this->num_rows;
}
public function results() {
return $this->results;
}
}
Since a key requirement seems to be that you can implement this with minimal impact on your current codebase, it would have been helpful if you had told us what interface you currently use for running your queries.
While you could use PDO:
that means an awful lot of work if you are not already using PDO
PDO exceptions are horrible
Assuming you are using procedural mysqli (and have a good reason not to use mysqli_prepare()) its not that hard to write something (not tested!):
function wrapAndExecute()
{
$args=func_get_args();
$db=array_shift($args);
$stmt=array_shift($args);
$stmt_parts=explode('?', $stmt);
if (count($args)+1!=count($stmt_parts)) {
trigger_error("Argument count does not match placeholder count");
return false;
}
$real_statement=array_shift($stmt_parts);
foreach ($args as $k=>$val) {
if (isnull($val)) {
$val='NULL';
} else if (!is_numeric($val)) {
$val="'" . mysqli_real_escape_string($db, $val) . "'";
}
$real_statement.=$val . array_shift($stmt_parts);
}
return mysqli_query($db, $real_statement);
}
Note that this does not handle IS [NOT] NULL nicely nor a literal '?' in the statement nor booleans (but these are trivial to fix).
I have found the PDO::FETCH_CLASS very useful. My classes map to tables. I just do a
$query = $pdo->query("SELECT * FROM fixedTime WHERE
transmissionProgramID = '$transmissionProgramID'");
$query->setFetchMode(PDO::FETCH_CLASS, 'FixedTime');
and voila.
I would like to be able to do the reverse: ie instantiate an object load up the values to UPDATE or INSERT and once again voila.
Have looked but cannot see if this is available.
Well, yes. To some extent you can use something similar for insert or update.
But to achieve that, you have to learn how to use PDO properly. So, first we have to fix your select code:
$sql = "SELECT * FROM fixedTime WHERE transmissionProgramID = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$transmissionProgramID]);
$stmt->setFetchMode(PDO::FETCH_CLASS, 'FixedTime');
$ftime = $stmt->fetch();
See - we are using prepared statements here, that you should be always using anyway. And at the same time that's the key for the [semi-]automation we can use with updates. Because with prepared statements you can use the object itself to provide values for the prepared query.
So, as long as you have object properties reflect table fields you can use a code like this:
$user = new stdClass();
$user->name = "foo";
$user->pass = "bar";
$sql = "INSERT INTO users VALUES (NULL, :name, :pass)";
$pdo->prepare($sql)->execute((array)$user);
But for the real automation you have to consider using an ORM, which is doing exactly what you're looking for. You can take a look at Eloquent for example. So, the code would be as simple and straightforward as
$ftime = new fixedTime;
$ftime->value = time();
$ftime->save();
So I'm making my own blog scripts using MYSQL and PHP.
I had the whole 'writing the blog to a database' thing working perfectly, until I realised that if you tried to write a blog with speech marks, this would prevent the INSERT statement from working (obviously - the speechmarks were ending the SQL statement).
So I tried to use real_escape_string, and now the INSERT doesn't work even if you exclude quotes.
I tried using:
sqlstate
in order to find out the issue, and it returned "42000" - which, after googling for a little bit, refers to a syntax error, which doesn't make much sense as there is no syntax error before the use of real_escape_string.
Also, I'm now getting this error:
Call to a member function close() on a non-object in /postarticle.php on line 37
Which refers to the close() call in the ELSE statement.
Please may you help? Been going round in circles for a while. Here is my code:
<?php
$host = 'CENSORED';
$user = 'CENSORED';
$pass = 'CENSORED';
$db = 'CENSORED';
$connection = new mysqli($host,$user,$pass,$db);
$_SESSION["article"] = $_POST["article"];
$date_of_blog = getdate();
$article = ($_SESSION["article"]);
$sql1 = "SELECT * FROM `Blogs`";
$res1 = $connection->query($sql1);
$newrows = $res1->num_rows + 1;
$sql2 = "INSERT INTO Blogs(BlogID, Blog_Contents, D_O_B) VALUES ('$newrows','$article','$date_of_blog')";
$sql2 = $connection->real_escape_string($sql2);
$res2 = $connection->query($sql2);
if ($res2->num_rows == $newrows)
{
$res->close();
$connection->close();
header( 'Location: adminpanel.php' );
}
else
{
echo ($connection->sqlstate);
$connection->close();
$res->close();
}
exit();
?>
Also, on a side note, the getdate() call that I've got has never worked. In the database every blog post comes up as:
0000:00:00 00:00:00
EDIT:
Issue is now solved. Find the functional code below:
<?php
$host = 'CENSORED';
$user = 'CENSORED';
$pass = 'CENSORED';
$db = 'CENSORED';
$connection = new mysqli($host,$user,$pass,$db);
$_SESSION["article"] = $_POST["article"];
$article = ($_SESSION["article"]);
$article = $connection->real_escape_string($article);
$sql1 = "SELECT * FROM `Blogs`";
$res1 = $connection->query($sql1);
$newrows = $res1->num_rows + 1;
$sql2 = "INSERT INTO Blogs(BlogID, Blog_Contents, D_O_B) VALUES (\"$newrows\",\"$article\",CURDATE())";
$res2 = $connection->query($sql2);
if ($res2 != false)
{
header( 'Location: adminpanel.php' );
}
else
{
echo ($connection->sqlstate);
}
$connection->close();
$res->close();
exit();
?>
I'm very sorry if these questions are basic and annoy the professionals around here; I've tried to follow the guidelines and I've googled for a while etc. I just haven't found any solutions that match my issue(s).
Thankyou for your time.
There are a number issues with the code as originally posted. Chiefly, the cause of the two issues you initially identified is a misuse of mysqli::real_escape_string(). It needs to be called on each variable individually which appears in the code. So instead of calling it on the whole statement, it must be called multiple times for multiple variables like:
$article = $connection->real_escape_string($connection);
The failure of the query due to incorrect quoting (due to real_escape_string()) is the reason for the error message calling close().
As ascertained in the comments, you are using num_rows + 1 to validate that one new row has been inserted based on the previous number of rows returned. This is problematic for a few reasons. Mainly, it exposes a race condition wherein a row may be inserted from two sessions at once and one or both will fail because the expected value for $newrows doesn't match. Really BlogID should be an auto_increment column in your database. That eliminates the need for any logic around it whatsoever. You don't even need to include it in the INSERT because it will be automatically incremented.
That also completely eliminates the need for the first SELECT statement.
Substituting MySQL's native NOW() function for the date value, you can simplify the statement to:
INSERT INTO Blogs (Blog_Contents, D_O_B) VALUES ('$article', NOW())
To test success or failure of the insert, you just need to verify that its variable is not false.
Putting this together, your code can be reduced as:
if (!isset($_POST['article'])) {
// exit or handle an empty post somehow...
}
$connection = new mysqli($host,$user,$pass,$db);
$_SESSION["article"] = $_POST["article"];
// Escape $article for later use
$article = $connection->real_escape_string($_SESSION["article"]);
// Only an INSERT is needed. $article is already escaped
$sql = "INSERT INTO Blogs (Blog_Contents, D_O_B) VALUES ('$article', NOW())";
// Run the query
$res = $connection->query($sql);
// Test for failure by checking for a false value
if ($res) {
// The connection & resource closure can be omitted
// PHP will handle that automatically and implicitly.
header( 'Location: adminpanel.php' );
// Explictly exit as good practice after redirection
exit();
}
else {
// The INSERT failed. Check the error message
echo $connection->error;
}
This should bring your current code into working order. However, since you're learning this it is an excellent time to begin learning to use prepared statements via prepare()/bind_param()/execute() in MySQLi. This is a recommended best practice to prevent SQL injection, although using real_escape_string() works as long as you use it correctly and never forget.
See How can I prevent SQL injection in PHP for examples.
But it would look like:
// connection already established, etc...
// Prepare the statement using a ? placeholder for article
$stmt = $connection->prepare("INSERT INTO Blogs (Blog_Contents, D_O_B) VALUES (?, NOW())");
if ($stmt) {
// bind in the variable and execute
// Note that real_escape_string() is not needed when using
// the ? placeholder for article
$stmt->bind_param('s', $_SESSION['article']);
$stmt->execute();
// Redirect
header( 'Location: adminpanel.php' );
exit();
}
else {
echo $connection->error;
}
You need to apply the real_escape_string function to the variables not the entire SQL string.
$sql2 = "INSERT INTO Blogs(BlogID, Blog_Contents, D_O_B) VALUES ('".$connection->real_escape_string($newrows)."','".$connection->real_escape_string($article)."','".$connection->real_escape_string($date_of_blog)."')";
The purpose is to remove anything that might be misinterpreted as query functions by MySQL, but there are parts of the query that you obviously want to be interpreted as such.
A few keep telling me that my code for updating data in my mysqli query is extremely insecure. Actually, several people on this site. So I would like to know what they say would secure my code below so it is secure when updating my database. I would like to know how the would secure my mysqli query.
Okay, in my code for my database entries, this is what I do. Let me start by saying that I always send via POST method to avoid browser url complications.
When I get the POST data, this is my code.
$ID = 1;
$DATA = htmlentities(addslashes($_POST['data']));
$FIELD = "lifename";
$DBQUERY = "UPDATE `lifetable` SET `$FIELD` = '$DATA' WHERE `id` = $ID";
$DBRESULT = $MYSQLI->query($DBQUERY);
I am currently using this on my local site.
How is this unsafe if I have escaped all quotes, all slashes, all ampersands (from javascript through ajax) and all semi colons? How is this vunerable?
So can you tell me what I should change when adding information to my database.
Thanks
PS ... I am using mysqli and will continue to use it. Thanks
A few suggested that I change from mysqli to pdo, but I am not willing to completely 100% change how I access data from my databases. Someone posted another link before about prepare and bind_param and this is what I am going to use. So thank you.
This is now my code, and binding params is supposed to make it so that each param is only for the one part of my query and can not be for anything else, nothing else at all.
$DBQUERY = "UPDATE `lifetable` SET `lifename` = ? WHERE `id` = ?"; // EACH ? IS A PART OF bind_param BELOW IN ORDER AFTER TYPE.
$STMT = $MYSQLI->prepare($DBQUERY);
$STMT->bind_param('si', $DATA, $ID); // THIS MAKES SURE THAT THE VARIABLES ARE ONLY USED FOR THERE PLACE HERE AND NOTHING ELSE. ? in order.
$DATA = htmlentities($_POST['data']); // I STILL USE MY CODE HERE TO REMOVED ANY OTEHR CHARACTERS, JUST INCASE. AND BEFORE IT GETS HERE, IT USES encodeURIComponent TO OUTPUT FROM AJAX.
$ID = $COLUMN[1];
$STMT->execute();
$STMT->close();
My code worked before and it works now, just more secure, or so I am told.
Use PDO Class like:
$db = new PDO('mysql:host=localhost;dbname=<SOMEDB>', '<USERNAME>', 'PASSWORD');
$query = $db->prepare('UPDATE `lifetable` SET :FIELD = :DATA WHERE `id` = :ID');
$query->execute(array(
':FIELD' => $field,
':DATA' => $data,
':ID' => $id
));
$query->commit();
For more info Are there good tutorials on how to use PDO?
i think your security lies in the SQL injection, and the best way i know to make the query secure is using mysql_real_escape_string on the var. Here an example taken from php.net
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$city = $mysqli->real_escape_string($city);
$mysqli->query("INSERT into myCity (Name) VALUES ('$city')")
you can apply the same procedure to your query
$ID = 1;
$DATA = $MYSQLI->real_escape_string($_POST['data']));
$FIELD = "lifename";
$DBQUERY = "UPDATE `lifetable` SET `$FIELD` = '$DATA' WHERE `id` = $ID";
$DBRESULT = $MYSQLI->query($DBQUERY);
I edited the above because I forgot the quotes for lifename in my question. They should be there as they are in my original code.
now tour query should be secure :D
here the reference to php.net documentation :
http://cn2.php.net/manual/en/mysqli.real-escape-string.php
I am relatively new to PHP OOP and i know that there are numerous questions here on SO, but none of them seam to be pointing me in the right direction. I have created the class user, and I am calling this in another file.
I am trying to get the method 'reset' to call up 'connect', connect to the mysql db and then query it and set various properties to the row contents.
I am receiving no errors but for some reason it is not feeding the properties any data from the database.
I have tried placing the mySQL connect in the reset method, just to see if the variables cannot be passed between methods. But still no joy.
Can anyone point me in the right direction?
class user(){
public function reset(){
$this->connect();
$sql ='SELECT * FROM users WHERE user_id="'.$user_id.'"' ;
$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result))
{
$this->user_name=$row['dtype'];
$this->user_id=$row['user_id'];
$this->atype=$row['atype'];
$this->user_email=$row['user_email'];
$this->group1=$row['group1'];
$this->group2=$row['group2'];
$this->group3=$row['group3'];
$this->group4=$row['group4'];
$this->group5=$row['group5'];
$this->group6=$row['group6'];
}
// Test that these properties are actually being echoed on initial file... it is
// $this->user_name = "john";
// $this->user_email = "john#gmail.com";
// $this->dtype = "d";
// $this->atype = "f";
}
public function connect(){
//GLOBALS DEFINED IN INDEX.PHP
if ($db_open !== true){
$con=mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
// Check connection
if (mysqli_connect_errno())
{
$debug_system .= 'Error on user.php: ' . mysqli_connect_error().'<br\/>';
} else {
$db_open = true;
$debug_system .= 'user.php: user details grab successful. <br\/>';
}
}
}
}
If you are relatively new to PHP OOP, it is strongly recommended not to mess with awful mysqli API but learn quite sensible PDO first, and only then, making yourself familiar with either OOP and prepared statements, you may turn to mysqli.
Nevertheless, there shouldn't be no function connect() in the class user. You have to have a distinct db handling class, which instance have to be passed in constructor of user class
The problem lies in this line:
$sql ='SELECT * FROM users WHERE user_id="'.$user_id.'"' ;
At no point do you actually define $user_id. Presumably you actually mean $this->user_id.
$sql ='SELECT * FROM users WHERE user_id="'.$this->user_id.'"' ;
Better still would be to make full use of parameterized queries, which might look like this:
$sql ='SELECT * FROM users WHERE user_id=?' ;
You would then prepare the statement and bind the user ID, then execute the query:
$stmt = mysqli_prepare($sql);
mysqli_stmt_bind_param($stmt, $this->user_id);
mysqli_stmt_execute($stmt);
And then fetch the results:
while($row = mysqli_stmt_fetch($result))
As you can see, there is a whole load more to modern MySQL libraries. I'd advise you to do more research into how MySQLi and parameterized queries work (and perhaps PDO as well: it's a superior library) before you use them further. It will be worth the effort.