Laravel / Eloquent: фатальная ошибка: вызов функции-члена connection () для необъекта

Я собираю пакет в 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 и вызывает запись:

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;
}
}

Тот факт, что БД недоступна, говорит о том, что Eloquent не загружается?

13

Решение

Ответ:

Загрузите ваш пакет у поставщика услуг boot метод.


объяснение:

Поскольку вы разрабатываете пакет для использования с Laravel, нет смысла делать свой собственный Capsule пример. Вы можете просто использовать Eloquent непосредственно.

Ваша проблема, кажется, проистекает из DB/Eloquent еще не настроен к тому времени, когда ваш код попадет в него.

Вы не показали нам своего поставщика услуг, но я предполагаю, что вы используете его и делаете все это в register метод.

Поскольку ваш пакет зависит от другого поставщика услуг (DatabaseServiceProvider) чтобы быть подключенным до его собственного выполнения, правильное место для начальной загрузки вашего пакета находится у поставщика услуг boot метод.

Вот цитата из документы:

register метод вызывается сразу же, когда поставщик услуг зарегистрирован, а boot Команда вызывается только перед отправкой запроса.

Таким образом, если действия вашего поставщика услуг основаны на том, что другой поставщик услуг уже зарегистрирован […], вам следует использовать boot метод.

26

Другие решения

Если вы работаете с Lumen, у вас может возникнуть идентичная проблема. В этом случае просто раскомментируйте:

// $app->withFacades();

// $app->withEloquent();

в bootstrap\app.php

14

@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();
9

То, что я сделал, было просто, я просто забыл раскомментировать $app->withFacades();
$app->withEloquent();
в моей начальной загрузке / app.php.

Сейчас работает нормально

2

Попробуйте включить фасад DB, а также Eloquent …

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

…а затем посмотреть, есть ли у вас доступ к DB::table('chat_history'),

(Также обратите внимание, что в вашем классе ваш призыв к use Illuminate\Database\Model; должно быть Illuminate\Database\Eloquent\Model; )

1
По вопросам рекламы [email protected]