Search code examples
phpajaxfat-free-framework

How to load or include/require 3rd party library php files in a controller only when needed in Fat Free Framework (f3)


I am trying to include a file for the ExactTarget api inside a controller. Basically, an ajax request submits a form to a route /send. In the controller for that route I have a class, but it fails when it makes a call to the ExactTarget library.

class sendexacttarget{
  public function send($f3)
  {
    $client = new ExactTargetSoapClient($wsdl, array('trace'=>1));
  }
}

I don't want to load the ExactTarget file in the index.php, because then it will load on every request. Ideally, I'd like to just load it here, in the send function. I've tried require() and include() but neither work.

I'm trying to include one file exacttarget.php and that file has a require statement calling soap-wsse.php which has another require statement calling xmlseclibs.php.

So first question: Is it possible to load these files from the controller and if so how?

The second part of the question is this. I am able to combine all of the PHP from those three files into one file and include from the index.php, but I have not been successful calling them as separate files. I have tried this:

$f3->set('AUTOLOAD','App/Controllers/;vendor/exacttarget/xmlseclibs.php;vendor/exacttarget/soap-wsse.php;vendor/exacttarget/exacttarget.php');

But it doesn't work.

I also tried this from another SO thread:

$f3->set('AUTOLOAD','App/Controllers/;vendor/exacttarget/');
$params = require 'vendor/exacttarget/exacttarget.php';

Doesn't work. This last bit of code I thought worked for a bit, but then it stopped working. I'm wondering if there is some caching going on?

In any case, if anyone can please help me include this library, even if on all pages I'd be very grateful. Also, this library I'm using is not available via composer so I don't think using composers autoload is an option.

Thanks.


Solution

  • The framework autoloader expects the following conditions in order to be working:

    • one class per file
    • each file named like the class it contains and located in a directory structure representating its namespace

    See the documentation and this SO question for more details.

    Since the external library you're trying to load doesn't meet those requirements, I suggest you three solutions:

    1) require all the dependencies inside your controller:

      public function send($f3) {
        require('vendor/exacttarget/xmlseclibs.php');
        require('vendor/exacttarget/soap-wsse.php.php');
        require('vendor/exacttarget/exacttarget.php');
        $client = new ExactTargetSoapClient($wsdl, array('trace'=>1));
      }
    

    2) create a service that will require all the dependencies and return an ExactTargetSoapClient instance:

    // index.php
    f3->SOAP = function($wsdl,array $options=[]) {
        require_once('vendor/exacttarget/xmlseclibs.php');
        require_once('vendor/exacttarget/soap-wsse.php.php');
        require_once('vendor/exacttarget/exacttarget.php');
        return new ExactTargetSoapClient($wsdl,$options+['trace'=>1]);
    }
    
    // controller
    public function send($f3) {
      $client = $f3->SOAP($wsdl);
    }
    

    NB: if the $wsdl and $options arguments are the same all other your app, you can even remove the function arguments and have a simple $f3->SOAP().

    3) concatenate the three files into one single file properly named and have it autoloaded:

    // vendor/exacttargetsoapclient.php
    <?php
    class ExactTargetSoapClient extends SoapClient {
    
    // etc.
    
    class WSSESoap {
    
    // etc.
    
    /**
    * xmlseclibs.php
    * etc.
    

    Now set up the autoloader:

    // index.php
    $f3->AUTOLOAD = 'App/Controllers/;vendor/';
    

    And you're done:

    // controller
      public function send($f3) {
      $client = new ExactTargetSoapClient($wsdl, array('trace'=>1));
    }