Link to home
Start Free TrialLog in
Avatar of LB1234
LB1234

asked on

How to count the number of items returned from resource record (query)

I have returned a bunch of results and put them in a table, which is itself within a form users must fill out. I was going to write a while statement that uses a variable to name each repeating form name unique $name[$i] but need to know how many resources so that I can write the for() statement.  Thanks.
SOLUTION
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Why not use foreach() ?  Iterators do not need to know how many elements are present.
Avatar of LB1234
LB1234

ASKER

i thought you couldn't use a foreach() for a resource record, only a standard PHP array?
To add to Ray's point, the while() iterator is typically the best one to use for looping through query results. See the examples here:

http://www.php.net/manual/en/mysqli-result.fetch-assoc.php
Want to show us what you've got so far?  We might have some useful ideas.
Avatar of LB1234

ASKER

Thank you!  one moment!
Avatar of LB1234

ASKER

Type is a drop down and I'm trying to capture the one the user picks.  I have the $i variable now, and I guess i just need to make a "name = type[$i]" statement in the <option> tag?  I don't know if the code below is correct.  I'm not sure where to put the $i variable.  This is what i have so far.  haven't added the name part yet.

<?php

$get_transactions = "SELECT * FROM transactions order by date ASC LIMIT 10";
$transactions_result_set = mysqli_query($connection, $get_transactions);


$row_cnt = mysqli_num_rows($transactions_result_set);

for ($i=0; $i<=$row_cnt; $i++);

<?php


$type = "<select>";
while ($row = mysqli_fetch_assoc($type_result_set)) {
$type .= sprintf("<option value='%s'>%s</option>", $row["type_name"], $row["type_name"]);
}
$type .= "</select>";
?>

<?php while ($expenses = mysqli_fetch_assoc($transactions_result_set)) { 
?>

 <tr>
 <td><?php echo date("F d, Y", strtotime($expenses["date"]));?></td>
 <td><?php echo number_format($expenses["amount"], 2);?></td>
 <td><?php echo $expenses["vendor"];?></td>
 <td><?php echo $expenses["description"];?></td>
 <td><?php echo $type; ?></td>
 <td><textarea name="notes" id="notes"></textarea></td>
 <td nowrap="nowrap">Trip place holder</td>
 <td><?php echo date("m/d/Y")?></td>
  <td>User Name</td>
<!--  <td><?php// date("F d, Y");?></td>-->
  
 <td><input name="done" type="checkbox" id="done" value="YES"></td>
 
 </tr>
 
 
<?php
}
?>

Open in new window

Avatar of LB1234

ASKER

I know the sprintf() line needs to fixing so that names are unique, but not sure how.
$get_transactions = "SELECT COUNT(*) as Cnt, * FROM transactions order by date ASC LIMIT 10";
$transactions_result_set = mysqli_query($connection, $get_transactions);
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of LB1234

ASKER

I don't know what <<< or EOD are.  I'm also confused because all the variable names are different.  I will look them up that syntax also try to understand the code you've written.
The <<< notation is called "Heredoc" notation.  It's a very useful way of defining a string when you need variable substitution inside it.  Don't be put off by the warning, just be mindful of the "column one" requirement for the end delimiter.
http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc
Avatar of LB1234

ASKER

Would this work Ray?  I know your way is much more elegant than mine, but dealing with refactoring and the concept itself is too much for me, right now.  Very new at this.  Once i get the concept and code working, I'll work on refactoring.

<?php

echo $row_cnt = mysqli_num_rows($transactions_result_set);

for ($i=0; $i<=$row_cnt; $i++);

?>

<td><textarea name="notes<?php echo $i ?>" id="notes"></textarea></td>

Open in new window

I don't know if it would work.  I expect it would generate invalid HTML because it appears to be planning for multiple <textarea> tags, but it uses the id= attribute, which must be unique in the document.  You might want to try it out, then use "view source" to see what the PHP script generated.
Avatar of LB1234

ASKER

the id=attribute is optional anyway, so couldn't i just get rid of it?  The important thing is to make sure that each "notes" text area is captured, i Guess?
Avatar of LB1234

ASKER

didn't work.  I got rid of the ID field but when i  used

<td><textarea name="notes<?php echo $i ?>"></textarea></td>

view source:

