php Laravel/Eloquent:致命错误:在非对象上调用成员函数 connection()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26680716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:00:00  来源:igfitidea点击:

Laravel/Eloquent: Fatal error: Call to a member function connection() on a non-object

phplaravelpackageeloquentcomposer-php

提问by J. LaRosee

I'm building a package in Laravel 4 but am getting a non-object error when attempting to access the db from which seems to be a properly instantiated object. Here's the setup:

我正在 Laravel 4 中构建一个包,但是在尝试访问似乎是正确实例化对象的数据库时出现非对象错误。这是设置:

The config and class in question:

有问题的配置和类:

composer.json:

作曲家.json:

...
"autoload": {
        "classmap": [
            "app/commands",
            "app/controllers",
            "app/models",
            "app/database/migrations",
            "app/database/seeds",
            "app/tests/TestCase.php"
        ],
        "psr-0": {
            "Vendor\Chat": "src/vendor/chat/src"
        }  
    }
...

The class:

班上:

namespace Vendor\Chat;

use Illuminate\Database\Eloquent\Model as Eloquent;


class ChatHistory extends Eloquent
{
    protected $table = 'chat_history';

    protected $fillable = array('message', 'user_id', 'room_token');

    public function __construct($attributes = array())
    {
        parent::__construct($attributes);
    }

}

The call:

电话:

$message = new Message($msg);

$history = new ChatHistory;
$history->create(array(
                 'room_token' => $message->getRoomToken(),
                 'user_id' => $message->getUserId(),
                 'message' => $message->getMessage(),
              ));

The error:

错误:

PHP Fatal error:  Call to a member function connection() on a non-object in /home/vagrant/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 2894

I believe I'm missing something fundamental and under my nose. Thanks for any and all help!

我相信我错过了一些基本的东西。感谢您的任何帮助!

EDIT:

编辑:

Here is the class that's instantiating ChatHistory and calling the write:

这是实例化 ChatHistory 并调用 write 的类:

namespace Vendor\Chat;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

use Vendor\Chat\Client;
use Vendor\Chat\Message;
use Vendor\Chat\ChatHistory;

use Illuminate\Database\Model;

class Chat implements MessageComponentInterface {

    protected $app;

    protected $clients;

    public function __construct() 
    {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) 
    {
        $client = new Client;
        $client->setId($conn->resourceId);
        $client->setSocket($conn);

        $this->clients->attach($client);
    }

    public function onMessage(ConnectionInterface $conn, $msg) 
    {
        $message = new Message($msg);

        $history = new ChatHistory;
        ChatHistory::create(array(
                     'room_token' => $message->getRoomToken(),
                     'user_id' => $message->getUserId(),
                     'message' => $message->getMessage(),
                  ));
        /* error here */
        /* ... */ 
    }

    public function onClose(ConnectionInterface $conn) 
    {
        $this->clients->detach($conn);
    }

    public function onError(ConnectionInterface $conn, \Exception $e) 
    {
        $conn->close();
    }

    protected function getClientByConn(ConnectionInterface $conn)
    {
        foreach($this->clients as $client) {
            if($client->getSocket() === $conn) {
                return $client;
            } 
        } 

        return null;
    }
}

The fact that DB isn't available suggest that Eloquent isn't being loaded up top?

DB 不可用的事实表明 Eloquent 没有被加载到顶部?

回答by Joseph Silber

Answer:

回答

Bootstrap your package in your service provider's bootmethod.

在您的服务提供商的boot方法中引导您的包。



Explanation:

说明

Since you're developing a package to be used with Laravel, there's no point in making your own Capsuleinstance. You can just use Eloquentdirectly.

由于您正在开发一个与 Laravel 一起使用的包,因此制作自己的Capsule实例是没有意义的。Eloquent直接使用就可以了。

Your problem seems to stem from DB/Eloquentnot being set up yet by the time your code hits it.

您的问题似乎源于DB/Eloquent尚未在您的代码命中它时进行设置。

You have not shown us your service provider, but I'm guessing you're using one and doing it all in the registermethod.

您还没有向我们展示您的服务提供商,但我猜您正在使用一个并在register方法中完成所有操作。

Since your package depends on a different service provider (DatabaseServiceProvider) to be wired up prior to its own execution, the correct place to bootstrap your package is in your service provider's bootmethod.

由于您的包依赖于不同的服务提供者 ( DatabaseServiceProvider) 在它自己执行之前进行连接,因此引导您的包的正确位置是在您的服务提供者的boot方法中。

Here's a quote from the docs:

这是文档中的引用:

The registermethod is called immediately when the service provider is registered, while the bootcommand is only called right before a request is routed.

So, if actions in your service provider rely on another service provider already being registered [...] you should use the bootmethod.

register方法在注册服务提供者时立即调用,而该boot命令仅在路由请求之前调用。

因此,如果您的服务提供者中的操作依赖于已经注册的另一个服务提供者 [...],您应该使用该boot方法。

回答by Kamil Szymański

In case you're working with Lumen, you may occur identical problem. In this case just uncomment:

如果您使用 Lumen,您可能会遇到相同的问题。在这种情况下,只需取消注释:

// $app->withFacades();

// $app->withEloquent();

in bootstrap\app.php

bootstrap\app.php

回答by J. LaRosee

@matpop and @TonyStark were on the right track: Capsule\Manager wasn't being booted.

@matpop 和 @TonyStark 走在正确的轨道上:Capsule\Manager 没有被启动。

use Illuminate\Database\Capsule\Manager as Capsule;

$capsule = new Capsule;
$capsule->addConnection([
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'project',
    'username'  => 'root',
    '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));

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

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

I am able to extend Eloquent after booting. I think another solution might be along the lines of (but not tested):

我可以在启动后扩展 Eloquent。我认为另一种解决方案可能与(但未经测试)类似:

include __DIR__ . '/../../vendor/autoload.php';
$app = require_once __DIR__ . '/../../bootstrap/start.php';
$app->boot();

回答by afrikandev

What i did was simple, i just forgot to uncomment $app->withFacades(); $app->withEloquent();in my bootstrap/app.php.

我所做的很简单,我只是忘记$app->withFacades(); $app->withEloquent();在 bootstrap/app.php 中取消注释。

Now works fine

现在工作正常

回答by damiani

Try including the DB facade as well as Eloquent...

尝试包括 DB 外观以及 Eloquent ...

use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Model as Eloquent;

...and then see if you have access to DB::table('chat_history').

...然后查看您是否可以访问DB::table('chat_history').

(Also note that in your class, your call to use Illuminate\Database\Model;should be Illuminate\Database\Eloquent\Model;)

(另请注意,在您的班级中,您的电话use Illuminate\Database\Model;应该是Illuminate\Database\Eloquent\Model;