我正在Laravel 4中构建一个包,但在尝试访问数据库时遇到非对象错误,似乎是一个正确实例化的对象.这是设置:
有问题的配置和类:
composer.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" } } ...
班级:
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); } }
电话:
$message = new Message($msg); $history = new ChatHistory; $history->create(array( 'room_token' => $message->getRoomToken(), 'user_id' => $message->getUserId(), 'message' => $message->getMessage(), ));
错误:
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
我相信我错过了一些基本的东西.感谢您的帮助!
编辑:
这是实例化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; } }
DB不可用的事实表明Eloquent没有被加载到顶部?
如果你正在使用流明,你可能会遇到同样的问题.在这种情况下,只需取消注释:
// $app->withFacades(); // $app->withEloquent();
在 bootstrap\app.php
答案:
使用服务提供商的boot
方法引导程序包.
说明:
由于您正在开发一个与Laravel一起使用的软件包,因此制作您自己的Capsule
实例毫无意义.你可以直接使用Eloquent
.
你的代码遇到它时,你的问题似乎源于DB
/ Eloquent
尚未设置.
你没有向我们展示你的服务提供商,但我猜你正在使用一个并在register
方法中完成所有工作.
由于您的软件包依赖于在DatabaseServiceProvider
自己执行之前要连接的不同服务提供者(),因此引导软件包的正确位置在您的服务提供者的boot
方法中.
以下是文档的引用:
在
register
注册服务提供程序时立即调用该方法,而boot
仅在路由请求之前调用该命令.因此,如果您的服务提供商中的操作依赖于已经注册的其他服务提供商,您应该使用该
boot
方法.
@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();
我可以在启动后扩展Eloquent.我认为另一种解决方案可能是(但没有经过测试):
include __DIR__ . '/../../vendor/autoload.php'; $app = require_once __DIR__ . '/../../bootstrap/start.php'; $app->boot();