2

I did a couple of projects with Laravel in the past but now I need something very light for a project and went to use Slim, it works great for what I need and I want the great Eloquent ORM and Query Builder of Laravel, can't go without it now :) Now I manage to get it all working with composer, using the information that Taylor displayed on his GitHub, copied his piece of code

use Illuminate\Database\Capsule\Manager as Capsule;

$capsule = new Capsule;

$capsule->addConnection([
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => '',
    'username'  => '',
    'password'  => '',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
]);

// Set the event dispatcher used by Eloquent models... (optional)
use Illuminate\Events\Dispatcher;
use Illuminate\Container\Container;
$capsule->setEventDispatcher(new Dispatcher(new Container));

// Set the cache manager instance used by connections... (optional)
$capsule->setCacheManager(...);

// Make this Capsule instance available globally via static methods... (optional)
$capsule->setAsGlobal();

// Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())
$capsule->bootEloquent();

That works perfectly good on my local dev (PHP 5.4.x) but when I put it on my server PHP 5.3.x, it just doesn't work anymore :( Now I see 1 problem being that we can't use anonymous array like this [] but instead should be written the old way of array(), that is inside the addConnection(array($settings)) great, now a little further...but then after it seems to crash inside $capsule->setEventDispatcher() and I don't have logs on my server (I only found through var_dump() here and there), it's just a NAS and I don't want to even think of spending a few hours just to find out how to enable it. But what's funny is that I had a Laravel 4 project working with it... so why just building a part of it Illuminate\Database doesn't work then? I also found another piece of code to make Eloquent ORM work in PHP 5.3.x

$settings = array(
    'driver' => '',
    'host' => '127.0.0.1',
    'database' => '',
    'username' => '',
    'password' => '',
    'charset'   => "utf8",
    'collation' => 'utf8_general_ci',
    'prefix' => ''
);


// Bootstrap Eloquent ORM
$connFactory = new \Illuminate\Database\Connectors\ConnectionFactory(new Illuminate\Container\Container);
$conn = $connFactory->make($settings);
$resolver = new \Illuminate\Database\ConnectionResolver();
$resolver->addConnection('default', $conn);
$resolver->setDefaultConnection('default');
\Illuminate\Database\Eloquent\Model::setConnectionResolver($resolver);

but if I use this piece of code, which is good with Models by the way. I need to use $conn->table('...')... instead of the Facade simple way of DB::table(....) which is what I want, why is it important you would say? Well what if I want to convert to Laravel in the future... I would have to change all of the $conn-> to DB:: so I would rather do it right the first time. If someone knows how to create Facade on the 2nd piece of code, I would be happy too... Thanks for any help.

ghiscoding
  • 12,308
  • 6
  • 69
  • 112

3 Answers3

3

Look at the Laravel datasource connector in PPI 2.1

https://github.com/ppi/framework/tree/2.1/PPI/DataSource/Connection

Paul Dragoonis
  • 2,315
  • 1
  • 16
  • 22
3

I'm also using Capsule with Slim. First off, make sure that you're using version 4.1.* of Illuminate/Capsule. When 4.2 came out, one of the big changes was that PHP 5.4 became the required minimum. 4.1 will still work with PHP 5.3.

Now, if you've done that and you're still running into problems, this is how I registered capsule with Slim's IoC container:

$app->container->singleton('capsule', function() use ($config) {
    $capsule = new Illuminate\Database\Capsule\Manager;

    $capsule->setFetchMode(PDO::FETCH_OBJ);
    $capsule->addConnection($config['database']);
    $capsule->bootEloquent();

    return $capsule->getConnection();
});

Note the call to getConnection(). This is necessary, as the Capsule global is not getting registered.

Edit: Also note the call to setFetchMode. When using Fluent from within Laravel, queries return instances of stdClass, but the default behavior appears to be to return associative arrays. The framework just overrides that at some point, leading to Capsule behaving in correct, yet unexpected ways. This sets it to run with more expected behavior.

Michael Cordingley
  • 1,485
  • 1
  • 11
  • 23
  • Thanks for your answer, I had similar solution after all... I also have `$container = $capsule->getContainer();` and `$container->offsetGet('config')->offsetSet('cache.driver', 'array');` and finally `$capsule->setAsGlobal();` ... I forgot the meaning of the first 2 but they work, if you know what meaning then let me know and maybe update your solution...thanks again :) – ghiscoding Aug 09 '14 at 19:14
  • I'm not entirely sure that answering the meaning of those two lines belongs in the answer, so I'll do that here in a comment. – Michael Cordingley Aug 10 '14 at 16:19
  • The container that `getContainer()` returns is an instance of Laravel's IoC container. Even if you're using a different IoC for your app, Capsule will still create and use its own internal one. The second line uses that container to resolve the Laravel configuration object that Capsule uses and then sets the cache driver to be an array. Documentation on that is here: http://laravel.com/docs/cache I think the "array" cache driver just puts the cache into memory for that request. – Michael Cordingley Aug 10 '14 at 18:23
  • @MichaelCordingley Just one problem. If the whole initial code is set in a Closure, then it will cause an error if you use Eloquent Model to get access to DB before use $app['capsule']. Because closure won't be invoked until it is needed. – JasonW May 21 '15 at 09:54
  • @JasonW This is very true. So far, I have gotten around it by just calling `$app->capsule` during application initialization without doing anything with it. That way, the models are all set up. – Michael Cordingley May 21 '15 at 14:07
2

Using version 4.1 of illuminate/database...simple case with a single connection:

// $app is a Slim instance

// add db connection parameters to the app config using mysql / utf8

$app->config(array(
    'db' => array(
        'driver'    => 'mysql',
        'host'      => 'locahost',
        'database'  => 'mydbname',
        'username'  => 'myuser',
        'password'  => 'mypass',
        'charset'   => 'utf8',
        'collation' => 'utf8_general_ci',
        'options'   => array(
            \PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'",
        ),
        'prefix'    => '',
    ),
));

// make sure we always use the same service instance

$app->container->singleton('capsule', function($c) use($app) {
    $capsule = new \Illuminate\Database\Capsule\Manager();
    $capsule->addConnection($params);

    return $capsule;
});

// USE IT ANYWHERE the slim $app instance or the slim app container are visible 

$capsule = $app->capsule;
// ...or if $c is the container
// $capsule = $c->get('capsule');
$people = $capsule->table('person')->take(10)->get();

Alternative easy to use database query builders:

  • doctrine/dbal (btw illuminate/database uses doctrine dbal connection)
  • zendframework/zend-db (providing table data gateway/row data gateway classes as well)
  • j4mie/idiorm
pine3ree
  • 458
  • 1
  • 4
  • 4