Quick links: Content - sections - sub sections
EN FR

To be able to respect the layer model, it is recommended to do all the business processing and the services in classes dedicated to it.

In this kind of classes, you will manipulate, for example, daos, data from daos or others, do all the processing other than display. The methods of your controllers will thus be lighter and the business processing will be reusable in other actions.

Create a class

Business classes and services in Jelix are classic PHP classes which have nothing specific. The only thing that you have to respect is to specify it in a file named "name_of_class.class.php" in the classes directory of the module :

  
   class StockService {
      public function getListeProduits(){
          $stock = jDAO::get("products");
          
          $list = $stock->findAll();
          
          // here : processing of the list (for example)
          
          
          return $list;      
      }
   }

This class must be placed in classes/StockService.class.php.

The difference between a service class and the other classes is that a service class gives a service. It doesn't need to be instanciated each time we use it because it doesn't have "discriminating" property. Only one instance is enough for all the application.

For example, a "factory" type class, which retrieves sets of data, is a service class. On the other hand, a class representing a product, which thus has identifying fields, is a non service class.

Including classes or interfaces

jClasses provides static methods inc() and incIFace to include classes and interfaces stored in a classes directory of a module.

A class should be defined in a PHP file which have the name of the class and the suffix .class.php. To declare the class stockUtils, you have to create a file classes/stockUtils.class.php which contains at least

<?php
class stockUtils {
    […]
}
?>

An interface should be store in a *.iface.php file. To declare a IStockUtils interface, store this content into the file classes/IStockUtils.iface.php:

<?php
interface IStockUtils {
    […]
}
?>

Then to include this interface, stored in the module commons, into the stockUtils.class.php file:

<?php
jClasses::inIface('commons~interfaces/IStockUtils');

class stockUtils implements IStockUtils {
    […]
}
?>

And to include the stockUtils class anywhere:

<?php
jClasses::inc('commons~stockUtils');

[…]
?>

Instantiation

Jelix proposes the jClasses class, which avoids to do an include and instantiate yourself.

jClasses gives two static methods, to which you give a selector :

  • createInstance($ClassSelector); (or create($ClassSelector) )
  • getService($ClassSelector);

The first will, for each call, give a new instance. The second will allways give the same instance of the class. getService will thus be used for the service classes, and createInstance for the others.

If our StockService class is in the "shop" module, here is an example in an actiongroup :


    $stocksrv = jClasses::getService("shop~stockservice");
    $rep->body->assign('product_list', $stocksrv->getProductList());

However in certain cases, like when the constructor of the business class ask a parameter, youhave to include the business class and then instantiate it "manually".

In this case the jClasses class has a static method inc($ClassSelector). It includes (require_once) the class specified by the selector.

Example :


    jClasses::inc('shop~shoesProduct');
    $shoe = new shoesProduct('43', 'black');

Notice that you can put classes in sub-directories of the classes/ directory. For example, you can store the StockService.class.php file into classes/shop/. Then, to call it:


   $stocksrv = jClasses::getService("shop~stocks/stockservice");

Installing and using vendor classes

You have often to use some classes provided by other projects. Of course, you can use it into a Jelix application.

Although you can store this classes where you want (because the require or include statement are not restricted), it's better to store them:

  • into the lib/ directory
  • or into the classes/ directory of a module

It is interesting to store a set of classes into the lib directory, because it's easier to share this classes between projects, and perhaps it will be easier to update them.

To include them, you have to use th LIB_PATH constant. For example, if you wan to include the lib/foo/bar.php, do this into your controller or other files of a module:


   require(LIB_PATH.'foo/bar.php');
   $myclass = new bar();

You can store the class in a module if it is used only by this module. You can put it into the classes directory:


   require(JELIX_APP_PATH.'modules/mymodule/classes/bar.php');
   $myclass = new bar();

If the name of the class and the name of the file follow the coding style of jelix (a "bar" class into a bar.class.php file), you can use jClasses:


   $myclass = jClasses::create('bar');

   // or if the constructor need arguments
   jClasses::inc('bar');
   $myclass = new bar('bla');

Loading classes before the session_start

Sometimes, you may want to store some of your business object in sessions. But then your classes should be loaded before the session_start() call, so PHP can unserialize this objects.

Jelix provide a simple way to indicates which classes to load before the session_start(). In the configuration, in the sessions section, indicate the selectors of this classes in the loadClasses options:


[sessions]

loadClasses = "mymodule~bar,mymodule~subdir/foo, shop~shoesProduct"

Note: the module name is required.