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
Laravel/Eloquent: Fatal error: Call to a member function connection() on a non-object
提问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 boot
method.
在您的服务提供商的boot
方法中引导您的包。
Explanation:
说明:
Since you're developing a package to be used with Laravel, there's no point in making your own Capsule
instance. You can just use Eloquent
directly.
由于您正在开发一个与 Laravel 一起使用的包,因此制作自己的Capsule
实例是没有意义的。Eloquent
直接使用就可以了。
Your problem seems to stem from DB
/Eloquent
not 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 register
method.
您还没有向我们展示您的服务提供商,但我猜您正在使用一个并在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 boot
method.
由于您的包依赖于不同的服务提供者 ( DatabaseServiceProvider
) 在它自己执行之前进行连接,因此引导您的包的正确位置是在您的服务提供者的boot
方法中。
Here's a quote from the docs:
这是文档中的引用:
The
register
method is called immediately when the service provider is registered, while theboot
command 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
boot
method.
该
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;
)