having problems to execute a PHP code with simple mySQL query - php

I am trying to execute a query with a WHERE clause but it looks like the id I retrieve needs to be perhaps converted from an array into something else. I am new to PHP so I am struggling a little:
...some previous query here
$sharepoint_id = $data[0];
//returns Array([ID] => a5f415a7-3d4f-11e5-b52f-b82a72d52c35)
qry = mysql_query("SELECT HostName FROM MSSWireList WHERE id=".$sharepoint_id);
$data = array();
while($rows = mysql_fetch_array($qry))
{
$data[] = array(
"ID" => $rows['ID'],
"Record" => $rows['Record'],
"HostName" => $rows['HostName']
);
}
return json_encode($data);
also tried $sharepoint_id = $data[0]->ID;
Thank you

"returns Array([ID] => a5f415a7-3d4f-11e5-b52f-b82a72d52c35)"
That's a string and not an integer. The variable in your WHERE clause needs to be quoted.
WHERE id='".$sharepoint_id."' ");
Checking for errors would have signaled the syntax error.
Add or die(mysql_error()) to mysql_query().
Ref: http://php.net/manual/en/function.mysql-error.php
Your present code is open to SQL injection. Use mysqli_* with prepared statements, or PDO with prepared statements.
Edit:
You only selected the HostName column from your query and not the other two, ID and Record.
However, when going over a loop, row names are case-sensitive.
So, if your row's case is id as opposed to ID, then that will matter in your loop.
$rows['ID'] and $rows['id'] are two different animals.
Sidenote:
Pulled from a comment I asked already:
qry = mysql_query if that your real code, it's missing a $ for qry.
And if so, error reporting would have thrown you an undefined constant qry notice.
http://php.net/manual/en/function.error-reporting.php

I won't take you to task for using the old mysql driver instead of mysqli or PDO, or for not using a prepared statement - I'll leave that for others to do - but
"...WHERE id = '" . $sharepoint_id['ID'] . "'"
should do the job.

Related

PDO fetch multiple records from database

