Solved

Unable to return an array from a function

Posted on 2004-04-29
8
350 Views
Last Modified: 2008-02-26
Sorry to post a large block of code, but I'm new to php (started last week) and am totally stumped.  What I have is a CSV file that needs to be scanned for a value stored in the second column, then use the data in the other columns to make a table, with the total size depending on the value in first column.  The variable "id" is passed in the URL and generated by the linking page.  the function works, and finds what its supposed to, but the return doesn't seem to work.  I think $data2 is empty, since it is using "case 0" in the switch block.

For example: a line from book2.csv (spaced added for ease of reading):
3 , il10 , IL-10 , oIMR0086 , GTG , oIMR0087 , GCC , endogenous IL-10 , oIMR0088 , CCT , 2 , mutant IL-10

I know I should probably use mySQL (or comparable), but I have 2 whole databases of maybe 20 lines each...

Below is the code I'm using right now; a couple of notes about this:
HTML has been stripped off for space
There are some lines that are strictly for debugging, and commented as such
I am using the install of Apache that comes with OS 10.2, with php enabled
I apologize for my mess.

<?php

$id1 = $_GET["id"] ;  //var "id" passed in URL

function scanarray ($file, $arg) {
echo "function called <hr>" ; //debug
  $file0 = fopen($file, 'r') ;
  while (($data0 = fgetcsv($file0, 2000)) != FALSE) {
    if ($data0[1] == $arg) {
      echo "$data0[2] primers found<hr>" ; //debug
    }
  }
  fclose($file0) ;
  return $data0;
}

$data2= scanarray('book2.csv',$id1) ;
switch ($data2[0]) {
  case 0: //no primers used
    echo "<p align=center> There are no primers available</p>" ;
    break;
  case 1: //multiple, start yanking primer sets
    for ($i ; $i<=$data2[0] ; $i++) {
      echo "<hr>" ;
    }
    break;
  case 2: //normal
    echo "<table border=\"5\" cellpadding=\"10\" align=center> \n <tr>" ; //establish table
    echo "<td> $data2[3] </td> <td> <code> $data2[4] </td> <td> with $data2[5] amplifies $data2[7] </tr> \n" ; //write first primer name, seq, and amp
    echo "<td> $data2[5] </td> <td> <code> $data2[6] </td> <td> with $data2[3] amplifies $data2[7] </tr> \n" ; //write 2nd name, seq, amp
    echo "</table> <br> <hr>" ; //end table
    break;
  case 3: // wt and null
    echo "<table border=\"5\" cellpadding=\"10\" align=center> \n <tr>" ; //establish table
    echo "<td> $data2[3] </td> <td> <code> $data2[4] </td> <td> with $data2[5] amplifies $data2[7] </tr> \n" ; //write first primer name, seq, and amp
    echo "<td> $data2[5] </td> <td> <code> $data2[6] </td> <td> with $data2[3] amplifies $data2[7] </tr> \n" ; //write 2nd name, seq, amp
    echo "<tr> <td> $data2[8] </td> <td> <code> $data2[9] </code> </td>" ; //write name, seq
    $tempval = $data2[10]*2+1 ; //reference
    echo "<td> with $data2[$tempval] amplifies $data2[11] </td> </tr> \n"; //write which and amp
    echo "</table> <br> <hr>" ; //end table
    break;
  default:
    echo "<b>Invalid argument</b>" ;
  } //end switch
?>
0
Comment
Question by:Adam Mason
  • 4
  • 4
8 Comments
 
LVL 6

Expert Comment

by:andreif
ID: 10953888
$data0 is local variable within while() {} structure, so it's empty after while ended

if you want to return $data0 as soon as you found it, try

 while (($data0 = fgetcsv($file0, 2000)) != FALSE) {
    if ($data0[1] == $arg) {
      echo "$data0[2] primers found<hr>" ; //debug
      fclose($file0) ;
      return $data0;
    }
  }
