2014-10-31 46 views
11

我在Laravel 4中構建了一個包,但在嘗試訪問似乎爲是一個正確實例化的對象。這裏的設置:Laravel/Eloquent:致命錯誤:調用非對象的成員函數連接()

在考慮中的配置和類:

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" 
     } 
    } 
... 

類:

​​

召喚:

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

事實上,DB不可用暗示雄辯沒有被加載上去頂?

+1

在哪一行中出現此錯誤?是歷史還是使用'$ message'方法。我們或當然不知道,我們不知道什麼'消息'是 – 2014-10-31 18:25:23

+0

道歉。在ChatHistory上調用create()時會觸發該錯誤。消息是表示套接字消息的簡單類。 – 2014-10-31 19:13:36

+1

您是否像https://laracasts.com/forum/?p=969-codeception-and-laravel/0中描述的那樣嘗試啓動Laravel? – 2014-11-03 21:46:03

回答

21

引導你的包在服務提供商的boot方法。


說明

既然你正在開發一個包與Laravel使用,還有在製作自己Capsule實例是沒有意義的。您可以直接使用Eloquent

您的問題似乎源於DB/Eloquent在代碼到達時尚未設置。

您沒有向我們展示您的服務提供商,但我猜你正在使用一種方法,並在register方法中完成所有操作。

由於您的軟件包依賴於不同的服務提供商(DatabaseServiceProvider)在自身執行之前進行連線,因此引導軟件包的正確位置在您的服務提供商的boot方法中。

下面是引自the docs

The register method is called immediately when the service provider is registered, while the boot 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.

+1

這裏是賞金!我猜想我們只是錯過了文檔中的一些聲明...請仔細閱讀! – matpop 2014-11-07 08:34:31

+0

使用Capsule「固定」了這個問題,但它似乎是一個不太理想的解決方案(https://github.com/illuminate/database)。尋找引導包是我正在尋找的,看起來像,雖然膠囊解決方案幫助我通過向我展示代碼不是問題的正確途徑,但我加載和使用代碼的順序不正確。 – 2014-11-07 18:32:08

7

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

我可以在啓動後擴展雄辯。我認爲,另一種解決方案可能是沿着線(而不是測試):

include __DIR__ . '/../../vendor/autoload.php'; 
$app = require_once __DIR__ . '/../../bootstrap/start.php'; 
$app->boot(); 
+0

您正在開發一個使用Eloquent的**獨立**包嗎?還是您正在構建一個專門用於Laravel_的包? – matpop 2014-11-05 10:17:16

+0

這是一個Laravel特定的包。 – 2014-11-05 17:31:20

+0

@matpop你的建議讓我走上了正確的軌道,所以我想給你賞金。由於你沒有提供答案,所以不知道該怎麼做。 – 2014-11-05 18:35:40

1

嘗試包括DB門面以及雄辯...

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

...然後看看你有權訪問DB::table('chat_history')

(另請注意,在你的類,你要use Illuminate\Database\Model;調用應該是Illuminate\Database\Eloquent\Model;

13

如果你正在使用流明工作,你可能會出現相同的問題。在這種情況下,只需取消註釋:

// $app->withFacades(); 

// $app->withEloquent(); 

bootstrap\app.php

2

我所做的很簡單,我只是忘了在我的引導/ app.php取消註釋$app->withFacades(); $app->withEloquent();

現在正常工作

+0

這爲我固定,但這是爲流明。 – 2016-11-09 17:25:49

相關問題