I am writing a pretty basic piece of code to fetch one or (in most cases) multiple rows from a mysql database.
function getschema($mysqli){
$id = $_SESSION['user_id'];
$query = $mysqli->prepare("SELECT a.naam
FROM schemes AS a, aankoop AS b
WHERE b.aankoop_username_id = :userid && b.aankoop_schema_id = a.id");
$query->bind_param(':userid', $id, PDO::PARAM_INT);
$query->execute();
$result = $query->fetchAll();
echo ($result);
}
I get the user id from the session and pull the data with the query in the prepared statement.
This statement is correct. I tried it in phpmyadmin and it returns the correct values.
Now I want to use this function in my HTML like so...
<?php echo getschema($mysqli); ?>
But my code does not return a thing, it even messes up the layout of my html page where I want to show the code.
I think it probably is something with the fetchAll command. I also tried the PDO::Fetch_ASSOC but that did not work either.
In addition, I cannot see the php errors, even when they are enabled in the php.ini file.
Here's what's going on; you're mixing MySQL APIs/functions and those do not intermix.
Replace the :userid (PDO) bind in b.aankoop_username_id = :userid with a ? placeholder
b.aankoop_username_id = ?
Then this line:
$query->bind_param(':userid', $id, PDO::PARAM_INT);
Replace :userid by $id and remove , PDO::PARAM_INT but adding i
$query->bind_param("i", $id);
Sidenote: Make sure that column is int type. If not, use s instead of i.
Replace the line for fetchAll with the loop as outlined in AbraCadaver's answer.
You can't mix MySQL APIs/function, read the following on Stack:
Can I mix MySQL APIs in PHP?
Read up on mysqli with prepared statements and how it works:
http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
Checking for errors would have outlined the errors.
http://php.net/manual/en/mysqli.error.php
http://php.net/manual/en/function.error-reporting.php
Instead of echo ($result); do return $result; in your function.
Then to use it you have to loop over the array of rows and echo the column that you want:
foreach(getschema($mysqli) as $row) {
echo $row['naam'];
}
Or assign the function return to a variable and loop over that:
$rows = getschema($mysqli);

How to use a quoted string variable in a MySqli prepared statement?

Sorry if this seems a really stupid question, but I'm struggling to get to grips with changing from Mysql to Mysqli and prepared statements.
So in mysql, I would have done this:
$q=('SELECT * FROM table WHERE field="'.$variable.'"');
$result = mysql_query($q);
I now know this is not good. So I now have the below:
$stmt = $mysqli->prepare('SELECT * FROM table WHERE field=? LIMIT 1');
$stmt->bind_param('s', $variable);
$stmt->execute();
Problem is that the query doesn't work. Say the ? is actually "tree". So the query becomes:
'SELECT * FROM table WHERE field=tree LIMIT 1'
If I tried to run that query in say phpmyadmin I get "Unknown column tree in where clause". Obviously if I put quotes around it then it works, hence the original query. So how can I get this to work if I can't use quotes, since then you are looking for the literal question mark?
For reference I am then using this code:
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$parameters[] = &$row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while ($stmt->fetch()) {
foreach($row as $key => $val) {
$x[$key] = $val;
}
$results[] = $x;
}
As I can't use get_result() which is very annoying. I have PHP version 5.4, and even the mysqlnd driver, but can't enable it as I'm on a VPS and my host says it might affect other sites on that server. Consequently what is actually just two lines in MySql is actually now something like 15 lines in the 'improved' mysqli. Great.
Any help would be appreciated!
This:
$stmt = $mysqli->prepare('SELECT * FROM table WHERE field=? LIMIT 1');
$stmt->bind_param('s', $variable);
is not equivalent to this:
SELECT * FROM table WHERE field=tree LIMIT 1
Prepared statement placeholders are not the same as copy and pasting in values. You are binding the value "tree" as a string here, the database will actually understand this. The ? is not simply being replaced by the bound value, the database understands the difference between your query structure with its placeholders and the values you're binding into them. Binding the parameter this way is equivalent to running:
SELECT * FROM table WHERE field='tree' LIMIT 1
Consequently what is actually just two lines in MySql is actually now something like 15 lines in the 'improved' mysqli. Great.
Mysqli is not intended to be used as is. It is but a building material for the higher level library. When used wisely, it can give you data in one line:
$data = $db->getAll('SELECT * FROM table WHERE field=?s', $variable);
(BTW, the same goes for the old mysql ext as well)

Calling prepare with mysqli won't fetch data

$data = $mysqli->prepare("SELECT amount FROM items WHERE id=:id");
echo 'forward1';
if(!$data->execute(array(':id' => $id)))
die("error executing".$data->error);
echo '2';
$row = $data->fetch_object();
die('Losing my mind'.$row->amount);
This will only echo "forward1", not "error executing..." or "2". It works with *$mysqli->query". If I add quotes '' to :id in the query, it will echo "forward1error executing".
First, make sure you understand the prepared statements syntax and working model.
As in:
$data = $mysqli->prepare("SELECT amount FROM items WHERE id=(?)");
// THIS ^^ actually "prepares" an object to be used in the statement
$data->bind_param("i",$id)
// ...then you "bind" the parameter for your statement as "i"(nteger)
echo 'forward1';
if(!$data->execute()) // And now you simply run it, with no other args
die("error executing".$data->error);
echo '2';
$row = $data->fetch_object();
die('Loosing my mind'.$row->amount);
I suggest though using something more like
$data->execute() or die("error executing".$data->error);
The main steps of a prepared statement are:
1. Prepare the query with some placeholder values;
2. "Bind" the required number of values to the query;
3. Execute it!
I fail to see why this is relevant in your case, with such a simple query. I also assume you actually need it for something bigger.
Please let me know if I misunderstood your point or code sample.
Oh, and.. have fun! :-)
Turn on your error reporting.
You get a fatal error by accessing the method execute on your mysqli::statement after prepare failed. Check if $data === false before calling execute.
Error message: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':id' at line 1
See this answer to why this error is triggered: MYSQLI::prepare() , error when used placeholder :something
See the PHP manual on how to use mysqli, or use PDO instead.

PDO mySql query not executing in for loop the second time up while calling

