Having a Function Inside of the Loop

I am trying to make a frontend product editor for WooCommerce, and have a loop that returns all of the products for the current user. I am trying to use gravity forms as the editor, so a single gravity form is displayed and populated for each product. However, I am not sure how to handle naming the function so it is not being re-declared for every product.

global $current_user;
new WP_Query( array( 'author' => $current_user->ID, 'post_type' => 'product' ) );
while ( have_posts() ) {
    the_post();
    add_filter('gfrom_pre_render_7', 'populate_each_product');
    function populate_each_product ($form){
        foreach($form["fields"] as &$field){
            if($field["id"] == 1){
                $field["defaultValue"] = get_post_meta($post->ID, '_virtual', true);
            }
        }
        return $form;
    }
}
wp_reset_query();
?>

Is there someway to add a counter or another variable to the function name? So along the lines of populate_each_product . $post->ID () or something of that nature? I have looked around for this quite a bit, but found no reference of using functions inside loops so I am worried what I am trying to do is not possible

Solutions Collecting From Web of "Having a Function Inside of the Loop"

Before continuing, please read this:

http://www.slideshare.net/andrewnacin/you-dont-know-query-wordcamp-netherlands-2012

It’s by a core WordPress developer and you should consider it required reading. You should never use query_posts, and it’s important to understand how to use loops correctly. That presentation will demonstrate the best practices, how, and why to use them.

I can see the approach you’ve taken, what you’re trying to do is:

foreach post that's of type product that belongs to me
    add a function that fills in the default value for that post

Unfortunately, that filter is fired for all posts, not individual posts. Also your approach is using a named function, if it were javascript and you were using lambdas and it was a per post filter, e.g. ‘gfrom_pre_render_’.$post->ID it might work, but that filter doesn’t exist, and you’re not using lambdas.

So instead, add your function to the filter, and it will get executed on all forms. Then filter out so that it only happens on the ones that you want:

add_filter('gfrom_pre_render_7', 'populate_each_product');
function populate_each_product ($form){
    global $post, $current_user;
    if($post->post_type == 'product' && $post->post_author == $current_user->ID){
        foreach($form["fields"] as &$field){
            if($field["id"] == 1){
                $field["defaultValue"] = get_post_meta($post->ID, '_virtual', true);
            }
         }
    }
    return $form;
}

Also this is how you would have done the query correctly:

$q = new WP_Query( array( 'author' => $current_user->ID, 'post_type' => 'product' ) );
if ( $q->have_posts() ) {
    while ( $q->have_posts() ) {
        $q->the_post();
    }
    wp_reset_postdata();
}

Don’t add the filter inside the loop. Put the code in functions.php, and use get_posts to get the products and populate the form.