Novice Alert
A mySQL table "tokens" contains a field, "dl" (DL), which is an integer (values: 0, 1 or 2)
For the row where field "token"==$stripped_token, the current value of "dl" is 0
I wish to read the record, increment the number found in field "DL" (zero) and update the record. Here's what I'm trying:
function sql_update_token($stripped_token)
{
global $mysqli ;
$curr_dl = $mysqli->query("SELECT dl FROM tokens WHERE token = ".$stripped_token) or die (mysqli_error());
$new_num = $curr_dl + 1;
$result = $mysqli->query("UPDATE tokens SET dl=".$new_num." WHERE token = ".$stripped_token) or die (mysqli_error());
}
The value of field DL is now "2" ! Why 2?
In troubleshooting the above, I tried this:
function sql_get_dl($stripped_token)
{
global $mysqli ;
$curr_dl_num = $mysqli->query("SELECT dl FROM tokens WHERE token = ".$stripped_token) or die (mysqli_error());
return $curr_dl_num;
}
$test = sql_get_token($stripped_token);
echo('[$test] == [ '.$test.' ]<br />');
The problem is that $test does not contain the number "0", as I had hoped. Instead, it contains: "current_field", "field_count", "lengths", "num_rows" and "type" (those text strings, in an array.
What are my errors?
One problem is that msysqli->query doesn't return the value you think it returns. It returns a result object. You then need to get at the data in that result. i.e.:
global $mysqli ;
$result = $mysqli->query("SELECT dl FROM tokens WHERE token = ".$stripped_token) or die (mysqli_error());
$row = $result->fetch_row();
$curr_dl_num = $row[0];
Think of $result as a table. fetch_row() gets the first row, and $row[0] gets the first cell of that row. This is really inconvenient, since you are only getting a table with one value in it, but with other queries, where multiple results are returned, being able to step through them using fetch_row() is really useful.
As well, how are you generating your $stripped_token value, since you said that wasn't behaving as you expected? If you are reading it from a mySQL query, your problem is probably the same - it might be a result object, and not a single value as you expect.
EDIT:
Never mind the bit about $stripped_token, I misinterpreted the last part of your question.
Related
<?php
$connect = mysqli_connect("localhost", "root", "", "hempbag_db") or die("Connection failed");
$query= "Select * from tbl_sales";
$ress = mysqli_query($connect, $query);
$result = mysqli_fetch_array($ress);
foreach($result as $a)
{
echo $a['ID']; // This doesnt print although i used fetch array
}
foreach($ress as $a)
{
echo $a['ID']; // This works why???? This variable has only query run
}
?>
Why does the upper foreach does not run and lower one does? Can anyone explain please?
When you run a query, it returns a result:
$ress = mysqli_query($connect, $query);
var_dump($ress); // You will see it's a result.
At this point $ress just contains the result of what you just queried. Think of it like this:
You goto the warehouse, and you make and order for 1000 boxes of crackers. She heads to the back, and gets your boxes ready, and comes back and hands you a piece of paper with the order number. (This is $ress). Now, you can't loop through that, you can't do anything with that.
You now take that piece of paper, and you hand it to your assistant, and you say you want to get all the crackers on your trucks (This is now mysqli_fetch_array()). Your assistant goes, fetches it, and returns you the crackers.
Simply put, mysqli_query just returns an object like Result#1. From Result#1, mysql can tell you how many rows were returned mysql_num_rows(Result#1), or get actual data if it was a select query: mysqli_fetch_array(Result#1).
Now onto the reasoning: Performance. Let's say you didn't want 1000 crackers, you just wanted to know if they had 1000 crackers. If she came back with all the boxes of crackers and you had to count them yourself, it would be much more difficult. Instead, with that piece of paper, she can determine how many boxes you were able to order. Less data being transferred, and much more efficient.
Just a small note, in later versions of php, they made it so the result is iterable, meaning that if you try and loop through it, it will automagically call mysqli_fetch_array on that result, and return you the results.
Additionally, mysql_fetch_array will return one row from the database, and is not able to be looped through via foreach. Perhaps you were thinking of mysqli_fetch_all? This returns all rows and can be looped through (Although is a bit less performant than using a while loop with mysqli_fetch_array)
$ress = mysqli_query($connect, $query);
This line returns a result set which is Traversable. So your second foreach works fine.
whereas the following line (mysqli_fetch_array) gets one row at a time and makes it an array.
$result = mysqli_fetch_array($ress); // Suppose you have 3 rows, Now cursor is at row 1
echo $result["ID"]; // this will print FIRST row's ID
$result = mysqli_fetch_array($ress); // Now cursor is at row 2
echo $result["ID"]; // this will print SECOND row's ID.
$result = mysqli_fetch_array($ress); // Now cursor is at row 3
echo $result["ID"]; // this will print THIRD row's ID.
To echo all IDs
while($result = mysqli_fetch_array($ress)) {
echo $result["ID"];
}
My connection & sql queries have already been tested and they work. I am just trying to print one column of data into my browser for output so I can test the rest of the database. I am just trying to print one row and when I run the code, nothing shows up in the browser as output. The database column name is "type" and there is a "1" in there for the user I am logging in with. The login works but I am trying to read the integer in the database in order to direct it to a specific profile. I can't get anything to printout from my table into the browser.
$role = "SELECT type FROM fp.user WHERE usname ='$username' AND pswd = '$password'";
$access = mysqli_query($link, $role);
$row = mysqli_fetch_row($access);
echo $row['type'];
There may be a problem with your query. You should check to see if $access is first false (Which would indicate a query failure), and echo out the error associated with the query.
$role = "SELECT type FROM fp.user WHERE usname ='$username' AND pswd = '$password'";
$access = mysqli_query($link, $role);
if ( !$access )
{
echo 'There was a problem running this query: ', mysqli_error($link);
exit;
}
$row = mysqli_fetch_row($access);
Also, according to the docs:
Fetches one row of data from the result set and returns it as an enumerated array, where each column is stored in an array offset starting from 0 (zero). Each subsequent call to this function will return the next row within the result set, or NULL if there are no more rows.
Check to make sure the user/password combo in the database is correct. Another issue could be that no user exists for that $username/$password combo.
So, I'm writing an application in PHP and I'm trying to retrieve unique user data based on what they entered. Here is my code:
function hello($username123) {
// Connect to Database //
$host3 = "db";
$username3 = "db";
$password3 = "db";
$db3 = "db";
$con3 = mysqli_connect($host3,$username3,$password3,$db3) or die("Can not connect to Server.");
$student1name;
$query3 = mysqli_query($con3,"SELECT * FROM 'users' WHERE 'username' = '$username123' and '$student1name' = 'student1'");
return "$student1name";
}
So, the user enters there username which they registered earlier on and then I run a query where the username field is equal to the username variable (The input) and that the student1name variable is equal to the student1 field where the username is the same as the one entered. I then return the student1name variable. But when I test this all that returns is "". I can't figure out the problem
You must bind the result in a result array and access it like that, something like this should work:
return $query3["student1name"];
Would probably be more effective.
If you're only selecting ONE variable in your query then you can simply echo $query3.
It would also be more effective if you'd look into prepared statements.
Note that
$student1name
doesn't do anything since you never give it a proper value.
you are not fetching the results of the query, try something like this after your query..
$row = mysqli_fetch_array($query3, MYSQLI_ASSOC);
return $row['studentname'];
i'm assuming the student's name is in a column called studentname in your DB
PHP automatically replaces any variables you use inside a string to the value of that variable. For example, if $student1name = 'foo' then putting $student1name anywhere in your SELECT statement literally outputs you a string 'foo' in place of that variable. As far as the mysqli statement is concerned, you aren't using a PHP value, you are using a literal string 'foo'. Therefore, expecting your $student1name var to magically change based on the sql statement isn't going to happen.
To retrieve a column's value you will need to fetch the result rows after you perform the query:
if ($row = $query3->fetch_assoc()) {
return $row["student1"];
}
If you are expecting more than one result row, then you just need to call fetch_assoc() again for each row until it returns you nothing (marking the end of the result rows).
I'm using Postgresql 9.2 and PHP 5.5 on Linux. I have a database with "patient" records in it, and I'm displaying the records on a web page. That works fine, but now I need to add interactive filters so it will display only certain types of records depending on what filters the user engages, something like having 10 checkboxes from which I build an ad-hoc WHERE clause based off of that information and then rerun the query in realtime. I'm a bit unclear how to do that.
How would one approach this using PHP?
All you need to do is recieve all the data of your user's selected filters with $_POST or $_GET and then make a small function with a loop to concatenate everything the way your query needs it.
Something like this... IN THE CASE you have only ONE field in your DB to match with. It's a simple scenario and with more fields you'll need to make it so that you add the field you really need in each case, nothing too complex.
<?php
//recieve all the filters and save them in array
$keys[] = isset($_POST['filter1'])?'$_POST['filter1']':''; //this sends empty if the filter is not set.
$keys[] = isset($_POST['filter2'])?'$_POST['filter2']':'';
$keys[] = isset($_POST['filter3'])?'$_POST['filter3']':'';
//Go through the array and concatenate the string you need. Of course, you might need AND instead of OR, depending on what your needs are.
foreach ($keys as $id => $value) {
if($id > 0){
$filters.=" OR ";
}
$filters.=" your_field = '".$value."' ";
}
//at this point $filters has a string with all your
//Then make the connection and send the query. Notice how the select concatenates the $filters variable
$host = "localhost";
$user = "user";
$pass = "pass";
$db = "database";
$con = pg_connect("host=$host dbname=$db user=$user password=$pass")
or die ("Could not connect to server\n");
$query = "SELECT * FROM table WHERE ".$filters;
$rs = pg_query($con, $query) or die("Cannot execute query: $query\n");
while ($row = pg_fetch_row($rs)) {
echo "$row[0] $row[1] $row[2]\n";
//or whatever way you want to print it...
}
pg_close($con);
?>
The above code will get variables from a form that sent 3 variables (assuming all of them correspond to the SAME field in your DB, and makes a string to use as your WHERE clause.
If you have more than one field of your db to filter through, all you need to do is be careful on how you match the user input with your fields.
NOTE: I did not add it here for practical reasons... but please, please sanitize user input.. ALWAYS sanitize user input before using user controlled data in your queries.
Good luck.
Don't do string concatenation. Once you have the values just pass them to the constant query string:
$query = "
select a, b
from patient
where
($x is not null and x = $x)
or
('$y' != '' and y = '$y')
";
If the value was not informed by the user pass it as null or empty. In the above query the x = $x condition will be ignored if $x is null and the y = '$y' condition will be ignored if $y is empty.
With that said, a check box will always be either true or false. What is the exact problem you are facing?
Always sanitize the user input or use a driver to do it for you!
I have created a Where clause builder exactly for that purpose. It comes with the Pomm project but you can use it stand alone.
<?php
$where = Pomm\Query\Where::create("birthdate > ?", array($date->format('Y-m-d')))
->andWhere('gender = ?', array('M'));
$where2 = Pomm\Query\Where::createWhereIn('something_id', array(1, 15, 43, 104))
->orWhere($where);
$sql = sprintf("SELECT * FROM my_table WHERE %s", $where2);
$statement = $pdo->prepare($sql);
$statement->bind($where2->getValues());
$results = $statement->execute();
This way, your values are escaped and you can build dynamically your where clause. You will find more information in Pomm's documentation.
I have a PHP server script that SELECTs some data from a MySQL database.
As soon as I have the result from mysql_query and mysql_fetch_assoc stored in my own local variables, I want to delete the row I just selected.
The problem with this approach is that it seems that PHP has done pass-by-reference to my local variables instead of pass-by-value, and my local variables become undefined after the delete command.
Is there anyway to get around this? Here is my code:
$query="SELECT id, peerID, name FROM names WHERE peer = $userID AND docID = '$docID' AND seqNo = $nid";
$result = mysql_query($query);
if (!$result)
self::logError("FAIL:1 getUsersNamesUpdate() query: ".$query."\n");
if (mysql_num_rows($result) == 0)
return array();
$row = mysql_fetch_assoc($result);
$result = array();
$result["id"] = $row["id"];
$result["peerID"] = $row["peerID"];
$result["name"] = $row["name"];
$query="DELETE FROM names WHERE id = $result[id];";
$result = mysql_query($query);
if (!$result)
self::logError("FAIL:2 getUsersNamesUpdate() query: ".$query."\n");
return $result;
You are overwriting your $result variable with your second statement:
$query="DELETE FROM names WHERE id = $result[id];";
$result = mysql_query($query); // result does not contain the array anymore
Change the name to something else. It has nothing to do with call-by-reference or such.
Actually, your first assignment of the values is unnecessary as $row is already an array:
$row = mysql_fetch_assoc($result);
$result = array();
$result["id"] = $row["id"];
$result["peerID"] = $row["peerID"];
$result["name"] = $row["name"];
You could just do:
$row = mysql_fetch_assoc($result);
// at the end
return $row;
Then you don't even have to change your variable name for the second statement. But consider to use meaningful variable names.
First of all, why not just use only one query to delete the row that interests you ?
Something like this should do the trick, I suppose :
delete
from names
where peer = $userID
AND docID = '$docID'
AND seqNo = $nid
Of course, don't forget to escape/convert the values that should be ;-)
This way, no need for a select query, followed by a delete one.
Second : to make your code more easier to read / understand / maintain, you should probably not re-use the same variable for several different purposes.
Here, your $result variable is used for more than one thing, and it makes things harder to understand :
resource returned by the first mysql_query
then, array containing data from the first row
then, resource returned by the second mysql_query
It's a bit confusing, and will, one day or another, lead to errors...
Actually, it already has ;-) : the third assignment is overriding the data you're getting with the second ones, and boom, you've lost the information that corresponds to the row you've just deleted ;-)