2

I am struggling to figure out how I can make a database query inside of a Laravel config file.

I currently use:

<?php
// config/database.php

$results = \Illuminate\Support\Facades\DB::select( \Illuminate\Support\Facades\DB::raw("select version()") );
$mysql_version =  $results[0]->{'version()'};
dd($mysql_version);

return [

...

But the error that I receive is that:

RuntimeException in Facade.php line 218:
A facade root has not been set.
in Facade.php line 218
at Facade::__callStatic('raw', array('select version()')) in database.php line 2
at require('/Users/test/code/clooud/config/database.php') in LoadConfiguration.php line 70
at LoadConfiguration->loadConfigurationFiles(object(Application), object(Repository)) in LoadConfiguration.php line 39
at LoadConfiguration->bootstrap(object(Application)) in Application.php line 208
at Application->bootstrapWith(array('Illuminate\\Foundation\\Bootstrap\\LoadEnvironmentVariables', 'Illuminate\\Foundation\\Bootstrap\\LoadConfiguration', 'Illuminate\\Foundation\\Bootstrap\\HandleExceptions', 'Illuminate\\Foundation\\Bootstrap\\RegisterFacades', 'Illuminate\\Foundation\\Bootstrap\\RegisterProviders', 'Illuminate\\Foundation\\Bootstrap\\BootProviders')) in Kernel.php line 160
at Kernel->bootstrap() in Kernel.php line 144
at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 116
at Kernel->handle(object(Request)) in index.php line 57
at require('/Users/test/code/clooud/public/index.php') in server.php line 128

How can I make sure that this query results in an output and resolve this error?

Thanks for any help!

Chris
  • 3,311
  • 4
  • 20
  • 34
  • 1
    http://stackoverflow.com/questions/29203532/eloquent-query-in-custom-config-file-config-laravel-5 – Philipp May 04 '17 at 17:48
  • Leave a default in the config file, then create a service provider to query the database after Laravel is booted then update the config value from the DB result. – jfadich May 04 '17 at 18:14
  • @Philipp that won't work, because it is the database config I am modifying. jfadich that works. Thanks :-) – Chris May 04 '17 at 19:13

3 Answers3

6

Leave a default or null value in your config/database.php file. Create a new service provider (either with the artisan command or manually)

php artisan make:provider DatabaseConfigProvider

Then add the new provider to the $providers array in your config/app.php file.

Finally add the following code to the boot() method.

public function boot()
{
    $result= \DB::select('select version() as version')[0];
    $this->app['config']->put('database.connections.mysql.version', $result->version);
}

The key in the put() argument can be whatever you want.

jfadich
  • 6,110
  • 2
  • 20
  • 31
2

I tried out @jfadich's answer and found it wasn't quite solving the issue for me (laravel 5.4). I guess this is probably due to a different laravel version, but modifying his instructions I was able to get something working. By all means if I'm a bit wide of the mark in my approach please let me know, and I'll amend my answer.

So, I worked in the AppServiceProvicer itself, but you could also create a new one as previously suggested.

The line $this->app['config']->put('database.connections.mysql.version', $result->version); was giving me an error (Call to undefined method Illuminate\Config\Repository::put())

I had a rummage in the Illuminate\Config\Repository file to see what methods it had defined and found a set() method instead, which seems to work. I set my file up as so:

//in AppServiceProvider.php

use Illuminate\Contracts\Config\Repository; //allow setting of app config values

public function boot(Repository $appConfig)
{
    $config = CustomConfig::first(); //get the values you want to use
    $appConfig->set('configfile.username', $config->demo_username);
    $appConfig->set('configfile.account', $config->demo_account);
}

I also came across the useful method all() - a dd of $appConfig->all() gave an easy way to check that the values had been set as intended.

Many thanks to @jfadich for putting me on the right path :)

Roxy Walsh
  • 659
  • 1
  • 10
  • 16
1

You have a raw SQL query, and you are inside the config file. The config file has to be parsed before Laravel connects to the database.

You can simply connect to the database in pure php and do the query.

Connecting and querying a database in pure php is explained here: https://www.w3schools.com/php/php_mysql_connect.asp

$conn = mysqli_connect($servername, $username, $password);
$result = $conn->query('select version() as version');
$row = $result->fetch_assoc();
echo $row["version"];
$conn->close();

This should do it.

vishva8kumara
  • 353
  • 1
  • 3
  • 15
  • You should't be connecting to the DB at all during the config loading phase. It would be better to add a service provider and load the version from there. – jfadich May 04 '17 at 18:15
  • 1
    This theoretically would work but I am using it within a installer wizard for new installs. So the user is entering the database info still. – Chris May 04 '17 at 19:14
  • An Installer wizard.! I hope this script might help: https://github.com/Villvay/veev/blob/master/configure.php It does more or less the same thing in a single page. Writes a framework config file and an .htaccess file based on user inputs. Verifies db credentials and loads an SQL dump to the database. – vishva8kumara May 04 '17 at 19:22