When I try to use the fetch_assoc or fetch_array(MYSQLI_ASSOC), the program just crashes and doesn't display any error information(I do have changed error_reporting to E_ALL).But it works fine when using fetch_array(MYSQLI_NUM) or fetch_row().
The weird thing is I can run my program on Wamp. But I cannot on the Apache+PHP+MYSQL environment installed manually.
so is this a PHP configuration problem or a MYSQL problem ?
$studentId = $this->mydblink->real_escape_string($studentId);
$result = $this->mydblink->query("SELECT * FROM student WHERE id = '$studentId'");
if($result->num_rows <= 0){
$result->free();
return null;
}
else{
$returnValue = array();
while($row = $result->fetch_assoc()){
array_push($returnValue,$row);
}
$result->free();
return $returnValue;
}
fetch_array() makes associative array in which there is a key and value.
fetch_assoc() only has value
You can also use fetch_object () that creates objects of your table name.
| id | category | name |
----------------------------------
| 1 | 2, 5, 7, 28 | Will |
----------------------------------
| 2 | 2, 9, 15, 18 | Drew |
EXAMPLES:
$sql=mysqli_query($connect, "SELECT id, category, name FROM users");
$data=mysqli_fetch_array($sql);
// 0=>id, 1=>category, 2=>name
$data[1]; // is same like $data['category'];
$data['category'];
$data=mysqli_fetch_assoc($sql);
$data['name'];
$data=mysqli_fetch_object($sql);
$data->name;
$data->category;
$data->id;
Related
I am a newbie to PHP and I am stuck at a certain point. I tried looking up a solution for it however, I didn't find exactly what I need.
My goal is to create a leaderboard, in which the values are displayed in descending order plus the rank and score are displayed. Furthermore, it should also display whether or not a tie is present.
The database should look like this:
+---------+------+----------------+-------+------+
| user_id | name | email | score | tied |
+---------+------+----------------+-------+------+
| 1 | SB | sb#gmail.com | 1 | 0 |
+---------+------+----------------+-------+------+
| 2 | AS | as#web.de | 2 | 0 |
+---------+------+----------------+-------+------+
| 3 | BR | br#yahoo.com | 5 | 1 |
+---------+------+----------------+-------+------+
| 4 | PJ | pj#gmail.com | 5 | 1 |
+---------+------+----------------+-------+------+
And the outputted table should look something like this:
+------+-------------+-------+------+
| rank | participant | score | tied |
+------+-------------+-------+------+
| 1 | BR | 5 | Yes |
+------+-------------+-------+------+
| 2 | PJ | 5 | Yes |
+------+-------------+-------+------+
| 3 | AS | 2 | No |
+------+-------------+-------+------+
| 4 | SB | 1 | No |
+------+-------------+-------+------+
I managed to display the rank, participant and the score in the right order. However, I can't bring the tied column to work in the way I want it to. It should change the value, whenever two rows (don't) have the same value.
The table is constructed by creating the <table> and the <thead> in usual html but the <tbody> is created by requiring a php file that creates the table content dynamically.
As one can see in the createTable code I tried to solve this problem by comparing the current row to the previous one. However, this approach only ended in me getting a syntax error. My thought on that would be that I cannot use a php variable in a SQL Query, moreover my knowledge doesn't exceed far enough to fix the problem myself. I didn't find a solution for that by researching as well.
My other concern with that approach would be that it doesn't check all values against all values. It only checks one to the previous one, so it doesn't compare the first one with the third one for example.
My question would be how I could accomplish the task with my approach or, if my approach was completely wrong, how I could come to a solution on another route.
index.php
<table class="table table-hover" id="test">
<thead>
<tr>
<th>Rank</th>
<th>Participant</th>
<th>Score</th>
<th>Tied</th>
</tr>
</thead>
<tbody>
<?php
require("./php/createTable.php");
?>
</tbody>
</table>
createTable.php
<?php
// Connection
$conn = new mysqli('localhost', 'root', '', 'ax');
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// SQL Query
$sql = "SELECT * FROM names ORDER BY score DESC";
$result = $conn->query("$sql");
// Initalizing of variables
$count = 1;
$previous = '';
while($row = mysqli_fetch_array($result)) {
$current = $row['score'];
$index = $result['user_id']
if ($current == $previous) {
$update = "UPDATE names SET tied=0 WHERE user_id=$index";
$conn->query($update);
}
$previous = $current;
?>
<tr>
<td>
<?php
echo $count;
$count++;
?>
</td>
<td><?php echo $row['name'];?></td>
<td><?php echo $row['score'];?></td>
<td>
<?php
if ($row['tied'] == 0) {
echo 'No';
} else{
echo 'Yes';
}
?>
</td>
</tr>
<?php
}
?>
I think the problem is here
$index = $result['user_id'];
it should be
$index = $row['user_id'];
after updating tied you should retrieve it again from database
So I solved my question by myself, by coming up with a different approach.
First of all I deleted this part:
$current = $row['score'];
$index = $result['user_id']
if ($current == $previous) {
$update = "UPDATE names SET tied=0 WHERE user_id=$index";
$conn->query($update);
}
$previous = $current;
and the previous variable.
My new approach saves the whole table in a new array, gets the duplicate values with the array_count_values() method, proceeds to get the keys with the array_keys() method and updates the database via a SQL Query.
This is the code for the changed part:
// SQL Query
$sql = "SELECT * FROM names ORDER BY score DESC";
$result = $conn->query("$sql");
$query = "SELECT * FROM names ORDER BY score DESC";
$sol = $conn->query("$query");
// initalizing of variables
$count = 1;
$data = array();
// inputs table into an array
while($rows = mysqli_fetch_array($sol)) {
$data[$rows['user_id']] = $rows['score'];
}
// -- Tied Column Sort --
// counts duplicates
$cnt_array = array_count_values($data);
// sets true (1) or false (0) in helper-array ($dup)
$dup = array();
foreach($cnt_array as $key=>$val){
if($val == 1){
$dup[$key] = 0;
}
else{
$dup[$key] = 1;
}
}
// gets keys of duplicates (array_keys()) and updates database accordingly ($update query)
foreach($dup as $key => $val){
if ($val == 1) {
$temp = array_keys($data, $key);
foreach($temp as $k => $v){
$update = "UPDATE names SET tied=1 WHERE user_id=$v";
$conn->query($update);
}
} else{
$temp = array_keys($data, $k);
foreach($temp as $k => $v){
$update = "UPDATE names SET tied=0 WHERE user_id=$v";
$conn->query($update);
}
}
}
Thank you all for answering and helping me get to the solution.
instead of the update code you've got use something simular
$query = "select score, count(*) as c from names group by score having c > 1";
then you will have the scores which have a tie, update the records with these scores and your done. Make sure to set tie to 0 at first for all rows and then run this solution
UPDATE for an even faster solution sql based:
First reset the database:
$update = "UPDATE names SET tied=0";
$conn->query($update);
All records have a tied = 0 value now. Next update all the records which have a tie
$update = "update docs set tied = 1 where score IN (
select score from docs
group by score having count(*) > 1)";
$conn->query($update);
All records with a tie now have tied = 1 as we select all scores which have two or more records and update all the records with those scores.
This question already has an answer here:
Post form and update multiple rows with mysql
(1 answer)
Closed last year.
For example, I have two data on my table:
| ID | Name | Age |
| 1 | Steve | 25 |
| 2 | Bob | 28 |
When i updating one value (for example: change "Bob" to "George"), it changes all value. This is the result:
| ID | Name | Age |
| 1 | George | 28 |
| 2 | George | 28 |
How to updating multiple rows in one query? To collect values, I use for loop like this:
<?php
...
$id_array = $_POST['id'];
$name_array = $_POST['name'];
$age_array = $_POST['age'];
$id = array();
$name = array();
$age = array();
for ($i = 0; $i < count($id_array); $i++) {
//count($id_array) --> if I input 4 fields, count($id_array) = 4)
$id[] = mysql_real_escape_string($id_array[$i]);
$name[] = mysql_real_escape_string($name_array[$i]);
$age[] = mysql_real_escape_string($age_array[$i]);
}
mysql_query("UPDATE member SET name = '$name', age = '$age' WHERE id = '$id'");
}
...
?>
Can you help me? Thank you.
Construct your query within the loop:
<?php
...
$id_array = $_POST['id'];
$name_array = $_POST['name'];
$age_array = $_POST['age'];
for ($i = 0; $i < count($id_array); $i++) {
//count($id_array) --> if I input 4 fields, count($id_array) = 4)
$id = mysql_real_escape_string($id_array[$i]);
$name = mysql_real_escape_string($name_array[$i]);
$age = mysql_real_escape_string($age_array[$i]);
$query .= "UPDATE member SET name = '$name', age = '$age' WHERE id = '$id';";
}
mysql_query($query);
}
...
?>
Hope that helps..!
Answer to your Question
MySQL updates all rows matching the WHERE clause, so to update multiple rows with the same value, you should use a condition matching all rows. To update all rows, dont set any where clause.
To update multiple rows with different values, you can't, use several queries.
Answer to your issue
In your code, $id, $name and $age are arrays so you can not use it in a string, this will not work. You should do the update in your FOR loop.
I advise you to try to respect resource oriented principe that all properties are assigned to their item (with associative array or object).
If you dont check the result, you could do all queries in one using a semi-colon.
I'm having some issues getting a tree menu to work from bottom-up.
I already have a script to work from top-down, which works fine.
This is a very simplified version of my table:
+-----+-----------+--------------------+
| uid | parent_id | page_address |
+-----+-----------+--------------------+
| 1 | 0 | index.php |
| 2 | 0 | login.php |
| 3 | 2 | dashboard.php |
| 4 | 3 | bookings.php |
| 5 | 3 | documents.php |
| 6 | 4 | changebookings.php |
| 7 | 4 | activities.php |
+-----+-----------+--------------------+
The page_address field is unique.
I can work out what page the user is currently on, for example changebookings.php
I would then like a menu to look like this:
login.php
dashboard.php
bookings.php
changebookings.php
activities.php
documents.php
However, the closest I've got so far is the following tree:
login.php
bookings.php
changebookings.php
As you can see, my script currently only returns the actual parent, and not a list of links currently in the parent.
For those interested, the script I use in total is at the bottom of this post.
Is there any easier way to get the bottom-up tree as required?
Many thanks
Phil
EDIT:
I've finally got the code to work, for future users who stumble upon this post, I have added the functionality below:
$dataRows = $databaseQuery->fetchAll(); // Get all the tree menu records
$dataRows = $result->fetchAll(PDO::FETCH_ASSOC);
foreach($dataRows as $row)
{
if($row['link_address']==substr($_SERVER['PHP_SELF'], 1, strlen($_SERVER['PHP_SELF'])-1))
{
$startingId = $row['parent_id'];
}
}
$menuTree = $this->constructChildTree($dataRows, $startingId);
private function constructChildTree(array $rows, $parentId, $nesting = 0)
{
$menu = array();
if(!in_array($nesting, $this->nestingData))
{
$this->nestingData[] = $nesting;
}
foreach($rows as $row)
{
if($row['parent_id']==$parentId && $parentId!=0)
{
$menu[] = $row['link_address'];
$newParentId = $this->getNextParent($rows, $row['parent_id']);
$parentChildren = $this->constructChildTree($rows, $newParentId, ($nesting+1));
if(count($parentChildren)>0)
{
foreach($parentChildren as $menuItem)
{
$menu[] = 'NESTING' . $nesting . '::' . $menuItem;
}
}
}
}
return $menu;
}
private function getNextParent($rows, $parentId)
{
foreach($rows as $row)
{
if($row['uid']==$parentId)
{
return $row['parent_id'];
}
}
}
Without reading your code you should be doing:
1) Get current page, look at parent ID.
2) Load all with that parent ID.
3) Get next Parent ID using current Parent ID as ID.
4) If new parent ID != 0, goto step 2 passing in the new Parent ID.
Sounds like you just need to edit your script to include ALL pages with the given ID as their parent ID.
<?PHP
$sql = "SELECT * FROM TABLE WHERE table parent_id=0";
$result = mysql_query($sql);
while($perant_menu = mysql_fetch_array($result))
{
echo display_child($perant_menu["uid"],$perant_menu["page_address"]);
}
// Recursive function
function display_child($parent_id,$name)
{
$sql= "SELECT * FROM table where parent_id = $parent_id";
$result = mysql_query($sql);
if(mysql_num_rows($result)>0)
{
while($menu = mysql_fetch_array($result))
{
echo display_child($menu["id"],$menu["page_address"]);
}
}
else
{
echo $name;
}
}
?>
I want to get text result like:
+----+-------+----------------------------------+----+
| id | login | pwd | su |
+----+-------+----------------------------------+----+
| 1 | root | c4ca4238a0b923820dcc509a6f75849b | 1 |
+----+-------+----------------------------------+----+
1 row in set (0.00 sec)
in PHP (string).
Example in php:
$query = mysql_query("SELECT * FROM users");
for (; $row = mysql_fetch_assoc($query); $data[] = $row);
I get array of arrays ($data):
$data =
0 => (id=>1, login=>root..)
But i want to get this as string:
+----+-------+----------------------------------+----+
| id | login | pwd | su |
+----+-------+----------------------------------+----+
| 1 | root | c4ca4238a0b923820dcc509a6f75849b | 1 |
+----+-------+----------------------------------+----+
1 row in set (0.00 sec)
By the way for query "insert into users set login = 'sp', pwd = 1, su = 0", this string must be "Query OK, 1 row affected, 2 warnings (0.18 sec)".
Like sql terminal though php!
Either invoke mysql client as an external command, or build the ASCII drawing table yourself. You can't get it purely by using PHP's MySQL library functions. Off the top of my head,
$result = `echo 'SELECT * FROM users' | mysql --user=username --password=password dbname`;
(ugly, slow, insecure, don't recommend); or simply get it as the array, iterate, and decorate with plusses imitating what mysql does (recommended). It's really easy.
However, I have no clue why you'd want that, unless you're using your PHP program as a command-line tool.
Collect the database result into an array of arrays(your $data variable is correct)
echo ascii_table($data);
I stole the following from someone named stereofrog
function ascii_table($data) {
$keys = array_keys(end($data));
# calculate optimal width
$wid = array_map('strlen', $keys);
foreach($data as $row) {
foreach(array_values($row) as $k => $v)
$wid[$k] = max($wid[$k], strlen($v));
}
# build format and separator strings
foreach($wid as $k => $v) {
$fmt[$k] = "%-{$v}s";
$sep[$k] = str_repeat('-', $v);
}
$fmt = '| ' . implode(' | ', $fmt) . ' |';
$sep = '+-' . implode('-+-', $sep) . '-+';
# create header
$buf = array($sep, vsprintf($fmt, $keys), $sep);
# print data
foreach($data as $row) {
$buf[] = vsprintf($fmt, $row);
$buf[] = $sep;
}
# finis
return implode("\n", $buf);
}
You can please query the following sql:
SELECT GROUP_CONCAT(id, ' | ', login, ' | ', pwd, ' | ', su)
AS 'User Object' FROM users group by id
Result Would Be:
I have a table which looks something like the following (first row is columns):
|section | col1 | col2 |
|----------------------|
|bananas | val | val2 |
|----------------------|
|peaches | val | val2 |
With some code to check if a section value matches up with one of the values in an array:
$sectionscope = Array('bananas', 'apples');
$sections = mysql_query("SELECT section FROM table WHERE col1=val AND col2=val2");
if (mysql_num_rows($sections)) {
$i = 0;
while ($row = mysql_fetch_array($sections)) {
if (in_array($row[$i], $sectionscope)) {
$section = $sectionscope[array_search($row[$i], $sectionscope)];
$section_is_valid = 1;
}
$i++;
}
}
If I echo the output from the while loop using echo $row[$i], it gives me: bananas
Doing the select from PHPmyadmin works fine
Can you tell me what I'm doing wrong here?
Thanks,
SystemError
Why are you incrementing $i in the while loop. Your query will return two rows and when you loop through the results, you can access the section value using $row[0] each time.
while ($row = mysql_fetch_array($sections)) {
echo $row[0];
}
This will print bananas and peaches.
In your code, when you enter the while loop second time, you are trying to retrieve section value using $row[1] (since your $i has incremented to 1), which will be null since your query result only contains one column.