Difference between #2 and #1 of How to use PHPExcel external library with Yii

unchanged
Title
How to use PHPExcel external library with Yii
unchanged
Category
How-tos
unchanged
Tags
yii, libraries
changed
Content
Trying to learn and help some other programmers to find their solutions on the
[Yii Forum](http://www.yiiframework.com/forum "Yii Forum") (I think is
a superb way to learn the framework), I was facing one challenge with an
external library that a fellow programmer wanted to use -quite good indeed:
[PHPExcel](http://phpexcel.codeplex.com/ "PHPExcel"). And what is
PHPExcel?  

<h4>PHPExcel - OpenXML - Create Excel2007 documents in PHP - Spreadsheet
engine</h4>
<blockquote>Project providing a set of classes for the PHP programming
language,  which allow you to write to and read from different file formats,
like  Excel 2007, PDF, HTML, ... This project is built around Microsoft's 
OpenXML standard and PHP.

Checkout the [Features](http://phpexcel.codeplex.com/wikipage?title=Features
"PHPExcel") this class set provides, such as setting spreadsheet meta
data (author,  title, description, ...), multiple worksheets, different fonts
and font  styles, cell borders, fills, gradients, adding images to your 
spreadsheet and much, much more!</blockquote>  

<h2>The Challenge</h2>
The fellow programmer ([Jack
Fiallos](http://www.yiiframework.com/forum/index.php?/user/2698-jack-fiallos/
"Jack Fiallos")) had a problem of using the libraries within Yii. He
was surprised that he could easily use the libraries outside of the framework
but not within the framework itself. At first we didn't think about it but
suddenly we thought about the autoloading features of Yii and looked into the
guts of PHPExcel to find out what was causing the problems.

We were right, PHPExcel has an autoloading feature itself that when a classes is
called (i.e. PHPExcel_Shared_ZipStreamWrapper) the first part of the name is
actually reflecting the folder's path where the class is located (i.e.
PHPExcel_Shared_ZipStreamWrapper = PHPExcel/Shared_ZipStreamWrapper.php). Please
review the following code (extracted from PHPExcel_Autoloader class):


~~~
[php]
public static function Load($pObjectName){
    if ((class_exists($pObjectName)) || (strpos($pObjectName, 'PHPExcel') ===
False)) {
       return false;
    }
    // this is the code that shows what I am saying
    $pObjectFilePath =  PHPEXCEL_ROOT.
          
str_replace('_',DIRECTORY_SEPARATOR,$pObjectName).'.php';str_replace('_',DIRECTORY_SEPARATOR,$pObjectName).'.php';

           ifif ((file_exists($pObjectFilePath) === false)
||
       || (is_readable($pObjectFilePath) === false)) {
		return false;
           }
	require($pObjectFilePath);}
     require($pObjectFilePath);
}	//	function Load()

~~~

<h2>Solution</h2>
The workaround to this problem (at least the one I know) is by making use of the
 [spl_autoload_register](http://php.net/manual/en/function.spl-autoload-register.php
"spl_autoload_register") and
[spl_autoload_unregister](http://www.php.net/manual/en/function.spl-autoload-unregister.php
"spl_autoload_unregister") PHP's functions. The following code shows
how we got the library working -I assume that you have [downloaded the
PHPExcel](http://phpexcel.codeplex.com/ "PHPExcel") files, unzipped
its contents and place them into a **phpexcel** folder within your application's
**protected/extensions** folder:



~~~
[php]

// 
// VERY DUMMY TEST CONTROLLER
// FOR THE SAKE OF THE EXAMPLE
// TEST IT AS http : / / <yourapplicationurl> / index.php ? r=test/test

class TestController extends Controller{

     // no layouts here
     public $layout = '';
	
     public function actionTest()
     {
     //
     // get a reference to the path of PHPExcel classes	
     $phpExcelPath = Yii::getPathOfAlias('ext.phpexcel.Classes');
     
     // Turn off our amazing library autoload 
      spl_autoload_unregister(array('YiiBase','autoload'));        

     //
     // making use of our reference, include the main class
     // when we do this, phpExcel has its own autoload registration
     // procedure (PHPExcel_Autoloader::Register();)
    include($phpExcelPath . DIRECTORY_SEPARATOR . 'PHPExcel.php');

     // Create new PHPExcel object
     $objPHPExcel = new PHPExcel();

     // Set properties
     $objPHPExcel->getProperties()->setCreator("Maarten
Balliauw")
	->setLastModifiedBy("Maarten Balliauw")
	->setTitle("PDF Test Document")
	->setSubject("PDF Test Document")
	->setDescription("Test document for PDF, generated using PHP
classes.")
	->setKeywords("pdf php")
	->setCategory("Test result file");


     // Add some data
     $objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A1', 'Hello')
            ->setCellValue('B2', 'world!')
            ->setCellValue('C1', 'Hello')
            ->setCellValue('D2', 'world!');

      // Miscellaneous glyphs, UTF-8
     $objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A4', 'Miscellaneous glyphs')
            ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');

      // Rename sheet
      $objPHPExcel->getActiveSheet()->setTitle('Simple');

      // Set active sheet index to the first sheet, 
      // so Excel opens this as the first sheet
     $objPHPExcel->setActiveSheetIndex(0);

      // Redirect output to a client’s web browser (Excel2007)
      header('Content-Type: application/pdf');
      header('Content-Disposition:
attachment;filename="01simple.pdf"');
      header('Cache-Control: max-age=0');

      $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');
      $objWriter->save('php://output');
      Yii::app()->end();
       
       // 
       // Once we have finished using the library, give back the 
       // power to Yii... 
       spl_autoload_register(array('YiiBase','autoload'));
       }
}

~~~

<h2>Final Words</h2>
This post is using PHPExcel external library as an example, but this procedure
should be taken into account when we encounter a problem like this. Whenever you
find a library that you wish to include in your Yii application, check out its
autoloading functions first.