views:

30

answers:

2

I have code in php such as the following:

while($r = mysql_fetch_array($q))
{

// Do some stuff

}

where $q is a query retrieving a set of group members. However, certain groups have there members saved in memcached and that memcached value is stored in an array as $mem_entry. To run through that, I'd normally do the following

foreach($mem_entry as $k => $r)
{

// Do some stuff

}

Here's the problem. I don't want to have two blocks of identical code (the //do some stuff section) nested in two different loops just because in one case I have to use mysql for the loop and the other memcached. Is there some way to toggle starting off the loop with the while or foreach? In other words, if $mem_entry has a non-blank value, the first line of the loop will be foreach($mem_entry as $k => $r), or if it's empty, the first line of the loop will be while($r = mysql_fetch_array($q))

Edit

Well, pretty much a few seconds after I wrote this I ended up coming with the solution. Figure I'd leave this up for anyone else that might come upon this problem. I first set the value of $members to the memcached value. If that's blank, I run the mysql query and use a while loop to transfer all the records to an array called $members. I then initiate the loop using foreach($members as as $k => $r). Basically, I'm using a foreach loop everytime, but the value of $members is set differently based on whether or not a value for it exists in memcached.

+3  A: 

Why not just refactor out doSomeStuff() as a function which gets called from within each loop. Yes, you'll need to see if this results in a performance hit, but unless that's significant, this is a simple approach to avoiding code repetition.

If there's a way to toggle as you suggest, I don't know of it.

Sid_M
The doSomeStuff section is around 600 lines of code and would have to set around 9 variables to global scope to be run as a function, 3 of which are mysql links. This situation occurs multiple times. Running it as a function would be too detrimental to performance.
Wow. I was trained that a function should be short enough to fit on one's screen. Maybe it has to be different for interpreted code, but it's hard for me not to think that you might be happier after some refactoring.
Sid_M
Also, rather than globalizing variables, you could pass a data object to doSomeStuff(). If you need doSomeStuff to set a bunch of variables, you could have it return a data object. If it needs to get and set a bunch of variables, you could pass in a data object by reference. (To be clear, in php a data object could just be an array.)
Sid_M
Obviously, I don't know your code, so these are just suggestions. I'm sorry if they're not helpful.
Sid_M
A: 

Not the ideal solution but i will give you my 2 cents. The ideal would have been to call a function but if you dont want to do that then, you can try something like this:

if(!isset($mem_entry)){
 $mem_entry = array();
 while($r = mysql_fetch_array($q))
 {

   $mem_entry[] = $r;

 }
}

The idea is to just use the foreach loop to do the actual work, if there is nothing in memcache then fill your mem_entry array with stuff from mysql and then feed it to your foreach loop.

Sabeen Malik
I literally just finished updating my post saying to do the same thing. It just hit me that I should modify the array rather than the loop :) I marked this as the right answer since it includes the code. Thank you.