0
 

Author Comment

by:Adam Mason
ID: 10954067
Huh.... don't remember seeing that anywhere in the documentation.  Need new glasses I guess.

What I originally had was a search for all instances of $arg in the "database" since some things had more than 1 row to be displayed, but I've changed that now, so yours should work.

Follow-up question:

could I declare $data0 empty, eg:
   $data0 = array() ;
at the beginning of the function and let it be changed by the function and then returned at the end of the search?

So on all the loops (eg "for") variables declared inside them are local? Or is it only when you declare them as part of the loop as I did w/ $data0.
0
 

Author Comment

by:Adam Mason
ID: 10954088
And as a further note... the only programming I've done before this was High School writing Pascal... so I probably write code funny.
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 6

Expert Comment

by:andreif
ID: 10954106
Loop variables are local and function variables are local. So

function Blah () {

}
0
 
LVL 6

Accepted Solution

by:
andreif earned 300 total points
ID: 10954199
Just tried to run this code:

function Blah () {
  $a='function';
  $i=0;
  while($i<3) {
    $i++;
    print "cycle: a=$a; i=$i<br>";
  }
  print "function: a=$a; i=$i<br>";
}

$a = 'global';
$i = 'global';

print "start: a=$a; i=$i<br>";
Blah();
print "end: a=$a; i=$i<br>";


Got results:

start: a=global; i=global
cycle: a=function; i=1
cycle: a=function; i=2
cycle: a=function; i=3
function: a=function; i=3
end: a=global; i=global

as you see, $a is local inside the function, but looks like $i is Ok after while ended. So, I confused you a bit, sorry. It's just my habit do not use cycle variable outside the cycle :)

Ok, problem with your code may be that you use $data0 =  fgetcsv()
when  fgetcsv() runs out of lines it will return FALSE and $data0 will get it. Well, FALSE is almost equal empty string. Anyway, it's not an array, or, possibly, empty array. Point is that data0 is last value returned by fgetcsv() , and that's not what you need. If you change code this way, it will work:

function scanarray ($file, $arg) {
echo "function called <hr>" ; //debug
  $file0 = fopen($file, 'r') ;
  while (($data0 = fgetcsv($file0, 2000)) != FALSE) {
    if ($data0[1] == $arg) {
      echo "$data0[2] primers found<hr>" ; //debug
      $myData = $data0;
    }
  }
  fclose($file0) ;
  return $myData;
}

if you have multiple lines which could match, you will need something like

function scanarray ($file, $arg) {
echo "function called <hr>" ; //debug
  $file0 = fopen($file, 'r') ;
  while (($data0 = fgetcsv($file0, 2000)) != FALSE) {
    if ($data0[1] == $arg) {
      echo "$data0[2] primers found<hr>" ; //debug
      $myData[] = $data0;
    }
  }
  fclose($file0) ;
  return $myData;
}

and now, returned value will be array of arrays :)
try print_r($myData); after function call to see what you got there
0
 

Author Comment

by:Adam Mason
ID: 10954362
I've been tinkering with it and I think I've got it now.
In the above example you called Blah, but that looks like a procedure call (with no arguments) to me, not a "true" function... Am I right?
0
 
LVL 6

Expert Comment

by:andreif
ID: 10954433
well, in Pascal it used to be some difference between function and procedure - I remember that :)
But not in PHP.
You can have function with or without arguments, it may return value and may not.
Even when it returns something, you can ignore that and call it as procedure, you just miss the returned value then
0
 

Author Comment

by:Adam Mason
ID: 10954486
Great... thanks for the quick help.  I'll probably need more later, but that pretty much sums it up for me.
0

Featured Post

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
Build an array called $myWeek which will hold the array elements Today, Yesterday and then builds up the rest of the week by the name of the day going back 1 week.   (CODE) (CODE) Then you just need to pass your date to the function. If i…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question