2

Im looking for a way to export to a csv on the fly and came accross this.

    $list = array (
                   array('aaa', 'bbb', 'ccc', 'dddd'),
                   array('123', '456', '789'),
                   array('"aaa"', '"bbb"')
                   );
    $fp = fopen('path_to_file/file.csv', 'w');

    foreach ($list as $fields) {
        fputcsv($fp, $fields);
    }

    fclose($fp);

Its just the basic code taken from the php.net page. Anyway i stuck it in to try it our before using it for my own needs. But i keep getting the following errors.

PHP Warning:  fopen(path_to_file): failed to open stream
fputcsv() expects parameter 1 to be resource, boolean given
fclose() expects parameter 1 to be resource, boolean given

I'm unsure why the fopen() error is appearing as i want it to just create a new file on the fly anyway, which was what i thought it done anyway?

Is it safe to assume that this is a file permission error?

Also since im using the exact code from the php.net page im assuming the other errors are displaying because of the fopen() issue.

EDIT.

It seems like i might be better to post some more info.

The classes involved.

 class transData{
var $connection;
var $date;
var $data;

function __construct($date){
    $this->date = $date;
    return;
}

function getData(){ //this method just pulls the results of the query and returns them as an array
    global $connection;
    $date=$this->date;

    //get num row for each date/fromfile combo, one with the most should be the most uptodate.
    // count(fromfile) for specific date, one with most will be the most up to date, if more than one then take the one with highest appended int
    $count=array();
    $x=0;
    $mysqli_result=$connection->query("select fromfile,count(fromfile) from transdata where soldtime like '%".$date."%' group by fromfile");
    while($row=$mysqli_result->fetch_row()){
        $count[$row[0]]=$row[1];
    }
    $mysqli_result->free();
    //got the data in array, now rearrange to get one with highest count
    arsort($count);
    $fromFile=key($count);


    $temp=array();
    $x=0;
    $mysqli_result=$connection->query("select * from transdata where soldtime like '%".$date."%' and fromFile='".$fromFile."' order by soldtime desc");
    while($row=$mysqli_result->fetch_row()){
        $temp[$x]['id']=$row[0];
        $temp[$x]['departure']=$row[1];
        $temp[$x]['type']=$row[2];
        $temp[$x]['typeText']=$row[3];
        $temp[$x]['price']=$row[4];
        $temp[$x]['soldTime']=$row[5];
        $temp[$x]['dateAdded']=$row[6];
        $temp[$x]['fromFile']=$row[7];
        $x++;

    }
    $this->data = $temp;
    $mysqli_result->free();
    return;
}




function dayTotal($noDays){
    //$list=array();
    $html="<table class=\"paxdata\">";

    $html.="<tr><th>Day</th><th>Date</th><th>No. Sold</th><th>Total Price(£)</th><th></th></tr>";
    //$list=array('Day','Date','No. Sold','Total Price(£)');
    //build list of dates to work with
    $inc=0;
    $hours=array();$hours[0]=0;$hours[1]=24;$hours[2]=48;$hours[3]=72;$hours[4]=96;$hours[5]=120;$hours[6]=144;$hours[7]=168;

    while($inc!=$noDays){

        $date=date('Y/n/j',time() - 60 * 60 * $hours[$inc]);        //format for calling class transData()
        $formatDate=date('Y-m-d',time() - 60 * 60 * $hours[$inc]);  //format for displaying date in table
        $day=date('l',time() - 60 * 60 * $hours[$inc]);             //text day name

        $link=explode('/',$date);

        //call to this class to get all the data for us
        $getData = new transData($date);
        $all = $getData->getData();
        $stuff = $getData->data;        

        $x=0;$price=0;
        foreach($stuff as $v){
            $price=$price+$v['price'];
            $x++;

        }
        $totalSold=$totalSold+$x;
        $totalPrice=$totalPrice+$price;

        $checkOdd=new numeric();
        $odd=$checkOdd->is_odd($inc);
        if($odd==1){$html.="<tr class=\"odd\">";}else{$html.="<tr class=\"even\">";}
        $html.="<td width=\"100px\">".$day."</td><td width=\"100px\">".$formatDate."</td><td>".$x."</td><td>".fixedToFloat($price)."</td><td><a href=\"index.php?module=chooseDate&year=$link[0]&month=$link[1]&day=$link[2]\">More info?</a></td></tr>";
        //$list=array($day,$formatDate,$x,$price);
        $inc++;
    }
    $html.="<tr><td></td><th>Totals:</th><th>".$totalSold."</th><th>".fixedToFloat($totalPrice)."</th></tr>";
    $html.="</table>";
    echo $html;


    $list = array (
                   array('aaa', 'bbb', 'ccc', 'dddd'),
                   array('123', '456', '789'),
                   array('"aaa"', '"bbb"')
                   );
    $fp = fopen('~/file.csv', 'w');
    if ($fp != false){
        foreach ($list as $fields) {
            fputcsv($fp, $fields);
        }
    }
    fclose($fp);

}

  }