I have an issue, I'm looping threw a set of values and then creating a PDO mySql query with every loop, now the problem is the first query is executing and returning results, but the second upwards aren't returning results. If I manually execute the queries on the server they return results. This is weird, maybe I'm doing something wrong here. My code below
if($num_results > 0){
for($i=0;$i<$num_results;$i++){
$sql_sub = "SELECT * FROM menu_config WHERE client_id =".$client_id ." AND id =".$data[$i]['root_menu_id'];
$results_s = $pdo->query($sql_sub);
$data_s = $results_s->fetchAll(PDO::FETCH_ASSOC);
$sub_menu_title = "<strong>".$data[$i]['title']."</strong>";
if(empty($data_s[0]['title'])){
$main_menu_title = '<span style="color:#FF0000;font-weight:bold;">No Main Menu Assigned to Sub Menu</span>';
}else{
$main_menu_title = $data_s[0]['title'];
}
$men_title = $data[$i]['title']
}
}
(this may be a little more than you asked for)
You seem to be missing out on some good things that prepared statements do.
First off, you don't usually want to pass the values directly into the query. (sometime's it's necessary, but not here). By doing that, you take out all the good stuff that protects from sql injection. Instead you want to send them as parameters after you've prepared the query.
Secondly, when in a loop, you can save yourself time and resources if you're running the same query over and over by preparing the statement, and then only changing the values you send to to that prepared statement using the PDOStatement::bindParam() function.
Thirdly, fetchAll() does not take a 'fetch_style' of PDO::FETCH_ASSOC. fetch() does. But I think you can get by with the default or none using fetchAll. You'll have to check into that and see what you need. Here are the fetchAll docs
$sql_sub = "SELECT * FROM menu_config WHERE client_id = :client_id AND id = :id ";
$query = $pdo->prepare($sql_sub);
for($i=0;$i<$num_results;$i++){
$query->bindParam(':client_id', $client_id);
$query->bindParam(':id', $data[$i]['root_menu_id']);
$query->execute();
$data_s = $query->fetchAll();
$sub_menu_title = "<strong>".$data[$i]['title']."</strong>";
if(empty($data_s[0]['title'])){
$main_menu_title = '<span style="color:#FF0000;font-weight:bold;">
No Main Menu Assigned to Sub Menu</span>';
}else{
$main_menu_title = $data_s[0]['title'];
}
$men_title = $data[$i]['title'];
}

Why doesn't this prepare statement work in MYSQLI?

I created this code:
$statement = $db->prepare("SELECT * FROM phptech_contact");
$statement->execute();
$result = $statement->result_metadata();
$object = $result->fetch_object();
print_r( $object );
When I run it, it doesn't work. Can anybody tell me why it doesn't work?
I have 20 rows in this table so data should be returned.
From http://ch.php.net/manual/en/mysqli-stmt.result-metadata.php
Note: The result set returned by mysqli_stmt_result_metadata() contains only metadata. It does not contain any row results. The rows are obtained by using the statement handle with mysqli_stmt_fetch().
As long as you don't need this meta data you don't need to call this method.
$statement = $db->prepare("SELECT fld1, fld2 FROM phptech_contact");
$statement->execute();
$stmt->bind_result($fld1, $fld2);
while ($stmt->fetch()) {
echo "$fld1 and $fld2<br />";
}
But I really dislike the mysqli extension. PDO is much cooler ... ;-)
$db = new PDO('...');
$stmt = $db->prepare("SELECT fld1, fld2 FROM phptech_contact");
$stmt->execute();
while ($obj = $stmt->fetchObject()) {
// ...
}
or
$objs = stmt->fetchAll(PDO::FETCH_OBJ);
if you're trying to get the rows from the database, the function you need is mysqli_stmt::fetch(), not mysqli_stmt::fetch_metadata()
You're also missing a few steps. When using prepared statements, you must specify the fields you would like to return instead of using the star wildcard, and then use mysqli_stmt::bind_result() to specify which variables the database fields should be placed in.
If you're more familiar with the original MySQL extension, prepared statements have a different process to use. If your select statement has a parameter (eg., "WHERE value=?") prepared statements are definitely recommended, but for your simple query, mysqli:query() would be sufficient, and not very different from the process of mysql_query()
I believe the problem is that mysqli_stmt::result_metadata() returns a mysqli_result object without any of the actual results — it only holds metadata.
So what you want to do is use $result = $statement->bind_result(...) and then call $result->fetch() repeatedly to get the results.
One of the comments under the bind-result() article shows how to do this for a query like yours, where you don't necessarily know all of the columns being returned.

Categories