我正在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 VendorChat;
use IlluminateDatabaseEloquentModel 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 VendorChat;
use RatchetMessageComponentInterface;
use RatchetConnectionInterface;
use VendorChatClient;
use VendorChatMessage;
use VendorChatChatHistory;
use IlluminateDatabaseModel;
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没有被加载到顶部?
答案:
使用服务提供商的boot
方法引导程序包。
解释:
既然您正在开发一个与Laravel一起使用的包,那么创建自己的Capsule
实例是没有意义的。您可以直接使用Eloquent
。
您的问题似乎源于您的代码命中DB
/Eloquent
时尚未设置。
您还没有向我们展示您的服务提供商,但我猜您正在使用一个,并在register
方法中完成所有操作。
由于您的程序包在执行之前依赖于要连接的不同服务提供商(DatabaseServiceProvider
),因此引导程序包的正确位置是在服务提供商的boot
方法中。
以下是文档中的一句话:
register
方法在注册服务提供商时立即调用,而boot
命令仅在路由请求之前调用。因此,如果您的服务提供商中的操作依赖于另一个已经注册的服务提供商[…],则应该使用
boot
方法。
如果您使用Lumen,可能会出现相同的问题。在这种情况下,只需取消注释:
// $app->withFacades();
// $app->withEloquent();
在bootstrapapp.php
中
@matpop和@TonyStark走在了正确的轨道上:Capsule\Manager没有启动。
use IlluminateDatabaseCapsuleManager 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 IlluminateEventsDispatcher;
use IlluminateContainerContainer;
$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();
我所做的很简单,我只是忘记在bootstrap/app.php中取消注释$app->withFacades();
$app->withEloquent();
。
现在工作良好
尝试包含DB facade以及Eloquent。。。
use IlluminateSupportFacadesDB;
use IlluminateDatabaseEloquentModel as Eloquent;
然后查看您是否有权访问DB::table('chat_history')
。
(还要注意,在您的类中,对use IlluminateDatabaseModel;
的调用应该是IlluminateDatabaseEloquentModel;
)
您必须使用
$capsule->`bootEloquent`();
在database.php
/中。
这是您的完整代码:
<?php
use IlluminateDatabaseCapsuleManager as Capsule;
$capsule = new Capsule;
$capsule->`addConnection`([
'driver' => `'mysql'`,
'host' => 'localhost',
'database' => 'test1',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => '',
]);
$capsule->`bootEloquent`();
<?php
namespace AppProviders;
use AppSetting;
use IlluminateSupportServiceProvider;
use IlluminateSupportFacadesSchema;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
Schema::defaultStringLength(191);
$settings = Setting::all();
foreach ($settings as $key => $settings) {
if($key === 0) $system_name = $setting->value;
elseif($key === 1) $favicon = $setting->value;
elseif($key === 2) $front_logo = $setting->value;
elseif($key === 3) $admin_logo = $setting->value;
}
$shareData = array(
'system_name'=>$system_name,
'favicon'=>$favicon,
'front_logo'=>$front_logo,
'admin_logo'=>$admin_logo
);
view()->share('shareData',$shareData);
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
}