Я собираю пакет в 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 не загружается?
Ответ:
Загрузите ваш пакет у поставщика услуг boot
метод.
объяснение:
Поскольку вы разрабатываете пакет для использования с Laravel, нет смысла делать свой собственный Capsule
пример. Вы можете просто использовать Eloquent
непосредственно.
Ваша проблема, кажется, проистекает из DB
/Eloquent
еще не настроен к тому времени, когда ваш код попадет в него.
Вы не показали нам своего поставщика услуг, но я предполагаю, что вы используете его и делаете все это в register
метод.
Поскольку ваш пакет зависит от другого поставщика услуг (DatabaseServiceProvider
) чтобы быть подключенным до его собственного выполнения, правильное место для начальной загрузки вашего пакета находится у поставщика услуг boot
метод.
Вот цитата из документы:
register
метод вызывается сразу же, когда поставщик услуг зарегистрирован, аboot
Команда вызывается только перед отправкой запроса.Таким образом, если действия вашего поставщика услуг основаны на том, что другой поставщик услуг уже зарегистрирован […], вам следует использовать
boot
метод.
Если вы работаете с Lumen, у вас может возникнуть идентичная проблема. В этом случае просто раскомментируйте:
// $app->withFacades();
// $app->withEloquent();
в bootstrap\app.php
@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();
То, что я сделал, было просто, я просто забыл раскомментировать $app->withFacades();
в моей начальной загрузке / app.php.
$app->withEloquent();
Сейчас работает нормально
Попробуйте включить фасад 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;
)