ChatGPT解决这个技术问题 Extra ChatGPT

Eloquent error: A facade root has not been set

I have been using Eloquent as a standalone package in Slim Framework 2 successfully.

But now that I want to make use of Illuminate\Support\Facades\DB since I need to show some statistics by getting the info from 2 tables and using a Left Join and a Counter from the database like this:

use Illuminate\Support\Facades\DB;
$projectsbyarea = DB::table('projects AS p')
        ->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
        ->leftJoin('areas AS a','p.area_id','=','a.id')
        ->where('p.status','in_process')
        ->where('a.area','<>','NULL')
        ->orderBy('p.area_id');

I get the following error:

Type: RuntimeException
Message: A facade root has not been set.
File: ...\vendor\illuminate\support\Facades\Facade.php
Line: 206

How can I solve it?

So far I have found out, in this link that I need to create a new app container and then bind it to the Facade. But I haven't found out how to make it work.

This is how I started the rest of my Eloquent and working fine:

use Illuminate\Database\Capsule\Manager as Capsule;

$capsule = new Capsule();

$capsule->addConnection([
    'my'         =>  $app->config->get('settings'),
    /* more settings ...*/
]);

/*booting Eloquent*/
$capsule->bootEloquent();

How do I fix this?

Fixed As @user5972059 said, I had to add $capsule->setAsGlobal();//This is important to make work the DB (Capsule) just above $capsule->bootEloquent();

Then, the query is executed like this:

use Illuminate\Database\Capsule\Manager as Capsule;
$projectsbyarea = Capsule::table('projects AS p')
            ->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
            ->leftJoin('areas AS a','p.area_id','=','a.id')
            ->where('p.status','in_process')
            ->where('a.area','<>','NULL')
            ->orderBy('p.area_id')
            ->get();
I got this "A facade root has not been set" error when I was trying to use the Laravel url('/') helper within a config file.
I had faced the same issue. Your solution helps me to identify it.
This helped me (in this post): stackoverflow.com/a/69677810/11716408

M
Martin Zabel

You have to change your code to:

$Capsule = new Capsule;
$Capsule->addConnection(config::get('database'));
$Capsule->setAsGlobal();  //this is important
$Capsule->bootEloquent();

And at the beginning of your class file you have to import:

use Illuminate\Database\Capsule\Manager as DB;

where do I put this? I'm getting that error after upgrading to Laravel 5.4: i.gyazo.com/a664efbe34aea117d2bbb8a8ad448951.png
Why do you have to do this? What does it do?
Its started working for me after adding this line use Illuminate\Database\Capsule\Manager as DB; but I have checked Manager class and there is no any methods exists related to transaction, than how it's working
K
Kaz

I have just solved this problem by uncommenting $app->withFacades(); in bootstrap/app.php


m
melvin atieno

Had the same issue with laravel 8. I replaced

   use PHPUnit\Framework\TestCase;

with:

 use Tests\TestCase;

This worked for me! I'm dealing with a legacy code base that was upgraded from Lumen to Laravel. The prior dev team did not upgrade the test suite...
This solved it for me. Interestingly I was using a brand new install of Laravel 8, and the ExampleTest.php that ships is extending the PHPUnit class.
Worked for me, using laravel 9, thank you
Works when using facades on Unit tests.
p
pixelistik

Try uncommenting in app.php $app->withFacades();


If you are using Lumen, this is probably the solution for you.
T
Thariama

One random problem using phpUnit tests for laravel is that the laravel facades have not been initialized when testing.

Instead of using the standard PHPUnit TestCase class

class MyTestClass extends PHPUnit\Framework\TestCase

one can use

class UserTest extends Illuminate\Foundation\Testing\TestCase

and this problem is solved.


This one is easier than the accepted answer, but if you're using Laravel 8, @melvin's answer below is even better. For this one to work, you have to use CreatesApplication trait in your unit test class. @melvin's answer OTOH doesn't require anything else.
a
astroneo

Do not forget to call parent::setUp(); before.

fails

public function setUp(): void {
    Config::set('something', true);
}

works

public function setUp(): void {
    parent::setUp();

    Config::set('something', true);
}

Thank you so much!!!! Helped me a lot
d
dwenaus

I got this error after running:

$ php artisan config:cache

The solution for me was to delete the /bootstrap/cache/config.php file. I'm running Laravel 5.5.

The seems to arise in multiple situation, and not just about facades.


H
Hossein Shafiei

wrong way

public function register()
   {
       $this->app->bind('Activity', function($app)
       {
            new Activity;
       });
   }

right way 👍

public function register()
   {
       $this->app->bind('Activity', function($app)
       {
            return new Activity;
       });
   }