Called by this via the browser.

$date=date('Y/n/j');

$getData = new transData($date);
$all = $getData->getData();
$getData->dayTotal(7);

The response in /var/log/system.log

   PHP Notice:  Undefined variable: totalSold in /Users/me/Sites/KF/sales/specificClasses.php on line 218
   PHP Notice:  Undefined variable: totalPrice in /Users/me/Sites/KF/sales/specificClasses.php on line 219
   PHP Warning:  fopen(~/Sites/KF/file.csv): failed to open stream: No such file or directory in /Users/me/Sites/KF/sales/specificClasses.php on line 238
   PHP Warning:  fclose() expects parameter 1 to be resource, boolean given in /Users/me/Sites/KF/sales/specificClasses.php on line 244
cosmicsafari
  • 3,949
  • 11
  • 37
  • 56
  • Is `path_to_file` really in your error message? Do you have such a directory? – Mat May 01 '12 at 11:24
  • no path_to_file was just to illustrate that there was a file path – cosmicsafari May 01 '12 at 11:32
  • -1 and voting to close for posting **truncated** error message, while **omitted part contains the actual explanation** – Your Common Sense May 01 '12 at 11:37
  • 1
    `Anyway i stuck it in to try it our before using it for my own needs` - what are your own needs? If you want to provide a CSV file for download, you don't need to be able to write to a local file anyway. – DaveRandom May 01 '12 at 11:42
  • I am pulling data from a DB then using various php classes to rearrange it and get it into a format for displaying on the page. I also wanted to create a csv which contained the same data which was being displayed on the page. – cosmicsafari May 01 '12 at 11:53
  • If you want to generate and cache them, you will need to check permissions, it seems to be the most likely cause of your current problem. But if would be better to generate the CSV files only when they are requested for download, otherwise you will have to implement some form of garbage collection - you don't want to keep pointless old files building up on your server. – DaveRandom May 01 '12 at 11:59
  • 1
    @DaveRandom he need to check the error message! **The whole darn error message it is!**. – Your Common Sense May 01 '12 at 12:01
  • Even copy-pasting code requires some common sense. – Salman A May 01 '12 at 12:18
  • Im sorry what is it that i have done wrong exactly? – cosmicsafari May 01 '12 at 13:24
  • I ended up just scrapping this idea and stuck the php code that produces the csv into a seperate file and it seems to be working fine now. Could it possibly be that because i was attempting to create a csv on the file from browser executed code. – cosmicsafari May 01 '12 at 15:19

2 Answers2

5

From PHP.net docs for fopen:

Return Values

Returns a file pointer resource on success, or FALSE on error.

Either your code can't find "path_to_file/file.csv", or your web server (or CLI) doesn't have permission to write there.

Community
  • 1
  • 1
Michel Carroll
  • 462
  • 2
  • 9
  • I tried a few different folder locations and had the same errors with each. Could it be due to attempting to produce a csv using a browser request? – cosmicsafari May 01 '12 at 11:33
  • 2
    most likely the directory `path_to_file` isn't existing. While `fopen()` can create new files it doesn't create new directories. – s1lence May 01 '12 at 11:33
1

i don't know your exact settings, but most often it's permission issue. fopen returns FALSE, if it cannot open or create the file and that's your "boolean" problem. try to set rights 777 on "path_to_file" folder and then try to run your script again

also you should check fopen's return value, before trying to manipulate with your file, something like

$fp = fopen('path_to_file/file.csv', 'w');
if ($fp != false){
    foreach ($list as $fields) {
        fputcsv($fp, $fields);
    }

    fclose($fp);
}
Kousalik
  • 3,111
  • 3
  • 24
  • 46
  • Don't bet. Programming is not gambling. – Your Common Sense May 01 '12 at 11:38
  • :D:D ok funny comment, but nonsense. If I get acces to his ftp or wherever he is trying to make it work, i will be 100% sure, until than, everyone can just gues. And by the way, permissions aren't programming issue, and that's the reason NOBODY of us can be 100% sure, bye – Kousalik May 01 '12 at 11:42
  • Funny comment but sadly illiterate. You don't need FTP access but a little knowledge only. To let you know, there is a thing called "error message". Which is pretty informative and unambiguous in determining the error cause. So, a programmer should debug, not gamble. Go figure. – Your Common Sense May 01 '12 at 11:44
  • yes, error message can move you forward, but can be caused by more things. From this one, you know only, that the file wasn't opened. And it could be from more reasons. And it doesn't change anything at all on that, he should check the return value. – Kousalik May 01 '12 at 11:49
  • This one was truncated for some reason by the opening poster. You have to beat him up until he deliver the rest, not gamble anyway. – Your Common Sense May 01 '12 at 11:50
  • 1
    ok, next time i would choose my words carefully. althoug as i see, only me gave him some tip, how to solve it :) (PS.: edited my answer and now am I not betting :) – Kousalik May 01 '12 at 12:01