3

Is it possible to return a loop? not the result but the loop it self. I want to create a function in php. For example like this.

function myloop($sql){
$query = mysql_query($sql);

return while(mysql_fetch_assoc($query))
}

The reason i want to create this is for me to avoid repeating code. Anyone can help me? Thank you..

Alessandro Minoccheri
  • 35,521
  • 22
  • 122
  • 171
thenewbie
  • 755
  • 19
  • 40
  • 6
    Why the downvotes? Ok, the question was not the highest quality, but has a good intent - reducing code duplication. Just the idea was not good, but I think this question can arise in many more people too, and providing a good answer to it can be heplful in the future. – ppeterka Oct 19 '12 at 06:55
  • @GolezTrol nice to see we had the same on our minds :) – ppeterka Oct 19 '12 at 07:01

7 Answers7

5

No, but you can simulate that with an Iterator for stable released PHP as of today. In PHP 5.5 there will be generators that is close, too.

$lazyQuery = new SqlResultItertor($sql);
foreach ($lazyQuery as $assoc) {
    $assoc; # the result, one per row
}

BTW: PDO and MySqli offer this already out of the box (not lazy query, but the result is traversable), for mysql you need to write such an iterator-result object your own.

For some mysql_* functions related code, see this answer. However the general suggestion as of today is to use PDO or mysqli instead, those offer more out of the box. See How to successfully rewrite old mysql-php code with deprecated mysql_* functions?

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
  • I will try this. I am much more familiar with mysql. But thanks for the tip – thenewbie Oct 19 '12 at 07:13
  • @thenewbie: You might find this helpful then: http://www.php.net/manual/en/mysqli.quickstart.dual-interface.php - however about the benefits you ask with your question, you want to have an object oriented interface. Mysqli and PDO will help you to not write that much code for that (in the end). – hakre Oct 19 '12 at 07:14
3

No, you can't. You can pass a function to a function, though:

// The myloop function, with another name.
function query($sql, $rowcallback)
{
  $query = mysqli_query($sql); // use mysqli, not mysql
  while 
    ( ($row = mysql_fetch_assoc($query)) &&
      call_user_func($rowcallback, $row) );
}

// The code to process a row.
function processRow(array $row)
{
   // Use your row here..
   var_dump($row);

   return true; // You can return false to break processing.
}

//calling:
query($yourSelf, 'processRow');

Instead of passing the function by name, you can also use anonymous functions, depending on your php version:

//calling:
query($yourSelf, 
  function(array $row)
  { 
    var_dump($row); 
    return true; // You can return false to break processing.
  });

The function which is called from the callee is often called a callback. call_user_func is the best way to call a callback, since it will also accept methods and static methods, not just functions, so you're more flexible.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
1

No, it isn't.

You can return a function to does nothing but run a loop, but you can't return the loop itself.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

No.

You could, for instance, return an anonymous function which may contain a loop, but you can only return values from functions, not language constructs.

deceze
  • 510,633
  • 85
  • 743
  • 889
1

You should turn it inside out!

Instead of returning the loop, you could do it this way using Variable functions :

function myloop($sql, $myFunction){ 
    $query = mysql_query($sql);  
    while(mysql_fetch_assoc($query)) {
        $myFunction($result);
    }

} 


function doSomethingWithTheResult($result) {
   echo $result; // just to have something here...
}

//now the usage:
myloop("SELECT 1", 'doSomethingWithTheResult');

With a squint, this is similar to the concept of the Template method OOP design pattern.

ppeterka
  • 20,583
  • 6
  • 63
  • 78
1

No, but you could do

function loopdate($sql,$code)
{
 $query=mysql_query($sql)
 while (mysql_fetch_assoc($query))
 {
  eval($code);
 }
}

However - eval is rediculously dangerous its really really discouraged.

function loopdate($sql,$function)
{
 $query=mysql_query($sql)
 while ($data=mysql_fetch_assoc($query))
 {
  $function($data);
 }
}

would be better.

myfunc($data)
{
 foreach ($data as $key->$value)
 {
  print "<tr><td>".$key."<td><td>".$value."</td></tr>\n";
 }
}

So you can call

loopdate("select * from mytable","myfunc");
BugFinder
  • 17,474
  • 4
  • 36
  • 51
0

In PHP 5.5+ it is possible, using the yield keyword instead of return (this is called a generator):

function myloop($sql) {
    $query = mysql_query($sql);
    while (($row = mysql_fetch_assoc($query))) {
        yield $row;
    }
}

foreach (myloop('SELECT * FROM foo') as $row) {
    // do something with $row
}

This is not much different from what you could do with iterators in older PHP, but the code is much cleaner.

Tgr
  • 27,442
  • 12
  • 81
  • 118