SitePoint Sponsor

User Tag List

Results 1 to 15 of 15
  1. #1
    SitePoint Evangelist
    Join Date
    Nov 2009
    Posts
    471
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    dynamically creating bind_result

    In a pagination class, I use it for multiple query sets. The bind_result code as follows works fine to populate an array with the result set.

    $prep1->bind_result($venueid, $name, $address, $city, $state, $zipcode);
    $x = 0;
    while ($prep1->fetch())
    {
    $users[$x][0] = $venueid;
    $users[$x][1] = $name;
    $users[$x][2] = $address;
    $users[$x][3] = $city;
    $users[$x][4] = $state;
    $users[$x][5] = $zipcode;
    $x++;
    }

    What I would like to be able to do is pass in an array of field names and dynamically create the bind_result statement (which I would assume can be done using call_user_func_array with an array of field names starting with $. But I still need to reference those names in the while statement to populate my array. Even with $$ all I get is a literal so it is interpreting it as a string, not a field name from the result set.

    It is my understanding that in order to retrieve the result set from a prepared statement I need to bind column names and then do a fetch, so I am not allowed to process the results with a numeric array, is that correct?

  2. #2
    SitePoint Evangelist
    Join Date
    Nov 2009
    Posts
    471
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Update;

    I have half of it working but can't get the bind_result to dynamically build.
    For the fetch part, this code works fine where numcols is the number of elements in the field array and fname is the field array:

    $y = 0;
    while ($prep1->fetch())
    {
    for ($x = 0; $x < ($numcols); $x++)
    {
    $users[$y][$x] = ${$fname[$x]};
    }
    $y++;
    }

    I tried this code for the bind_result both with and without the $ signs in front of the field names.

    for ($i = 0; $i < $numcols; $i++)
    {
    $fnamew[$i] = "$" . $fname[$i];
    }
    call_user_func_array(array($prep1, 'bind_result'), $fnamew);

  3. #3
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,147
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    The issue is passing the variables by reference. From what I recall I don't think this possible. I vaguely remember attempting what your trying to do a long while back and falling short without eval. One thing you could try is to override bind_result accepting an array by reference. Than looping through it and calling parent::bind_result() to bind the reference. That may work though never tried it. You can do it with eval though if you build out the string and eval it but its pretty dirty that way.
    The only code I hate more than my own is everyone else's.

  4. #4
    SitePoint Evangelist
    Join Date
    Nov 2009
    Posts
    471
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks, I'll give it a try. I thought what I was doing would work and was able to do it with bind_param so I was surprised when it didn't work with bind_result. The messiest part of it in any event is the while loop and I was able to get that one at least. Thanks again for the input.

  5. #5
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,147
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    Well the issue is that call_user_func_array() will not unpack the array and pass the variables by reference. It is passing copies not references.
    The only code I hate more than my own is everyone else's.

  6. #6
    SitePoint Evangelist
    Join Date
    Nov 2009
    Posts
    471
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So in the bind_param, I am unpacking values, not actual variable names? I tried passing them, or at least I think I did, as ${fname1} which should assign them as variable names, right? Anyhow, if you happen to think of anything else that might work let me know but it's not that critical. It's a relatively easy workaround for that particular piece.

  7. #7
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,147
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    Take a look at the first comment on manual page here:

    http://www.php.net/manual/en/mysqli-...ind-result.php

    Assuming that is what your doing it should work.
    The only code I hate more than my own is everyone else's.

  8. #8
    SitePoint Evangelist
    Join Date
    Nov 2009
    Posts
    471
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Understand. So is there a way to take an array of strings and turn them into variable names using ${}? I think I tried every possible combination but certainly could have missed one.

    Actually I got it to create them as variables in the array but when you dump the array all you see is "" because that's the value of the variable I am assuming.

    And if the values in the array are "$fldnm" it doesn't recognize those as variable names. The "" are added by the variable dump, not by me on creation.

    Anyhow, time to move on unless someone comes up with a way. Thanks again for all your input and the discussion.

  9. #9
    Floridiot joebert's Avatar
    Join Date
    Mar 2004
    Location
    Kenneth City, FL
    Posts
    823
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    $fnamew[$i] =& $$fname[$i];

  10. #10
    SitePoint Evangelist
    Join Date
    Nov 2009
    Posts
    471
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great! That works. Thanks for the input.

  11. #11
    Floridiot joebert's Avatar
    Join Date
    Mar 2004
    Location
    Kenneth City, FL
    Posts
    823
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I had the same sort of problems with bind_param a few months ago.

    I have a bad feeling that the situation with prepared statements and call_user_func_array needing references is going to have people inadvertently creating bugs in their applications based on references, or worse yet, security holes that are a nightmare to track down.

    Be careful.

  12. #12
    SitePoint Evangelist
    Join Date
    Nov 2009
    Posts
    471
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Would you expound on that a little bit.

    My bind_param statement is

    call_user_func_array(array($prep1, 'bind_param'), $bind_param);

    with the $bind_param passing an array of values, i.e. strings and integers with the [0] element being a string "sssii" for example. Where would the trouble arise?

  13. #13
    SitePoint Evangelist
    Join Date
    Nov 2009
    Posts
    471
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    One more note, I am only using the dynamic bind_param for the WHERE or JOIN ON clause in select statements. Any direct manipulation of the database is done in long hand.

  14. #14
    Floridiot joebert's Avatar
    Join Date
    Mar 2004
    Location
    Kenneth City, FL
    Posts
    823
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The trouble would come from the fact that bind_param and friends expect to recieve arguments by reference and that the list of variable names that will be referenced is determined at runtime.

    Bugs could arise if any of the variable names are generated, rather than pulled from a hard-coded list. Especially if the generation has any sort of user input as generation input.

    By bugs, I mean that previously created variables could be overwritten by bind_result and unexpected variables could inadvertently be pulled into a query by bind_param.

    For an example of an overwrite bug, check out this pair of loops

    Code:
    for($i = 0; $i < 100; $i++)
    {
    	for($i = 0; $i < 50; $i++)
    	{
    	
    	}
    }
    Because the inner loop keeps resetting $i, the loop would run indefinitely. While a bind_result bug probably wouldn't leave anything running in an infinite loop, it might overwrite something that's used to build a later variable and cause unexpected output.

  15. #15
    SitePoint Evangelist
    Join Date
    Nov 2009
    Posts
    471
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I understand the loop issue and I think I understand your point with the bind_result and bind_param generation of variable names but will spend some more time with this to make sure.

    And you make a very good point that there is the possiblity for problems here if you are not careful and your input there is most valuable. I will be careful in how the names are used and where all this is used.

    Thanks again for the discussion.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •