undefined function???

Topics: Developer Forum, User Forum
Feb 20, 2012 at 11:09 PM
Edited Feb 20, 2012 at 11:11 PM

a script that has been working for MONTHS has now been throwing this error:

Call to undefined method PHPExcel_Reader_CSV::setReadDataOnly()

Any ideas?

Here's the code:


    set_include_path(get_include_path() . PATH_SEPARATOR . 'PHPExcel/Classes/'); 
    require_once 'PHPExcel/Classes/PHPExcel.php';
    require_once 'PHPExcel/Classes/PHPExcel/IOFactory.php';
    $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_discISAM;
    $objReader = PHPExcel_IOFactory::createReaderForFile($file);
    $objPHPExcel  = $objReader->load($file);
    $objWorksheet = $objPHPExcel->getActiveSheet();

Feb 21, 2012 at 8:55 AM

maybe you always gave the script some xls file, now you are trying to give a csv file and for csv files read data only method does not exist.

Feb 21, 2012 at 11:08 PM

The PHPExcel_Reader_IReader interface identifies the methods that are required by all readers: literally just the canRead() and load() methods. All other methods are specific to the readers themselves (i.e. SYLK and CSV are "single sheet" formats, so there is no purpose in having a listWorksheetNames() method in those classes; and CSV cannot hold formatting information, so having a setReadDataOnly() method would be meaningless in that class.

Just because the file has an .xls extension, doesn't mean it's a BIFF5 file, so using identify is a good safeguard against rogue files.

It is possible to use the IOFactory's identify() method to return the reader that will be used for a file, instantiate that reader, and change any appropriate settings.

$inputFileName = './sampleData/example1.xls';
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
// Set any $objReader configuration here, as identified by $inputFileType
$objPHPExcel = $objReader->load($inputFileName);
Feb 22, 2012 at 3:03 PM

I was just about to ask how to tell which reader was created. Thanks, Mark.

Feb 22, 2012 at 3:05 PM
Edited Feb 22, 2012 at 3:07 PM

What are the values returned by identify() so that I can call setReadDataOnly() for BIFF5 files?

Actually, I may just call my CSV importer when it is a CSV file with an XLS extension.

Feb 22, 2012 at 4:02 PM

Here's an example of how I detect the file type.


// readSpreadsheetData()
//                       $FileName (String): File Name
public function readSpreadsheetData($FileName) {
  $this->data = array();

  if (empty($FileName)) {
    throw new Exception("No file specified.");

  if (!file_exists($FileName)) {
    throw new Exception("Could not open " . $FileName . " for reading! File does not exist.");

  try {
    $FileType = PHPExcel_IOFactory::identify($FileName);
    $SpreadsheetReaderObj = PHPExcel_IOFactory::createReader($FileType);
    switch ($FileType) {
      case 'Excel2007':
      case 'Excel2003XML':
      case 'Excel5':
      case 'OOCalc':
      case 'SYLK':
      case 'CSV':

    // Get worksheet information.
    $WorksheetListInfo = $SpreadsheetReaderObj->listWorksheetInfo($FileName);

    // Estimate maximum chunk size based on system memory.
    $MemoryLimit = $this->getMemorySizeAsBytes();
    $BufferFactor = 1; 
    $RowMemory = (1024 * 1) * $WorksheetListInfo[0]['totalColumns'];
    $MaxChunkSize = max(intval(($MemoryLimit / $BufferFactor) / $RowMemory), 100);

    $ReadFilter = new ReadFilter();

    foreach ($WorksheetListInfo as $WorksheetIndex => $WorksheetInfo) {
      // Worksheet Id may be used for identifying specific record.
      $WorksheetId = $WorksheetIndex + 1;

      // If chunk size > total rows in sheet reduce chunk size to total rows.
      $ChunkSize = ($MaxChunkSize < $WorksheetInfo['totalRows'])
                 ? $MaxChunkSize
                 : $WorksheetInfo['totalRows'];

      // Configure read filter.
      $ReadFilter->setColumns($this->getColumnRange('A', $WorksheetInfo['lastColumnLetter']));

      for ($StartRow = 1; $StartRow <= $WorksheetInfo['totalRows']; $StartRow += $ChunkSize) {

        $SpreadsheetObj = $SpreadsheetReaderObj->load($FileName);

        $WorksheetObj = $SpreadsheetObj->getActiveSheet();
        foreach ($WorksheetObj->getRowIterator() as $RowObj) {
          $RowId = $RowObj->getRowIndex();
          if ($RowId > $ChunkSize) {

          $SheetRowId = $StartRow + $RowId - 1;
          if ($SheetRowId > $WorksheetInfo['totalRows']) {

          $RecordId = "{$WorksheetId}-{$SheetRowId}";
          $this->data["{$RecordId}"] = array(); // array() represents column data.
  } catch (Exception $ExceptionObj) {
    // Exception Error Handling

Feb 22, 2012 at 5:34 PM

@schir1964 Nice little block of code demonstrating how to use identify and the switch for special reader settings, and all wrapped in a nice try/catch block as well.... a perfect example for any future reference. (wishing Codeplex would let me bookmark postings)

Feb 23, 2012 at 2:42 AM
Edited Feb 23, 2012 at 2:44 AM

Will the processing work exactly the same with any type of the files?

We wrote the code to work only on Excel files, not CSV. We use another class for processing the CSV files.

If this is so, I may just use PHPExcel to process them, too.

Have any of the memory issues been settled since 1.7.3c which is what I have installed now. That being said, we have had problems with memory exhaustion on large spreadsheets before. Does the snippet above help with that issue?

Feb 23, 2012 at 4:42 PM
Edited Feb 23, 2012 at 4:52 PM

The snippet above comes from this thread (http://phpexcel.codeplex.com/discussions/259971)  where I customized the reader files with a new listWorksheetInfo method that returns information about the worksheets without loading the actual data of the file.

This allowed my code to be written to adjust the reading so that the memory is never exhausted (but it does take a little longer to read large files).

Anyway, the new methods and full example code of how to use the read filters is in that thread above.

Also, Mark Baker is planning on incorporating the listWorksheetInfo method into the next release of the software so the customized code will become standard (which is a cool thing in and of itself).


Note: I use this code to allow customers to upload their data with the file types listed. The actual program will read in the first 10 to 15 lines of the first worksheet and display it as a sample of their data. The web form then lets them pick the appropriate columns and match them to the appropriate data types that the program needs. Then the program reads in all the data based on the selections of the customer. This way we don't have to enforce a specific format or column order from the customer who may or may not be savvy in editing files. After a few bumps in the code it has been refined to the point that we don't have any complaints from the customers uploading their data and we don't have to dedicate time/effort for converting or loading their data for them.


- Christopher Mullins