1

I have a basic mvc like framework, and I would like to use pimple for dependance injection, but I don't know how to use it inside the framework. This is my app structure.

x-framework
  - config
  - app
      controller
         homeController.php
  - core
  - vendor
     pimple
       lib
         pimple.php
  - public

Now, in homeController.php I would like to use Pimple, but without actually doing new Pimple as seen in this example.

use vendor\pimple; 

class homeController
{
 function index(){
  $app = new Pimple();
  $app['orm'] = $app->share({ return new vendor\orm; });

  $orm = $app['orm'];


  $orm->table('foo'); 
  $orm->findFirst(['name'=>'john']);
}
}

It seems as seen in this example, it would be a very cumbersome task to initialize the pimple class on every controller. How is this done correctly?

Cœur
  • 37,241
  • 25
  • 195
  • 267
robue-a7119895
  • 816
  • 2
  • 11
  • 31
  • 1
    How about you at first learn **how to make a simple class** before starting to pretend that you have an "mvc framework". This question has **NOTHING** to do with MVC architectural pattern. – tereško Nov 19 '14 at 08:48
  • the first link in this answer is a great tutorial to have a deeper understanding of Pimple http://stackoverflow.com/a/10685436/576767 – Félix Adriyel Gagnon-Grenier Dec 02 '14 at 02:59

2 Answers2

4

My answer was not relevant, though the principle of abstract classes stays interesting. Now:

I would like to use Pimple, but without actually doing new Pimple as seen in this example.

At some point you have to instantiate an object, if you want to use it.

Pimple uses a container to store and retrieve services and parameters:

$container = new \Pimple\Container();
// define some services
$container['session_storage'] = function ($c) {
    return new SessionStorage('SESSION_ID');
};

this exemple from the doc defines an anonymous function which returns a session storage object

integrating a container

Pimple, or any container, can be made available using the dependency injection pattern.

either pass it as a parameter to the index

function index(\Pimple $app){

or pass it to homeController's constructor

function __construct(\Pimple $app){
  $this->app = $app;

then use it as a property or a variable

$orm = $app['orm']; // through index() parameters
$orm = $this->app['orm']; // through constructor

abstract classes allow you to define a method for every extending classes, or forcing every extending classes to define a method.

here, we define a constructor for every extending classes, typehinting the Pimple class so that php will ensure your controller receives a real pimple object

abstract class Pimpleized {
  function __construct(\Pimple $pimple) {
    $this->app = $pimple;
  }
}

then your controller

class homeController extends Pimpleized {
  function foo() {
    $this->app->accessSomePimpleMethod();
  }
}

that way, you only have to create your Pimple object once, then pass it to your controllers:

$pimp = new Pimple();
$controller = new homeController($pimp);
  • I know about Pimple. But you didn't answer my question. Because, you are extending the homeController class, which as you can see in my example is not being extended. I just want to have the same capability as symphone/laravel has ... for example. declaring http class as `use symfony\components\...\request` then use that class without using the new keyword. – robue-a7119895 Nov 20 '14 at 22:54
  • Hello @Contax! To increase your chances of obtaining quality answers, please add any content such as the requirement for not extending your homeController in your question. Just because your exemple does not extend anything does not mean it is a requirement :) also, please read the link in this answer, most people use the `container` class in the *namespace* pimple when using this library – Félix Adriyel Gagnon-Grenier Nov 21 '14 at 15:57
-2

Just extend HomeController class with pimple

class HomeController extends Pimple {
  public function __construct() {
    $this['orm.class']= 'vendor\orm'; 
    $this['orm'] = $this->share(function($c){ return new $c['orm.class']; });
  }
}

//and use it directly just after instanciation
$controller = new HomeController();
// you can modify parameters if you need
$controller['orm.class'] = 'myothervendor\orm';
//And get class
$orm = $controller['orm'];
$orm->table('foo'); 
$orm->findFirst(['name'=>'john']);

i hope it's you want :) cheers

Shadar
  • 22
  • 4
  • Sorry, but this does not give me the answer I needed. First you are extending the HomeController, the all the business logic is being done outside the controller. So, what I am looking for is actually the opposite. – robue-a7119895 Nov 17 '14 at 21:10