<td><textarea name="notes11"></textarea></td>

so weird... should've counted up sequentially.
You could try that.   If you want to style the textarea, you could use a class= attribute.  If you want to use TinyMCE or similar, you might want to set aside some extra test time if there are multiple textarea items on the page.

One of the useful things you can do when working with forms is to add this statement to your action= script.

var_dump($_POST);

That will let you see exactly what the form sent to the action script.
Avatar of LB1234

ASKER

when i ran this check:

$row_cnt = mysqli_num_rows($transactions_result_set);

for ($i=0; $i<=$row_cnt; $i++) {
	echo "I: $i <br>";	
}

Open in new window


I got:

I: 0
I: 1
I: 2
I: 3
I: 4
I: 5
I: 6
I: 7
I: 8
I: 9
I: 10

which seems to be right... Can't understand why it's not incrementing the number in that name= code.
Avatar of LB1234

ASKER

DUH!!!!!!!

i know what i did wrong...

i didn't put in an echo in the for statement!!
Avatar of LB1234

ASKER

Nope that wasn't it.  I think what's happening is the for statement is being completed before the rest of the script runs.  It's not looping through.  I have to put the for statement in the actual <td> line.
Avatar of LB1234

ASKER

That didn't work either.  When i do this:

<td><textarea name="notes <?php for ($i=0; $i<=$row_cnt; $i++) {
	echo $i;	
} ?>
"></textarea></td>

Open in new window


i get this :  <td><textarea name="notes 012345678910"></textarea></td>
Avatar of LB1234

ASKER

With the for statement ahead of the table, it's completing and returning a value of "11".  And it's inserting that into name = "notes11".
Can you please isolate this part of the issue into the form of the SSCCE and post the code here?  I am fairly sure we can help once we have enough of the code that we can duplicate the issue on our own servers.  Thanks.
Avatar of LB1234

ASKER

User generated image
Ok I'll try to be as clear as possible.  Every user has a number of charges per month.  My code grabs all of those and puts them into a table.  I'm trying to capture responses to the form in the type, notes, and done areas.  As I understand it, each row of the table must have a unique name so they must be setup as name= type, type1, type 2, so that the captured value isn't overwritten because they all have a common name attribute, as is the case now.  I'm trying to use PHP to insert a "1" after the value for name in the form to make each entry have a unique name.
Avatar of LB1234

ASKER

nevermind, i got it... i need an array in there to capture the value of $i, and then echo that sequentially, I think.  Let me test this out.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of LB1234

ASKER

Chris, thanks so much.  Question, does $ID = $expenses['yourPrimaryKey']; have to go in the
while ($expenses = mysqli_fetch_assoc($transactions_result_set)) {
    //code goes in here to create each record
    //you have access to each data record in the $expenses array.
}

Open in new window


code block?
Yes - you don't have access to anything from your database until you're inside this block - that's what the 'while' line does - it assigns each row of your query to the expenses variable, one row at a time.
Avatar of LB1234

ASKER

Ok i got everything changed and it's still collecting table data so all appears well.  on the process page, i just wanted to see if the info from the form was captured, but doesn't seem to be working.  Is this syntax correct on the processing page?

<?php


print_r($_POST["expense[][]"]);



?>
Start with var_dump($_POST); and refine your data-access strategy after you see the structure of $_POST.
Avatar of LB1234

ASKER

var dump returns a bunch of information!  This is great!  

 <td><?php echo "<select name='expense[" . $id . "][type]'>" . $type_options . "</select>"?></td>
 
 
 <td><?php echo "<textarea name='expense[" . $id . "][notes]'></textarea>";?></td>

not sure of the syntax of getting specific post information from this though.
Hooray!  You have discovered the programmers' best friend: var_dump().  Couple of things.  Do not do this:

<?php echo "<select name='expense[" . $id . "][type]'>" ...

This article explains why that unquoted index is a time-bomb in your code.
https://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_12241-Quotation-Marks-in-PHP.html

If you want to post the output of var_dump() here in the code snippet I will be glad to show you how to tease it apart into something useful.
Avatar of LB1234

ASKER

:)

