2015-10-05 27 views
2

我是使用作曲家的新手,並且因爲Rachet和websockets而引起了我的注意。我能夠獲得Rachet websocket聊天應用程序的工作,但現在我想在示例中使用我自己的類。試圖瞭解如何在命名空間中添加我自己的類

我有相同的目錄結構聊天的例子中發現here這些名稱的變化:

/src/MyApp/Chat.php = /src/Websocket/SocketControl.php

/bin/chat-server.php = /bin/socket-server.php

我composer.json:

{ 
    "autoload": { 
     "psr-0": { 
      "Websocket": "src" 
     } 
    }, 
    "require": { 
     "cboden/ratchet": "^0.3.3" 
    } 
} 

在我src文件夾我添加了一個文件夾MyClass並有一個文件Foo.php看起來是這樣的:

<?php 
class Foo{ 
    function __construct(){ 
     echo "Foo construct!\n"; 
    } 
} 

我怎麼能得到一個新的Foo在我SocketControler例如像:

<?php 
namespace Websocket; 
use Ratchet\MessageComponentInterface; 
use Ratchet\ConnectionInterface; 

class SocketControl implements MessageComponentInterface { 
    protected $clients; 
    protected $foo; 

    public function __construct() { 
     $this->clients = new \SplObjectStorage; 
     $this->foo = new Foo(); 
     echo "New construct!\n"; 
    } 

    public function onOpen(ConnectionInterface $conn) { 
     // Store the new connection to send messages to later 
     $this->clients->attach($conn); 

     echo "New connection! ({$conn->resourceId})\n"; 
    } 

    public function onMessage(ConnectionInterface $from, $msg) { 
     $numRecv = count($this->clients) - 1; 
     echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n" 
      , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's'); 

     foreach ($this->clients as $client) { 
      if ($from !== $client) { 
       // The sender is not the receiver, send to each client connected 
       $client->send($msg); 
      } 
     } 
    } 

    public function onClose(ConnectionInterface $conn) { 
     // The connection is closed, remove it, as we can no longer send it messages 
     $this->clients->detach($conn); 

     echo "Connection {$conn->resourceId} has disconnected\n"; 
    } 

    public function onError(ConnectionInterface $conn, \Exception $e) { 
     echo "An error has occurred: {$e->getMessage()}\n"; 

     $conn->close(); 
    } 
} 
+1

您告訴作曲者Websocket名稱空間位於src目錄中。所以如果你將foo設置爲命名空間Websocket \ MyClass,並嘗試使用Websocket \ MyClass \ Foo,它應該可以工作。 – JimL

+0

@JimL我不知道如何告訴作曲家? – K3NN3TH

+0

我將Foo類文件移動到Websocket fodler中,並將其名稱空間設置爲Websocket,並且可以工作,但我應該理解爲什麼我無法在不同的目錄中使用不同的名稱空間訪問它 – K3NN3TH

回答

2

的一兩件事是:你一定要了解PHP命名空間的工作?由於自動加載是一回事,爲了讓事情順利進行,您最好使用老式的require_once()來查看您的代碼是否正常工作或存在問題。

自動加載本身應該非常直接,但是如果你沒有弄清你的命名空間問題,它會混淆你。問題不在於自動加載無法正常工作,而是由於代碼請求不能自動加載的類名,因爲類本身的名稱是錯誤的。

例如,在您的代碼中,您位於命名空間「Websocket」中,並且此代碼爲new Foo()。這將嘗試自動加載類Websocket\Foo。你有這堂課嗎?沒有!你有class Foo...,但你沒有把namespace Websocket;作爲第一個代碼行。

自動加載會告訴你,PHP無法加載Websocket\Foo,但爲什麼?你的自動加載定義是這樣說的:每個以命名空間Websocket\開頭的類都在路徑「src /」中。所以PSR-4創建路徑「src/Foo.php」來找到Websocket\Foo。但是,該文件中的代碼不會聲明這樣的類!它在全局命名空間中聲明\Foo。執行該文件後,沒有定義類Websocket\Foo,這會使代碼失敗。

請注意,PHP名稱空間和文件系統佈局之間沒有直接連接。從理論上講,您可以將各種名稱空間分散在任何類型的文件佈局中。這只是爲了方便的原因,選擇1:1的類名映射到路徑名 - 它不是由PHP強制執行,也不保證在自動加載代碼時工作,即在正確位置的代碼文件仍然必須有正確的代碼堅持承諾宣佈一個正確的名字。

相關問題