having trouble with getting rows back from msqli::multi_query - php

I've got an sql query that contains a number of statements. It:
sets a user variable
calls a stored procedure
calls another stored procedure
selects some data
I know that the query is correct, because I've tested it in MySQL Workbench, under the same user. The query is this:
set #current_post = 535; /* 535 for testing, this will be a variable */
call under_user_type(#currrent_post, #user_type, #user_id);
call get_category(#current_post, #category);
select p.post_title, p.post_name,
(
swell_wp.post_score(p.ID)
) as score,
(
swell_wp.is_under_user(p.ID, #user_type, #user_id)
) as under_user,
(
swell_wp.is_under_category(p.ID, #category)
) as under_category
from wp_posts as p
where p.post_type = 'post'
and p.id != #current_post
and p.post_status = 'publish'
having (
under_user = true
or under_category = true
)
order by score desc;
that's just stored in a string: $sql. I then do this with it in PHP:
$query = new MySQLi(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$query->multi_query($sql);
do {
$query->next_result();
} while( ! $result = $query->use_result() );
print_r($result);
this prints a result object, but one that is empty. Trying to iterate over it doesn't produce any results either.
What am I doing wrong? Can I even use user variables like this? Or will I need to turn the procedures into stored functions and do three separate queries?

Try this:
$query = new MySQLi(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
if ($query->multi_query($sql)) {
do {
if ($result = $query->use_result()) {
while ($row = $result->fetch_row()) {
printf("%s\n", $row[0]);
}
$result->free();
}
} while ($query->next_result());
} else {
echo 'ERROR FOR QUERY!';
}
This should help you trap any errors. Also, I think your use_result needs to be swapped with the next_result.
UPDATED: One other thing, have you checks to make sure the variables you are passing to the query actually contain data? Print our the query to make sure you can run it in the database and get results manually too.

You are apparently not fetching the rows from the result. Please change the code to this and it will print the results.
$query = new MySQLi(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$query->multi_query($sql);
do {
/* store first result set */
if ($result = $query->use_result())
{
while ($row = $result->fetch_row())
{
print_r($row);
}
$result->close();
}
/* print divider */
if ($query->more_results())
{
printf("-----------------\n");
}
} while ($query->next_result());

Related

Flattening a SQL query result for PHP array

I have a SQL table (modules) with two columns (id, name). Now I can retrieve the rows from this through a PHP script but what I want is to use the value of id as the key, and the value of name as the value, in a multidimensional array. Then I want to be able to encode those into a JSON, retaining the relationship between key/value. I've muddled something together but it returns null.
the relevant code from index.php
$mod1 = $core["module1"];
$mod2 = $core["module2"];
$modules = $db->getModulesById($mod1, $mod2); //module names & ids
$response["module"]["mod1"] = $modules[$mod1];
$response["module"]["mod2"] = $modules[$mod2];
$response["module"]["mod1name"] = $modules[$mod1]["name"];
$response["module"]["mod2name"] = $modules[$mod2]["name"];
echo json_encode($response);
The function from DB_Functions.php
public function getModulesById($mod1, $mod2) {
require_once 'include/Config.php';
$con = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD);
// Check connection
if (!$con)
{
die("Connection error: " . mysqli_connect_error());
}
// selecting database
mysqli_select_db($con, DB_DATABASE) or die(mysqli_connect_error());
$query = "SELECT * FROM modules WHERE id= '$mod1' OR id='$mod2'";
$result = mysqli_query($con, $query);
$arr = array();
while($row = mysqli_fetch_assoc($result)) {
// process each row
//each element of $arr now holds an id and name
$arr[] = $row;
}
// return user details
return mysqli_fetch_array($arr);
close();
}
I've looked around but I'm just not 'getting' how the query return is then broken down into key/value for a new array. If someone could ELI5 I'd appreciate it. I'm just concerned with this aspect, it's a personal project so I'm not focusing on security issues as yet, thanks.
You are pretty well there
public function getModulesById($mod1, $mod2) {
require_once 'include/Config.php';
$con = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
// Check connection
if (!$con) {
die("Connection error: " . mysqli_connect_error());
}
$query = "SELECT * FROM modules WHERE id= '$mod1' OR id='$mod2'";
$result = mysqli_query($con, $query);
$arr = array();
while($row = mysqli_fetch_assoc($result)) {
$arr[] = $row;
}
// here is wrong
//return mysqli_fetch_array($arr);
// instead return the array youy created
return $arr;
}
And call it and then just json_encode the returned array
$mod1 = $core["module1"];
$mod2 = $core["module2"];
$modules = $db->getModulesById($mod1, $mod2); //module names & ids
$response['modules'] = $modules;
echo json_encode($response);
You should really be using prepared and paramterised queries to avoid SQL Injection like this
public function getModulesById($mod1, $mod2) {
require_once 'include/Config.php';
$con = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
// Check connection
if (!$con) {
die("Connection error: " . mysqli_connect_error());
}
$sql = "SELECT * FROM modules WHERE id= ? OR id=?";
$stmt = $con->prepare($sql);
$stmt->bind_param('ii', $mod1, $mod2);
$stmt->execute();
$result = $stmt->get_result();
$arr = array();
while($row = mysqli_fetch_assoc($result)) {
$arr[] = $row;
}
// here is wrong
//return mysqli_fetch_array($arr);
// instead return the array youy created
return $arr;
}
mysqli_fetch_array requires the result of a mysqli_query result. Passing the constructed array to mysqli_fetch_array() is not going to work.
If you want to have a specific value from a row to use as its key, you can't resolve this with any mysqli_* function. You could however construct it yourself:
while($row = mysqli_fetch_assoc($result)) {
// process each row
//each element of $arr now holds an id and name
$arr[$row['id']] = $row;
}
mysqli_close($con);
return $arr;
You should close the connection before returning the result, code positioned after a return will not be executed.

Joining a string and array elements not working

Here is my PHP code:
$conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD);
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$statecodes = array(0=>"test1","test2");
while($i<sizeof($statecodes)) {
$ini = "users_";
$var = sprintf("%s%s", $ini, $statecodes[$i]);
print $var;
$query = "CREATE DATABASE IF NOT EXISTS" . $var;
$stmt = $mysqli->prepare($query);
/* Execute the statement */
$stmt->execute();
$i=$i+1;
/* close statement */
$stmt->close();
}
And the output i get is
users_
I want to create databases named user_test1 and user_test2
Try this out. You were missing a space after IF NOT EXISTS and your loop was broken due to not initializing your counter. PHP provides a lot of convenient methods for doing things like array traversal and string concatenation; looking at your code I'd guess your experience is with a much lower level language? Things like printf() come in handy for some tasks, but it's overkill when you just want to jam two strings together!
Finally, no need to prepare and execute a query if it isn't a prepared statement with placeholders. You will, however, want to sanitize your input and check the result of your query for errors.
<?php
$conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD);
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$statecodes = array("test1","test2");
foreach ($statecodes as $state) {
$var = "users_$state";
// remove dangerous characters!
$var = preg_replace("/[^\w]/", "", $var);
$query = "CREATE DATABASE IF NOT EXISTS $var";
$result = $conn->query($query);
if (!$result) {
//do something!
}
}

Ranking system using mysqli

I want to check if the user what rank a user has, which is stored in my database as an integer of 0, 1, 2, or 3.
I want it to be echo'd like echo $my_rank; #Instead of it saying 0,1,2,or 3 it says User for 0, Moderator for 1, Admin for 2, and Owner for 3.
Here is my code:
$my_rank = $_SESSION['rank'] = array("owner","administrator","moderator","user");
$rank = array (
'0' => 'user',
'1' => 'moderator',
'2' => 'administrator',
'3' => 'owner'
);
config.php
<?php
# Error Reporting
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
# No Error Reporting
//error_reporting(0);
# Message Responses
$success = array();
$danger = array();
$warning = array();
$info = array();
# Define the Database
define('DB_SERVER','localhost');
define('DB_USERNAME','blah');
define('DB_PASSWORD','blah');
define('DB_DATABASE','blah');
# Connect to the database
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
if (!$con) {
$danger[] = mysqli_connect_error();
} else {
//echo "It worked";
}
?>
Well... Going by the information you've given me, it seems like all that is needed is a query, to get the data from the database. Then we can echo it.
In the else block in your database connection, we can do something like:
# Connect to the database
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
if (!$con) {
$danger[] = mysqli_connect_error();
} else {
//echo "It worked";
// HopefulLlama code below:
// Construct our SQL query, which will retrieve data from the database.
$sql="SELECT * FROM Users";
$result=mysqli_query($con,$sql);
// Loop through all results return by our query
while ($row = mysqli_fetch_assoc($result)) {
// $row['rank'] will contain our Integer of 0, 1, 2, or 3
echo $row['rank']
// This will access your $rank array, and use the index retrieved from the database as an accessor.
echo $rank[$row['rank']]
}
}
One can query the database with sql statements. The one you're looking for is a select upon the usertable:
// array which holds the info
$rank = array ('user', 'moderator', 'administrator', 'owner');
// set up db connection
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
if (!$con) {
$danger[] = mysqli_connect_error();
} else {
//echo "It worked";
// Baklap4's Addition:
// SQL statement to retrieve the row where username is piet
$sql = "SELECT * FROM Users WHERE username = `piet`";
// Execute the query and check if there is a result.
if ($result = $con->query($sql)) {
// if there are results loop through them.
while ($row = mysqli_fetch_assoc($result)) {
// print for each rank a different rank name.
echo $rank[$row['rank']];
}
// free resultset
$result->close();
}
// close connection
$con->close();
//clean up the temp variables
unset($obj);
unset($sql);
unset($result);
}
This will retrieve The user Piet from your database and print the rank (which is listed in the database).
Then it'll unset all the temporary values made within the whileloop so you can't reuse them again.
What you should do is change the hard coded value piet to a variable. One could go to http://localhost/scriptname.php?username=piet to retrieve the same outcome.
To make this a variable change the sql line as following:
$sql = "SELECT * FROM Users WHERE username = $_GET['username']";

MySQLi prepared query failing after first query

I have one function selecting a load of information from one table. This then launches another function to get some info from another table.
Here's the shortened code:
$con = new mysqli("localhost", "user", "password");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$con->select_db("stories_test");
getStories($con);
function getStories($con) {
... //get's a load of data from one table
$result = getStoryName($con, $stringstoryid);
... //More stuff here
}
function getStoryName($con) {
$newquery = "SELECT storyname, genre FROM stories WHERE storyid = 'Anewstory9856'";
if ($stmt = $con->prepare($newquery)) {
echo $newquery;
$stmt->execute();
$stmt->bind_result($storname, $genre);
while ($stmt->fetch()) {
$resultarray = array (
'storname' => $storname,
'genre' => $genre
);
}
}
else {
echo 'statement failed';
}
return $resultarray;
}
All I ever get is 'statement failed' from the second query.
I have tried the exact same query in a separate script on its own and it works fine, but here it seems to fail at 'prepare'.
Does anyone have any clues?

$mysqli->fetch_object($result) not working

I am learning mysqli.
I am trying to fetch data from a table "tbllogin".
//DATABASE CONNECTION
$hostname="p:localhost";
$database="dbLogin";
$username="user1";
$password="pwd1";
$mysqli = new mysqli($hostname, $username, $password,$database);
if(mysqli_connect_errno()){
echo mysqli_connect_error();
}
// Create Query
$query = "SELECT * FROM tbllogin";
// Escape Query
$query = $mysqli->real_escape_string($query);
echo $query;
// Execute Query
if($result = $mysqli->query($query)){
print_r($result);
while($row = $mysqli->fetch_object($result)){
echo $row->column;
}
//Free result set
$result->close();
}
?>
But $mysqli->fetch_object($result) is not working. The if statement containing $mysqli->fetch_object($result) does not execute. I cannot identify if there is any error.
Please help.
Also, suggest whether mysqli procedural form is better or object-oriented form?
Thanks in advance.
Shouldn't that be $result->fetch_object() ?
http://php.net/manual/en/mysqli-result.fetch-object.php
From Example 1:
if ($result = $mysqli->query($query)) {
/* fetch object array */
while ($obj = $result->fetch_object()) {
printf ("%s (%s)\n", $obj->Name, $obj->CountryCode);
}
According to the answers on this stackoverflow page, there is not much of a difference between the two.
Try this:
if($result = $mysqli->query($query)){
print_r($result);
while($row = $result->fetch_object($result)){
//do something
}
}
You need to chain the commands together.

Categories