Is it possible to use a nested mysql_fetch_assoc Basically I used the first one to populate text boxes, now from another table I need to fetch and image. How do I go about doing this without closing the first one, because I have more text boxes below this image that need to be fetched.
while($row = mysql_fetch_assoc($result)){
?>
<form id="myform" name="myform" action="profiledo.php" method="post">
<p>First Name
<input type="text" name="firstname" id="textfield" value="<?php echo( htmlspecialchars( $row['FirstName'] ) ); ?>" />
<br />
in order to be able to fetch $result more times (I see no reason though), you'll have to make single query for each fetch. I see no reason for doing so though
I think you are looking for a single query with a join. Something like:
SELECT * FROM `Profile` NATURAL JOIN `Table with Image`
But the exact query depends on the schemas of your two tables.
I think that it is more beneficial to put all of the information you want quickly into an array and accessing the retrieved data from memory, as opposed to slowly adding it while the query is looping through it.
// Read records
$query = "SELECT * FROM table WHERE condition";
$query = mysql_query($query);
// Put them in array
for($i = 0; $array[$i] = mysql_fetch_assoc($query); $i++) ;
// Delete last empty one
array_pop($array);
You can use print_r($array) to see the results.
If the image is not on the same table, you could join the tables via a similar identifier (unique user id?).
$query = "SELECT * FROM table1, table2 WHERE table1.id=table2.id";
Then the first user's First name would be: $array[0]['FirstName'], second would be $array[1]['FirstName'], etc.
Blake
The answer is, yes it is possible to use nested mysql_fetch_assoc().
Though I'm not very sure on the question and what does your current implementation looks like but here are some suggestion anyways:
Use a JOIN query: though it is possible only if the data contained in your text-boxes is related to the image. From what little information you have provided, I guess the image is the user's image and is stored in a separate table. If that is true, then the most obvious implementation is that the image table is referenced by some user id. Assuming that there is a User and UserImage tables, this is how the JOIN query might look like:
SELECT `User.*`, `UserImage`.`image`
FROM `User`
INNER JOIN `UserImage` ON `User`.`id` = `UserImage`.`user_id`
WHERE `User`.`id` = xxx;
Please note that the above is only a template query and you'll need to change this as per your schema and logic. Also, I missed to mention that the above implementation might need some extra logic if there can be multiple images per user.
A nested mysql_fetch_assoc() is possible but it depends on your implementation. As you've mentioned that the first (or outer) mysql_fetch_assoc() is used to fill-in text boxes. And within this, you would like to run another mysql_fetch_assoc() to fetch the image. So, if the image query is run on a separate table and is run as a separate query, then you might store its result in a separate variable, say $result1 and then run the inner mysql_fetch_assoc() on that resultset.
while ($row = mysql_fetch_assoc($result)) {
// $row array now contains the profile details
$result1 = mysql_query('the query for fetching the image');
while ($row1 = mysql_fetch_assoc($result1)) {
// $row1 array now contains the image
}
}
It is important that the inner mysql_fetch_assoc() runs on a separate resultset.
Hope the above helps! If it is none of the above that you are trying to do, I'd appreciate if you could provide more inputs on what you require.
Related
Function render makes website 500% slow! Can anyone fix that please ?
Someone told me :
because it sends a database request on each iteration of the loop (it's not the only problem with this chunk of code but it's the most taxing one)
Yes I understand what that means. His way is:
you need to get all of the data before you start building the menu,
then you just insert the data instead of requesting more data on each
iteration
But i don't know how i must do it!
<?php
$menu_html='';
function render_menu($parent_id,$actmenuid)
{
$obj = new Database();
$con = $obj->dbconnectt();
global $menu_html;
$result=mysqli_query($con, "select * from tbl_menu where parent_id='$parent_id'");
if(mysqli_num_rows($result)==0) return;
if($parent_id==0){
$menu_html.='<ul class="topnav">';
}else{
$menu_html.='<ul>';
}
while($row=mysqli_fetch_array($result)) {
$childnum = $obj->recordcount("SELECT * FROM tbl_menu WHERE parent_id='".$row['id']."'");
if($childnum == 0){
$linkvalue='/category/'.$row['id'].'.html';
} else{
$linkvalue='#';
}
if($row['id']==$actmenuid && $actmenuid !=NULL){
$actv='class="active"';
}else{
$actv='';
}
$menu_html.='<li '.$actv.'>'.$row['title'].'';
render_menu($row['id'],$actmenuid);
$menu_html.='</li>';
}
$menu_html.='</ul>';return $menu_html;
}
if($isDsh==false){
echo render_menu(0,$actmenuid);
}
?>
Depending on how many records you have, try removing this query from inside the loop since it's running for every record on the first query.
$childnum = $obj->recordcount("SELECT * FROM tbl_menu WHERE parent_id='".$row['id']."'");
Change it a single query like this where it returns counts for each parent idea, and place it outside of the loop:
$parentcount = mysqli_query($con, ("SELECT parent_id, count(*) FROM tbl_menu GROUP BY parent_id");
There may be other issues, so please post the database structure and number of records that you're working with too.
Don't make recursive queries.
Having "more than 1000" rows is not too big. You can simply call everything from the table into php, then perform the recursive html build in php this will have a memory overhead, but far less processing overhead because you only ever make one trip to the db.
Alternatively (when your db table is prohibitively large), you should avoid gathering rows unnecessarily by adding a new column. The new column will store all "descendants" for the respective row when the row is INSERTed or update it when it is UPDATEd. Then you only need to reference this column when needing to call specific rows. In other words, do the recursive processing only once (when writing to the db) AND not when needing to display the data. This will, again, produce a finite result set in one query which can then be recursively traversed to build the desired output.
basically you need to do what #spudly has suggested.
But there is a small catch in his solution which depending on the number of the rows in yous tbl_menu table you may use a big chunk of memory to fetch all the records.
you can optimise it more with using his solution but changing the query to:
select
parent_tbl_menu.id,
count(child_tbl_menu.id) as cnt
from
tbl_menu as parent_tbl_menu
left join
tbl_menu as child_tbl_menu
on parent_tbl_menu.id = child_tbl_menu.parent_id
where
parent_tbl_menu.parent_id = ?
group by
parent_tbl_menu.id
This way you will only fetch the child records of a specific parent.
And please consider using prepared statements as your code has sql injection vulnerability.
Connect (from PHP to MySQL) only once for the entire web page.
Don't put a SELECT inside a loop if you can do all the work in a single SELECT, such as with a JOIN. (Exception: A "hierarchical" table needs the nested SELECT. Exception to the exception: MySQL 8.0 and MariaDB 10.2 can do it with a "recursive CTE".)
Don't fetch all the columns (SELECT *) when all you want it is a recordcount. Instead, SELECT COUNT(*) ... and use the number returned.
1000 of anything is probably excessive for a web page. Re-think the UI.
I have two mysql tables. I want to get the data from these tables and show it in a loop. The data is totally unrelated to each other and should stay that way. I just need to show data from these two different tables in the same place.
I tried the mysqli_multi_query, but I couldn't show the results from an individual column like I can with a normal query.
For each of these two tables, I need 2 SELECT statements with two WHERE clauses. Does anyone know how to do this?
I've tried all different ways of trying to get the info from both tables and just show them in one loop. I've tried mysqli_multi_query, but don't know how to save specific column results in a variable.
$sql = "SELECT *
FROM misc
WHERE height LIKE '$height_input'
SELECT *
FROM bolts
WHERE name LIKE '$bolt_name_input'
;
";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$height_row = $row['height'];
$bolt_name_input = $row['name'];
?>
Height Row: <?php echo $height_row; ?>m<br />
bolt Name: <?php echo $bolt_name_input; ?><br />
} //while
My error message is generally "Trying to get property 'num_rows' of non-object".
Yes everyone, I have taught myself PHP and MySQL through online tutorials and have not had a lot of experience with them yet. I apologise, I am still getting the hang of this.
I have just worked out now by trial and error that I can show information from a table outside of the while loop. I had no idea I could do this! Which changes everything. So I can select information from various database tables using different SELECT statements and then echo them all into one place in my HTML table underneath it on my web page. The results don't have to be shown in the while loop, they can be outside it.
So my structure now looks like this basically:
SELECT from table 1 column 1 WHERE (form input value)
num rows
while loop
$height = $row_height['height'];
end num rows
end while loop
SELECT from table 2 column 1 WHERE (form input value)
num rows
while loop
$bolts = $row_bolts['bolts'];
end num rows
end while loop
<table>
<tr>
<td>echo $height</td>
<td>echo $bolts</td>
</tr>
</table>
So, this is working for me to retrieve multiple results from my different tables. I have to change the variable names of the sql statement each time, I guess I could do it with a function so i can repeat it and make it look neater, but this is working for me this way. So, with bolts I am using the variable names $sql_bolts, $result_bolts and $row_bolts and with height I am using variable names $sql_height, $result_height and $row_height and so on.
$bolts_input = $_POST['bolts'];
$sql_bolts = "
SELECT *
FROM bolts
WHERE name LIKE '$bolts_input'
;";
$result_bolts = $conn->query($sql_bolts);
if ($result_bolts->num_rows > 0) {
// output data of each row
while($row_bolts = $result_bolts->fetch_assoc()) {
$bolts = $row_bolts['name'];
} //bolts while
} // bolts num rows
I am not using mysql, but mysqli. I did a whole bunch of tutorials on PDO and how to connect to the database and retrieve information and just couldn't figure out how to show values from a row like I can with the above. It's frustrating because I want to use the latest methods, but I can't find how to online that makes sense to me.
Thank you for eveyone's comments so far.
I need to run queries in mysql and dislay the output in some way, however the queries are provided by a third party and I can't change them. An example would be:
SELECT j.`First Name`, j.`Last Name`, c .*
FROM PersonalInfo j
INNER JOIN
Evaluations c
ON j.UIN = c.UIN
Where table PersonalInfo has people's personal info and table Evaluations stores people's evaluations. The Evaluations table contains blob fields where the (sometimes heavy) pdf's of the evaluations have been stored.
The problem with this query is that since Evaluations have blob fields and these are selected in the SELECT statement I have no option than to read those fields when I do $result->fetch_assoc() as below
if ($result = $mysqli->query($DTIS->query)){
while ($row = $result->fetch_assoc()) {
// at this point I believe the (heavy) blob info has been fetched and put into $row["blobfield"] right ?
// if field is blob display just a link, otherwise the info.
}
}
Is there a way to SKIP THE FETCHING of a specific COLUMN so I can display the table quickly without reading any of the heavy blob info ? Remember I can't change the query string. Any code template is also appreciated it.
Thanks for the help.
If queries are provided by a third party and you can't change them - no.
You can use below way to access your data field wise, however it is some what lengthy but may be useful to you:
First find the number of rows for that query // which you can get using mysql_num_rows
Loop using that number in below way, to get only selected field data one by one
$result = mysql_query($query);
$count = mysql_num_rows($result);
$i = 0;
while ($i < $count) {
$firstColumnData[] = mysql_result($result, $i, 'first_field_name');
$secondColumnData[] = mysql_result($result, $i, 'second_field_name');
$i++;
}
In this way, you may get only desired field data from mysql result set.
Hi there i am working on PHP code that is selecting columns from two tables.
Here is my code:
$result2 = mysql_query("SELECT *
FROM `videos`, `m_subedvids`
WHERE `videos.approved`='yes' AND
`videos.user_id`='$subedFOR'
ORDER BY `videos.indexer`
DESC LIMIT $newVID");
while($row2 = mysql_fetch_array($result2))
{
$indexer = addslashes($row2['videos.indexer']);
$title_seo = addslashes($row2['videos.title_seo']);
$video_id = addslashes($row2['videos.video_id']);
$title = addslashes($row2['videos.title']);
$number_of_views = addslashes($row2['videos.number_of_views']);
$video_length = addslashes($row2['videos.video_length']);
}
When i try to print $indexer with echo $indexer; it's not giving me any results.
Where is my mistake in this code?
It seems to me like the key 'indexer' isn't in your results. It's hard to tell, since you haven't listed a definition for your table and you're using SELECT * so we can't see the names.
It makes the program easier to read later, if instead of SELECT *..., you use SELECT col1, col2, .... Yes, SELECT * will save you some typing right now, but you'll lose that time later when you or anyone else who works on your code has to check the table definition every time they work with that line of code.
So, try changing your query to explicitly select the columns you use. If it's an invalid column you'll get an error right away rather than this silent failure you're getting now, and you'll thank yourself later as well.
So long as videos.indexer is a unique field name among all tables used in the query you can change
$indexer = addslashes($row2['videos.indexer']);
to
$indexer = addslashes($row2['indexer']);
You don't need to (or can not) use the table name when referring to the result.
This code is used to get a specific list of ID's from one table, then use those ID's to get the information from another table. Once I get all the information from the 2nd table, I am attempting to sort the data alphabetically based on a field in the 2nd table.
Example, I am getting the name based on a correlating ID and then want to display the entire result in alphabetical order by name (artist_name).
Here is the code I have. When I execute this without the sort(), it works fine but is not in alphabetical order. When I add the sort() in the 2nd while statement, the page looks the same but the name and other data do not display. The source code in the browser shows that the results are being accounted for but the sort must be preventing the variables or information from being displayed for some reason.
I haven't used a sort function before and I tried looking at some examples but couldn't really find something specific to my situation. Any and all help would be greatly appreciated. I have already looked at the PHP manual for sort so no need to send me a link to it ;-)
<?php $counter = 0;
$artistInfo = mysql_query("SELECT DISTINCT event_url_tbl.artist_id FROM event_url_tbl WHERE (SELECT cat_id FROM artist_tbl WHERE artist_tbl.artist_id = event_url_tbl.artist_id) = 1");
while ($aID = mysql_fetch_array($artistInfo))
{
$getArtistInfo = mysql_query("SELECT * FROM artist_tbl WHERE artist_id = '" . $aID['artist_id'] . "'");
while($artist = mysql_fetch_array($getArtistInfo))
{
sort($artist);?>
<a class="navlink" href="<?=HOST?><?=$artist['page_slug']?>/index.html">
<?=$artist['artist_name']?>
</a><br />
<?php }
}
?>
Your best bet, as a commenter mentioned, is to use an ORDER BY clause in SQL.
SELECT *
FROM artist_tbl
WHERE artist_id = XXX
ORDER BY artist_name ASC
The other commenter who suggested using PDO or mysqli is also correct, but that's a different issue.
To answer your specific question about sorting, according to the manual,
Blockquote Note: This function assigns new keys to the elements in array. It will remove any existing keys that may have been assigned, rather than just reordering the keys.
This means all of your array keys ('page_slug', 'artist_name', etc) are wiped out. So when you try to refer to them later, there is no data there.
Were you to use this method, you would want to use asort to sort an associative array.
However, you don't want to use sort here. What you're sorting is the variables for one row of data (one individual artists), not all of your artists. So if you think of each artist row as an index card full of data (name, id#, page slug, etc) all you're doing is moving those items around on the card. You're not reorganizing your card catalog.
Using an order by clause in the SQL statement (and rewriting in PDO) is your best bet.
Here is how I would rewrite it. I have to take some guesses at the SQL because I'm not 100% sure of your database structure and what you're specifically trying to accomplish, but I think this would work.
$query_str = "
SELECT
artist.name,
artist.page_slug
FROM
artist_tbl AS artist
INNER JOIN event_tbl AS event
ON event.artist_id = artist.artist_id
WHERE
artist.cat_id = 1
ORDER BY
artist.name ASC";
$db_obj = new PDO (/*Connection stuff*/);
$artists_sql = $db_obj->prepare ($query_str);
$artists_sql->execute ();
while ($artist = $artists_sql->fetch (PDO::FETCH_ASSOC)) {
$return_str .= "<a class='navlink' href='{HOST}
{$artist['page_slug']}/index.html'>
{$artist['artist_name']}</a><br/>";
}
echo $return_str;
In all honesty, I would probably create an artist class with a display_link method and use PDO's fetchObject method to instantiate the artists, but that's getting ahead of ourselves here.
For now I stuck with procedural code. I don't usually like to mix my HTML and PHP so I assign everything to a return string and echo it out at the end. But this is close to what you had, using one SQL query (in PDO - seriously worth starting to use if you're creating new code) that should give you a list of artists sorted by name and their associated page_slugs.
You could do all of this in one query:
SELECT * FROM event_url_tbl AS event
INNER JOIN artist_tbl AS artist ON event.artist_id = artist.id
ORDER BY artist.name DESC;
This cuts out a lot of the complexity/foreaches in your script. You'll end up with
Label1 (Label 1 details..) Artist1 (Artist1 details..)
Label1 (Label 1 details..) Artist2 (Artist1 details..)
Label2 (Label 2 details..) Artist3 (Artist1 details..)
Always good to bear in mind "one query is better than many". Not a concrete rule, just if it's possible to do, try to do it. Each query has overheads, and queries in loops are a warning sign.
Hopefully that helps