#16
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    80
    Rep Power
    7
    ... and apparently i was more confused on this cross join business than i thought in how to display the results...

    obviously, i want to only display the username and email once, but i want to display ALL the permissions and their check boxes. Im assuming its a FOREACH?
  2. #17
  3. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,317
    Rep Power
    7170
    Your database result set will include the username and email multiple times, but your output doesn't have to display the result set returned by the database row for row. You can use a foreach loop to group the rows in a different structure than the database returns, and then use a second foreach loop or loops to display the final structure.

    The most straight forward way to do this is just to regroup the results into a new array.
    PHP Code:
    $organized_results = array();
    foreach(
    $database_results as $row) {
      
    $organized_results[$row['grouping_field']][] = $row;
    }

    foreach(
    $organized_results as $grouping_value => $grouped_rows) {
      echo 
    "{$grouping_value}\n";
      foreach(
    $grouped_rows as $row) {
        echo 
    "---- {$row['field']}\n";
      }

    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around
  4. #18
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    80
    Rep Power
    7
    Originally Posted by E-Oreo
    Your database result set will include the username and email multiple times, but your output doesn't have to display the result set returned by the database row for row. You can use a foreach loop to group the rows in a different structure than the database returns, and then use a second foreach loop or loops to display the final structure.

    The most straight forward way to do this is just to regroup the results into a new array.
    PHP Code:
    $organized_results = array();
    foreach(
    $database_results as $row) {
      
    $organized_results[$row['grouping_field']][] = $row;
    }

    foreach(
    $organized_results as $grouping_value => $grouped_rows) {
      echo 
    "{$grouping_value}\n";
      foreach(
    $grouped_rows as $row) {
        echo 
    "---- {$row['field']}\n";
      }

    perfect, works great. thanks.
  6. #19
  7. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    There's absolutely no reason for looping over the result set twice. Make one loop. In every iteration, you output the checkbox. And in the first iteration, you also output the user details.

    Yeah, I think we definitely need a FAQ entry, since this pattern seems to have gone out of fashion.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  8. #20
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    80
    Rep Power
    7
    Maybe the reason I am having trouble producing my results is because I am not outputting the results in a table currently? Maybe I'm over thinking it.

    Not sure if you saw my other questions based on your original post yesterday...

    ... and is there a book or website that would be beneficial for me to obtain? I know there are a lot of different interpretations for everything, but i'd like to be able to have a solid go to guide whenever i need to figure something out.
  10. #21
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    80
    Rep Power
    7
    I am definitely missing something, and I greatly apologize for continuing this...

    Since the double looping was unnecessary, I cant seem to have to results set ONLY produce the user details once, and then repeat all of the necessary check box elements on the remaining loops through the query.

    Should I be using one query to display the user details, followed by a second to only bring in the permissions? Should I be using something other than FOREACH?

    I'm really confused. Apologize again for the amateurness of my problem. I probably could have figured it out but i cant seem to find any examples of how a similar solution was figured out.
  12. #22
  13. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Each row of the result set contains a single permission as well as all user details, right? And you want to display the user details once, and after that you want a list of checkboxes for all the permissions. Right?

    So why not simply go through the result set once(!), generate a checkbox for each row, and for the first row, you also generate a header with the user details?

    As pseudo code:

    Code:
    first_iteration := true
    each row in result_set:
    	# if it's the first row, we display the user info
    	if first_iteration:
    		print_line "User name: " + escape(row.user_name)
    		print_line "Email address" + escape(row.email_address)
    		first_iteration := false
    	# in any case, we display the checkbox
    	print_line "<input type='checkbox' ... />" + ...
    You'll need this pattern very often in PHP, because that's how relational database systems work: They collect all information in a single stream of rows. To get a structure from this, you need to loop through the rows and display different information depending on the row number or certain values or whatever.

    A typical example would be a bunch of products, and each product has a list of attributes. The result set would look something like this:

    Code:
        product_id    |    product_name    |    attribute_name    |    attribute_value    
    ------------------+--------------------+----------------------+-----------------------
      96              |  fence             |  height              |  enormous
      96              |  fence             |  material            |  wood
      96              |  fence             |  costs               |  huge
      128             |  gate              |  weight              |  minimal
      128             |  gate              |  color               |  red
      128             |  gate              |  material            |  steel
      128             |  gate              |  costs               |  tiny
    ...
    Now you wanna list of products, and for each product, you also wanna display the attributes.

    You loop through the rows. For every row, you display the attribute. And if the product ID changes, you also display the product info:

    Code:
    last_product_id := null
    each row in result_set:
    	# if the product ID changes (or it's the very first ID), we display the product name
    	if last_product_id = null or row.product_id != last_product_id
    		print_line "Product " + row.product_name
    		last_product_id := row.product_id
    	# in any case, we display the current attribute
    	print_line row.attribute_name + ": " + row.attribute_value
    Code:
    Product "fence"         <-- first row (new product ID)
    height:   enormous      <-- first row		
    material: wood          <-- second row
    costs:    huge          <-- third row
    
    Product "gate"          <-- fourth row (new product ID)
    weight:   minimal       <-- fourth row
    color:    red           <-- fifth row
    material: steel         <-- sixth row
    costs:    tiny          <-- seventh row
    Since a lot of people seem to struggle with this pattern, I'll probably write down a short explanation this weekend.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  14. #23
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    80
    Rep Power
    7
    I definitely understand the concept. And based on your example, i feel like i have it right...

    but, its doing the opposite of what I intended it to do.

    It NEVER displays the user info, but it displays the checkboxes as intended. its almost like something is backwards still. here is my code:

    PHP Code:
    <?php
                            $last 
    null;
                            foreach(
    $permiss as $row):
                                if (
    $last null or $row['category_id'] != $last) {
                        
    ?>
                        <input type="hidden" name="id" value="<?php echo $row['user_id']; ?>" />
                        Username:<br />
                        <b><?php echo htmlentities($row['username'], ENT_QUOTES'UTF-8'); ?></b>
                        <br /><br />
                        E-Mail Address:<br />
                        <input type="text" name="email" value="<?php echo htmlentities($row['email'], ENT_QUOTES'UTF-8'); ?>" />
                        <br /><br />
                        Password:<br />
                        <input type="password" name="password" value="" /><br />
                        <i>(leave blank if you do not want to change the password)</i>
                        <br /><br />
                        Permissions:<br />
                        <?php
                                $last 
    $row['category_id'];
                                }
                        
    ?>
                        <input type="checkbox" name="permissions[]" value="<?php echo $row['category_id']; ?><?php IF ($row['has_permission'] == 1) { echo "CHECKED"; } ?><?php echo $row['category']; ?><br />
                        <?php
                            
    endforeach;
                        
    ?>
  16. #24
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    80
    Rep Power
    7
    well i feel slightly stupid.

    All i needed to do was change the if statement to a double == sign and only keep the $last == null portion and it works fine.

    And it looks like I have everything taken care of in terms of inserting, deleting, etc for the permissions.

    Thanks for all the help so far. If I have any other issues I am sure you will hear from me.
  18. #25
  19. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    And now you need to add security.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  20. #26
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    80
    Rep Power
    7
    Originally Posted by Jacques1
    And now you need to add security.
    I've actually been in the process of working through this security FAQ since you had mentioned it in a previous post.

    The $_GET statements is the big one for me, as well as escape all outputs. But those are easy fixes.

    I'm also using E-Oreo's tutorial for the user interface as my initial guide, which is also helping me to learn all of these extra security items.

    Some follow up questions, just to gain a better understand of some things:

    1) You had mentioned previously about not using explode(). Was that in reference to that specific instance, or is it a bad idea to EVER use it?

    2) on the security FAQ post, is there any specific reasoning behind using for example functions.inc.php instead of just functions.php?
  22. #27
  23. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Originally Posted by zubes1001
    1) You had mentioned previously about not using explode(). Was that in reference to that specific instance, or is it a bad idea to EVER use it?
    There's nothing wrong with the function itself. What's wrong is stuffing the database values into a pseudo-CSV and then using explode() to extract them again.



    Originally Posted by zubes1001
    2) on the security FAQ post, is there any specific reasoning behind using for example functions.inc.php instead of just functions.php?
    The extension tells you that this file is supposed to be included and doesn't work on its own. The name doesn't increase security or something.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  24. #28
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    80
    Rep Power
    7
    I have another query or two using explode at the moment, i will definitely revisit those.

    And good to know re: the extensions.

    Thanks for your help. I've learned a lot.
  26. #29
  27. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2008
    Posts
    80
    Rep Power
    7
    Originally Posted by Jacques1
    And now you need to add security.
    I forgot one follow up question re: #3.

    The article discusses not to display internal errors.

    Is a catch(PDOException $ex) fall under that same category? Or is that typically considered OK?

    It's part of E-Oreo's tutorial, so I figured it was OK, but I'd rather be safe than sorry.
  28. #30
  29. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Originally Posted by zubes1001
    Is a catch(PDOException $ex) fall under that same category? Or is that typically considered OK?
    No, it's not OK. It's dangerous and simply useless. I don't understand why it's so extremely popular that it even made it into the PHP manual.

    The reason why exceptions even exist is because they allow you to handle errors in a smart way: You can catch them right away and handle the error. You can let them bubble up and catch them on a higher level. Or you can let them bubble up and not catch them at all, which causes the script to abort and send the error message and the stack trace to the appropriate device (the screen, a log file, the database, anything you want).

    If you replace an exception with a hard-coded die($error_message), you lose all those benefits. A die() is dumb, it simply spills the error message onto the screen, regardless of whether the application runs in your local test environment or on a live server. There's no chance of catching the error or redirecting the message to a different device, plus you lose important info like the exception class and the stack trace.

    As long as you work on your local PC, you might not really care about this. But as soon as you want to publish the site, you got a problem: If you leave the script as it is, it will greet your users with a long cryptic error message whenever something goes wrong, scaring off the legitimate users and helping the others to gain information about your system. If you want to repeair the script, you have to literally go through every single script and replace all die($error_message) with something else. And of course you must not overlook a single usage. I could hardly think of a worse job.

    So don't use die() for error handling. If you can't do anything useful with an exception, don't catch it. Just let it bubble up and do its job.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".

IMN logo majestic logo threadwatch logo seochat tools logo