I know this particular query works, as I tested it with unprepared, procedural methods. Here it is:
$name = 'introduction';
$mysqli = new mysqli('localhost', 'user', 'pass', 'db') or die('There was a problem connecting to the database.');
$stmt = $mysqli->prepare("SELECT name, content FROM sections WHERE name = ?");
$stmt->bind_param('s', $name);
$stmt->execute();
$stmt->bind_result($content);
$stmt->fetch();
echo $content;
$stmt->close();
I realized that, since I have an id column as an index in the sections table, I needed to bind that as a result as well, given the above statement at php.net, (thanks again, Bill).
Here's the new code:
$name = 'introduction';
$mysqli = new mysqli('localhost', 'user', 'pass', 'db') or die('There was a problem connecting to the database.');
$stmt = $mysqli->prepare("SELECT name, content FROM sections WHERE name = ?");
$stmt->bind_param('s', $name);
$stmt->execute();
$stmt->bind_result($id, $name, $content);
$stmt->fetch();
echo $content;
$stmt->close();
Thanks again to all who can offer suggestions. (I'm curious: I find it hard to debug when using the OOP style of prepared statements in this way. Is there, for example, an easy way to simply see the query that was actually used?)
If I do the following, just as a quick-and-dirty example:
$name = 'introduction';
#mysql_connect('host', 'user', 'pass');
#mysql_select_db('db');
$query = "SELECT name,content FROM sections WHERE name = '$name'";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_object($result)) {
$content = $row->content;
echo $content;
}
My data appears and all is well. If, however, I do the following:
$name = 'introduction';
$mysqli = new mysqli('localhost', 'user', 'pass', 'db') or die('There was a problem connecting to the database.');
$stmt = $mysqli->prepare("SELECT name, content FROM sections WHERE name = ?");
$stmt->bind_param('s', $name);
$stmt->execute();
$stmt->bind_result($name, $content);
$stmt->fetch();
echo $content;
$stmt->close();
Which I believe is correct (feel free to yell if not, of course), I get nothing. What's more, with that code, when I do an html validation (just in case), I get an internal server warning (500), which I take to be a problem with the sql code. Am I just nuts?
I don't see anything wrong with your preparation of the statement or use of parameters, but there is something wrong in your binding results:
http://php.net/manual/en/mysqli-stmt.bind-result.php says:
Note that all columns must be bound
after mysqli_stmt_execute() and prior
to calling mysqli_stmt_fetch().
(emphasis mine)
The above doc should be taken as all columns in your query, not all columns in your table.
Okay, I just tried this myself. If I omit the $name column, it gives this warning:
PHP Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't
match number of fields in prepared statement in mysqli.php on line 9
PHP Stack trace:
PHP 1. {main}() /Users/bill/workspace/PHP/mysqli.php:0
PHP 2. mysqli_stmt->bind_result() /Users/bill/workspace/PHP/mysqli.php:9
But it does fetch the data.
If I bind both $name and $content to the results of the query, it works without error or warning.
So I'm forced to ask you: are you sure there's a row in the database that matches your condition? That is, where name = 'introduction'? Keep in mind that in SQL, string comparisons are case-sensitive by default.
One mistake I see people make frequently is that they connect to a different database in their PHP script than the database they use for ad hoc queries. So you need to be absolutely sure you're verifying that the data exists in the right database.
Shouldn't that be
$stmt->bind_result($name, $content);
As you select 2 columns
Related
Can someone help to figure out why this query will not work on retrieving a certain record from my database?
$db = new mysqli(DB_HOSTNAME,DB_USERNAME,DB_PASSWORD,DB_DATABASE);
$query1 = $db->query("SELECT * FROM `customer` WHERE `wmmw_domain` = '" . array_shift((explode(".",$_SERVER['HTTP_HOST']))) . "'");
while($r = $query1->fetch_array()){
$aff_id = $r['wmmw_id'];
}
echo $aff_id;
This is the link for the test script:
http://evecournoyer.wm-mw.org/testindex.php
If I change one letter, or add a letter, to the database record
(such as evecournoyer1, or vecournoyer), it works.
Is there something in the name, evecournoyer, that prevents the
query from running? It's weird....
Here is one that works:
http://brucetherrien.wm-mw.org/testindex.php
Note: I can retrieve the record using Perl from a command shell, if it matters.
Try using prepare() and binding params and result.
Hopefully something like this:
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');
$stmt = mysqli_prepare($link, 'select name, id from mytable where myfield=?');
mysqli_stmt_bind_param($stmt, 's', $myValue);
$myValue = getSessionHttpHost();
/* bind result variables must match */
$stmt->bind_result($name, $id);
/* fetch values */
while ($stmt->fetch()) {
printf ("%s (%s)\n", $name, $id);
}
/* close statement and connection */
mysqli_stmt_close($stmt);
......
I would check the data type, encoding and length for the offending field.
I presume you get results for other domains and so your http_host statement is working.
The adding or removing a char from the sub domain makes it work doesn't make sense. If the data type length was being exceeded and the stored value was truncated then I would expect it to fail the select condition but you are adding to it and it works.
I can't see anything in the sub domain that should fail. As suggested above viewing the query string might show up an anomaly in the where condition. Does the query fail if you run it manually through command prompt or client using the result of your http_host code for that domain?
I am trying to make a basic hit counter that I can use on all of my websites.
I have a prepared statement querying both my Go Daddy MySQL server as well as my MAMP MySQL server, and the the statement won't 'Prepare'. Here it is:
function hit_counter($url){
if($mysqli = new mysqli('localhost', 'root', '', 'DB')){
$crack = "SELECT hc-id, hc-url, hc-unique_hits, hc-total_hits, hc-last_viewed FROM hit_counter WHERE hc-url =?";
if($stmt = $mysqli->prepare(crack)){
$stmt->bind_param('s', $url);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id, $url, $unique_hits, $total_hits, $last_viewed);
$stmt->fetch();
echo "the statement was prepared successfully";
$total_hits = $total_hits+1;
$last_viewed = date('l jS \of F Y h:i:s A');
echo $unique_hits;
if($unique === true){
$unique_hits = $unique_hits+1;
}
$update = 'UPDATE hit_counter set hc-unique_hits=? hc-total_hits=? hc-last_viewed=? WHERE hc-url=?';
if($stmt= $mysqli->prepare($update)){
$stmt->bind_param('iiss', $unique_hits, $total_hits, $last_viewed, $url);
$stmt->execute();
}else{echo "the update statement wasn't prepared.";}
}else{echo "The statement wasn't prepared.";}
}else{echo "the SQL connection wasn't made";}
}
I know that it is connecting to the database, but whenever I run the script, it echos the else statement for if($stmt = $mysqli->prepare(crack)){ "The Statement wasn't prepared".
Your columns contain hyphens which MySQL is interpreting it as hc MINUS unique_hits etc. thinking you want to do a mathematical problem.
You also have missing commas in your SETs
UPDATE hit_counter set `hc-unique_hits`=?, `hc-total_hits`=?, `hc-last_viewed`=? WHERE `hc-url`=?
It's best to stay away from using hyphens for column names. Use underscores instead.
Using
if(!$stmt->execute()){trigger_error("there was an error....".$mysqli->error, E_USER_WARNING);}
would have spotted that error.
Same thing for
$crack = "SELECT hc-id, hc-url, hc-unique_hits, hc-total_hits, hc-last_viewed FROM hit_counter WHERE hc-url =?";
use backticks around those containing hyphens.
$crack = "SELECT `hc-id`, `hc-url`, `hc-unique_hits`, `hc-total_hits`, `hc-last_viewed`
FROM hit_counter WHERE `hc-url` =?";
For more information on Identifier Qualifiers, consult:
http://dev.mysql.com/doc/refman/5.0/en/identifier-qualifiers.html
Also
if($stmt = $mysqli->prepare(crack)){
should be
if($stmt = $mysqli->prepare($crack)){
where you missed the $ for crack. Otherwise it's treated as a constant.
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Error reporting should only be done in staging, and never production.
Another developing tool that is at your disposal is var_dump().
Use var_dump($variable_to_check); to see what is passing through or not.
see the value if($stmt = $mysqli->prepare(crack)){ should be
$crack , spot the $ !!
im trying to use mysqli with bind_result but all i get is null values. My $stmt
number of rows is greater than 0 so i do have some data in it.
I dont realy understand what value should come into bind_result
I have read at the manual http://php.net/manual/en/mysqli-stmt.bind-result.php
And they dont explain what should i put in the bind_result.
Should i put there the column names? if yes, as strings? how do i get my wanted values?
Here is my code thanks for helping:
$sql = "SELECT * FROM comments WHERE workout_name = ? AND user = ?";
$stmt = $mysqli->prepare($sql) or trigger_error($mysqli->error."[$sql]");
$stmt->bind_param('ss', $workout_name, $user);
$workout_name = "rytg";
$user = "tomer";
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($comment, $commented_user);
if($stmt->num_rows > 0)
{
$response["workouts"] = array();
while ($stmt->fetch())
{
// temp user array
$workouts = array();
$workouts["comment"] = $comment;
$workouts["user"] = $commented_user;
// push single product into final response array
array_push($response["workouts"], $workouts);
}
}
Your only problem is insufficient error reporting
error_reporting(E_ALL);
ini_set('display_errors',1);
Just add these lines at the top of your code and you will be immediately informed of the exact problem with your code.
Note that on the production server you have to turn displaying errors off and logging on
I don't have a working PHP installation next to me at the moment, so I can't verify it, but I believe you might have to bind both parameters and result before you execute the query, like so:
$workout_name = "rytg";
$user = "tomer";
$stmt = $mysqli->prepare($sql) or trigger_error($mysqli->error."[$sql]");
$stmt->bind_param('ss', $workout_name, $user);
$stmt->bind_result($comment, $commented_user);
$stmt->execute();
I'm not too sure about store_result() either. I don't recall having to use it while retrieving the results, so you might want to try running your code without it and see what happens.
I'm getting the following error message in my PHP script;
mysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement
But here is the relevant code:
$con = mysqli_connect( $db_url, $db_user, $db_pwd, $db );
$sql = "SELECT * FROM problems WHERE mrn=?";
$stmt = mysqli_prepare( $con, $sql );
mysqli_stmt_bind_param( $stmt, 'i', $sent_mrn );
It points me to the last line there. Am I missing something really obvious? There is only one parameter in the SQL query and I'm binding only one variable! (I know some people will suggest I use PDO, but I gotta use mysqli at the moment)
When using procedural functions (as opposed to object-oriented), you must first call mysqli_stmt_init() to get the statement object. Then you call mysqli_prepare with this statement as the first parameter, NOT the connection as you are currently doing. Also you don't need the return value of mysqli_prepare unless you're meticulously checking for error conditions. Its return value is NOT passed to mysqli_stmt_bind_param, but rather the statement returned from mysqli_stmt_init().
$con = mysqli_connect( $db_url, $db_user, $db_pwd, $db );
$sql = "SELECT * FROM problems WHERE mrn=?";
$stmt = mysqli_prepare($con, $sql);
$stmt -> bind_param('i', $sent_mrn);
Give this a try.
I have a little login script.
function login($sql) {
try {
$fbhost = "localhost";
$fbname = "foodbank";
$fbusername = "root";
$fbpassword = "";
$DBH = new PDO("mysql:host=$fbhost;dbname=$fbname",$fbusername,$fbpassword);
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$STH = $DBH->query($sql);
$STH->setFetchMode(PDO::FETCH_ASSOC);
session_start();
if ($row = $STH->fetch()) {
$_SESSION['username'] = "$row[username]";
header("Location:index.php");
}
} catch(PDOException $e) {
echo $e->getMessage();
}
}
EDITS:
index.php
$sql = "SELECT username from users where username = ". $_POST['username'] ." AND password = ". $_POST['password'] ."";
login($sql);
Changed above from insert to select query. Now I get new error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'pvtpyro' in 'where clause'
Based on your latest edit: You can't fetch results with PDO after executing an INSERT query. See here: http://www.php.net/manual/en/pdostatement.fetch.php#105682
Edit: I suppose, since the function's called "login", you want to have something like this as $sql: "SELECT password FROM users WHERE username = :username", and then iterate over the results with the while loop, and then log in the user if the password matches?
Edit2: Based on your edit to provide a SELECT query: DO NOT USE THIS QUERY. What you are doing is NOT SQL injection proof. Never ever use variables from user input (i.e. $_POST, $_GET et al) and put them unfiltered into an SQL query. Please look up the term "prepared statements" here at SO or Google.
As you can see, since you forgot to put single ticks (apostrophes) before and after the double quotes, MySQL thinks that your input refers to another column ("pvtpyro") instead of comparing the value in the column against a string. ALWAYS use the ":username", ":password" syntax (the one with prepended colons) or your queries will be unsafe and enormously dangerous to your application.
The constructor of PDO uses 2 variables which are not defined in the code you supplied - $fbhost and $fbname.
EDIT:
You're calling session_start() inside the while loop, which can cause errors. Take it out of the loop.
EDIT 2:
You should really debug the code. Either via putting die in different parts of the code, outputting some helpful information just before (which is the less preferred way) OR by using xdebug and an IDE, which will allow you to run line by line, and see the exact state of each variable and such.
If I undestand correctly, $data $STH->execute($data); should be an array, even if value is one. So, you may try replacing that query with $STH->execute(array($data));
edited:
Change your lines to this:
$data = array($_POST["username"], $_POST["password"]);
$sql = "INSERT INTO users (username, password) value (?, ?)";
$STH = $DBH->prepare($sql);
$STH->execute($data);
Seems to me that you're not connected to your database properly... I had this error earlier today and it was for that reason. Either that or you have an incorrect string