---------------------------------- don't forget return


G
Germain Pereira

I received the following message while running tests using PHPUnit v.9.5.4, PHP v.8.0.3 and Lumen v. 8.2.2:

PHP Fatal error: Uncaught RuntimeException: A facade root has not been set. in path_to_project/vendor/illuminate/support/Facades/Facade.php:258

And that happened although I had apparently already configured my app.php to enable facades ($app->withFacades();), still I received this error message whenever I tried to run tests using Illuminate\Support\Facades\DB. Unfortunately, none of the other answers helped me.

This error was actually been thrown due to my configs in phpunit.xml, which didn't point to my app.php file, where I actually enabled facades.

I just had to change

<phpunit (...OTHER_PARAMS_HERE) bootstrap="vendor/autoload.php">

to

<phpunit (...OTHER_PARAMS_HERE) bootstrap="bootstrap/app.php">

Hope it helps.


m
mcanvar

If you recently upgrade Laravel on Homestead & VirtualBox environment or do not find any reason that causing please be sure your Vagrant is up to date.

Referance

I had Taylor lock this thread. The past several replies have restated the solution, which is to Upgrade to Virtualbox 6.x, the thread is locked to prevent other issues that are not related from being dogpiled on here.


P
PHZ.fi-Pharazon

In my project, I managed to fix this issue by using Laravel Dependency Injection when instantiating the object. Previously I had it like this:

$class = new MyClass(
    new Client(),
    env('client_id', 'test'), 
    Config::get('myapp.client_secret')
);

The same error message happened when I used Laravel env() and Config().

I introduced the Client and env in the AppServiceProvider like this:

     $this->app->bind(
         MyClass::class,
         function () {
             return new MyClass(
                 new Client(),
                 env('client_id', 'test')),
                 Config::get('myapp.client_secret')
             );
         }

and then instantiated the class like this:

$class = app(MyClass::class);

See more from https://laravel.com/docs/5.8/container .


c
ccy

Upgrade version for php, I encountered this error while calling the interface.

$ php artisan config:cache

Deleting the /bootstrap/cache/config.php file is a very effective way.


W
William Desportes

Tested on Laravel 8.78

tests/bootstrap.php

<?php

use Illuminate\Foundation\Bootstrap\RegisterFacades;
use Illuminate\Foundation\Bootstrap\LoadConfiguration;

require_once __DIR__ . '/../vendor/autoload.php';

$app = require_once __DIR__ . '/../bootstrap/app.php';

(new LoadConfiguration())->bootstrap($app);//  <------- Required for next line
(new RegisterFacades())->bootstrap($app);//  <------- Add this line

J
Jason

Here is yet another instance of this error, happened to me after upgrading Laravel 8 to 9.

I had feature tests with a @dataProvider to supply data to those tests. Some of the data supplied by the data provider methods came from an application service. It was being initialised like this:

/**
 * @dataProvider myDataProvider
 */
public function testSomeStuff(...)
{
   ...
}

public function myDataProvider()
{
   $myService = app(Service::class); // This is trouble

   return [
      ['test1_data' => $myService::SOME_CONSTANT],
      [...],
      ...
   ];
}

This worked under Laravel 8, but not in Laravel 9. All other solutions listed in this SO thread were checked and were correctly set up.

The problem is that the application is not being inititialised until after the data provider method is run. It was presumably initialised before this stage in the Laravel 8 install. So app(Service::class) was failing due to it using facades internally.

One workaround could be to force the application to initialise earlier, in the data provider function: $this->createApplication(). I would not recommend this due to potential side effects of the test parts running in the wrong order, though it does appear to work when I tried it.

Best solution is to avoid accessing any part of the application functionality in the data provider methods. In my case it was easy to replace $myService::SOME_CONSTANT with MyService::SOME_CONSTANT after making sure those constants were public.

Hopefully this will help somebody suddenly hitting this problem running feature tests after a Laravel 9 upgrade.


q
qskane

In my case, all facades are unavailable, including any commands of artisan.

I tried deleting the vendor and reinstalling, but the problem still occurs.

I finally found the problem because I was using the bensampo/laravel-enum library, and I used a statement similar to the following in a config file,


'name' =>\App\Enums\VipLevelEnum::getDescription(
    \App\Enums\VipLevelEnum::GOLD
)

This may lead to errors due to Lang facade not being loaded yet (I guess)


s
sh6210

In my case, for a while a ran a PHP project in PHP version 8, and that time I used some PHP 8 features like param definition and method's multiple return type declarations supported by only PHP 8 and above. When I downgraded from PHP 8 to PHP 7.4 I faced this issue. After removing the return types and param hinting the problems are gone.