array (size=1)
  'expense' => 
    array (size=10)
      245 => 
        array (size=3)
          'type' => string 'Asset - Office Equipment' (length=24)
          'notes' => string 'something' (length=9)
          'done' => string 'YES' (length=3)
      246 => 
        array (size=3)
          'type' => string 'Conference: Meeting/Banquet rooms' (length=33)
          'notes' => string 'something' (length=9)
          'done' => string 'YES' (length=3)
      247 => 
        array (size=2)
          'type' => string 'Computer Supplies' (length=17)
          'notes' => string 'something' (length=9)
      248 => 
        array (size=2)
          'type' => string 'Cell Phone' (length=10)
          'notes' => string 'something' (length=9)
      249 => 
        array (size=3)
          'type' => string 'Computer Software' (length=17)
          'notes' => string 'something' (length=9)
          'done' => string 'YES' (length=3)
      250 => 
        array (size=3)
          'type' => string 'Computer Software' (length=17)
          'notes' => string 'something' (length=9)
          'done' => string 'YES' (length=3)
      238 => 
        array (size=2)
          'type' => string 'Conference: Meals - Employee Only' (length=33)
          'notes' => string 'something' (length=9)
      239 => 
        array (size=2)
          'type' => string 'Conference: Meals - Clients/Entertainment' (length=41)
          'notes' => string 'something' (length=9)
      240 => 
        array (size=2)
          'type' => string 'Conference: Miscellaneous' (length=25)
          'notes' => string 'something' (length=9)
      241 => 
        array (size=3)
          'type' => string 'Conference: Meals - Employee Only' (length=33)
          'notes' => string 'something' (length=9)
          'done' => string 'YES' (length=3)

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of LB1234

ASKER

Ok, so I got the array info back properly, and now I need to insert the entries into mysql.  Would that go like this?

<?php


foreach ($_POST['expense'] as $id => $expenseInfo) {
	$query = "INSERT INTO transactions (type, notes, done) VALUES ";
	$query .= "({$expenseInfo["type"]}, {$expenseInfo["notes"]})";

   if (isset($expenseInfo['done'])) { 
      $query2 = "INSERT INTO transactions (done) VALUES"; 
	  $query2 .= "({$expenseInfo["notes"]})";
	  }
}

?>

Open in new window

No. You're running 2 queries there. You would have something like this:

foreach ($_POST['expense'] as $id => $expenseInfo) {
   $type = $expenseInfo["type"];
   $notes = $expenseInfo["notes"];
   $done = (isset($expenseInfo['done']) ? $expenseInfo['done'] : '' ;
   $query = sprintf("INSERT into transactions (type, notes, done) VALUES ('%s', '%s', '%s')", $type, $notes, $done);
   mysqli_query($query);
}

Open in new window

The $done variable is set to the value of the checkbox is it's ticked and an empty string if it's not - change that accordingly.

Also, I would have assumed you would want to UPDATE your database (using your Primary Key), not INSERT new records?
Avatar of LB1234

ASKER

Argh, you're right -- UPDATE.  What would be the syntax please..  I tried to craft my own, but i know it's wrong :(
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of LB1234

ASKER

Getting Parse error: syntax error, unexpected ';' on line 4 of your code.  Don't see anything wrong it tho!
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of LB1234

ASKER

Guys, I finally got this working with all your help.  Chris, I want to especially thank you for dealing with the formidable incompetence of a real noob.  Your help has been incredibly awesome.  Not only can i move forward with the project, but you've really advanced my understanding of coding and the concepts related to this project.  I thank you for the time and effort that went into you re-factoring and fixing my truly terrible code.  I made sure to really try to grasp the code you'd written, rather than just plugging it into the script and moving on.  Still a few things I'm not 100% clear on, but I'll get them.  I guess that's part of the journey and the challenge. ;)

Ray, as always, your continued help and is greatly appreciated.

Lol this was like a bad Oscars award speech.  I'll end it here.  Thanks again guys. :)
No worries. Pleased you got it working, but especially pleased you learned something and understood the code. It's all too easy to copy/paste these days, but learning why and how code works will stand you in good stead.

You know the saying - 'Give a man a fish, he eats for day. Teach a man to fish, he eats for a lifetime' or something like that ;)

As for the incompetence of a real noob and the truly terrible code - we've all been there. Occassionally I come across some old code I've written and I'm amazed that it worked at all...although it can be a worthwhile learning exercise to revisit and refactor it from time to time.

Good luck with your coding