❶ php7使用use引入命名空間提示語法錯誤
我也遇到了這個問題,我是這樣解決的,我伺服器裝了5.2和7.2兩個版本,可能兩者有沖突,5.2不支持命名空間,不支持use和namespace,解決辦法就是卸載5.2版本!!!
❷ PHP+Laravel框架RabbitMQ簡單使用(PTP)
一、簡介Point-to-Point,點對點通信模型。PTP是基於隊列(Queue)的,一個隊列可以有多個生產者,和多個消費者。消息伺服器按照收到消息的先後順序,將消息放到隊列中。隊列中的每一條消息,只能由一個消費者進行消費,消費之後就會從隊列中移除。
特點:
每個消息只用一個消費者;
發送者和接受者沒有時間依賴;
接受者確認消息接受和處理成功。
P 表示為生產者 、C 表示為消費者,紅色表示隊列。
在RabbitMQ中有生產者,消費者的概念,本篇主要是消息如何生產以及消費者這部分的實現。使用的laravel框架,php-amqplib拓展。
二、Laravel中添加依賴在項目根目錄下執行一下命令
composer require php-amqplib/php-amqplib
lishuo@李碩的MacBook?Pro:~/Code/php/www.zfw.com?(branch:?master!)$?composer?require?php-amqplib/php-amqplibUsing?version?^3.1?for?php-amqplib/php-amqplib./composer.json?has?been?updatedRunning?composer?update?php-amqplib/php-amqplibLoading?composer?repositories?with?package?informationUpdating?dependenciesNothing?to?modify?in?lock?fileInstalling?dependencies?from?lock?file?(including?require-dev)Nothing?to?install,?update?or?removePackage?caouecs/laravel-lang?is?abandoned,?you?should?avoid?using?it.?Use?https://github.com/Laravel-Lang/lang?instead.Package?swiftmailer/swiftmailer?is?abandoned,?you?should?avoid?using?it.?Use?symfony/mailer?instead.Generating?optimized?autoload?files>?::postAutoloadDump>?@php?artisan?package:discover?--ansiDiscovered?Package:?barryvdh/laravel-ide-helperDiscovered?Package:?facade/ignitionDiscovered?Package:?fruitcake/laravel-corsDiscovered?Package:?jenssegers/mongodbDiscovered?Package:?laravel/passportDiscovered?Package:?laravel/sailDiscovered?Package:?laravel/sanctumDiscovered?Package:?laravel/tinkerDiscovered?Package:?maatwebsite/excelDiscovered?Package:?nesbot/carbonDiscovered?Package:?nunomaro/collisionPackage?manifest?generated?successfully.100?packages?you?are?using?are?looking?for?funding.Use?the?`composer?fund`?command?to?find?out?more!>?@php?artisan?vendor:publish?--tag=laravel-assets?--ansiNo?publishable?resources?for?tag?[laravel-assets].Publishing?complete.三、使用Laravel的command來實現消息的生產和消費1.創建生產者執行以下命令快速創建生產者
php artisan make:command RabbitmqProcerCommand
lishuo@李碩的MacBook?Pro:~/Code/php/www.zfw.com?(branch:?master!)$?php?artisan?make:command?RabbitmqProcerCommandConsole?command?created?successfully.基本代碼(接下來就在command裡面寫生產消息的邏輯)<?phpnamespace?AppConsoleCommands;use?IlluminateConsoleCommand;//引入amqp擴展use?;use?PhpAmqpLibMessageAMQPMessage;class?RabbitmqProcerCommand?extends?Command{????/**?????*?The?name?and?signature?of?the?console?command.?????*?????*?@var?string?????*/????protected?$signature?=?'rabbitmq_procer'//給生產者起個command名稱????/**?????*?The?console?command?description.?????*?????*?@var?string?????*/????protected?$description?=?'Command?description'????/**?????*?Create?a?new?command?instance.?????*?????*?@return?void?????*/????public?function?__construct()????{????????parent::__construct();????}????/**?????*?Execute?the?console?command.?????*??生產者消息代碼?????*?@return?int?????*/????public?function?handle()????{????????//創建伺服器連接????????$connection?=?new?AMQPStreamConnection('localhost',?5672,?'guest',?'guest');????????//連接信道????????//信道是生產消費者與rabbit通信的渠道,生產者publish或者消費者消費一個隊列都是需要通過信道來通信的????????//信道是建立在TCP上面的虛擬鏈接,也就是rabbitMQ在一個TCP上面建立成百上千的信道來達到多個線程處理。????????//注意是一個TCP?被多個線程共享,每個線程對應一個信道,信道在rabbit都有唯一的ID,保證了信道的私有性,對應上唯一的線程使用。????????$channel?=?$connection->channel();????????//channel->queue_declare通過信道創建一個是否是持久化的消息隊列????????//queue第一個參數代表消息隊列名稱????????$channel->queue_declare('test',?false,?false,?false,?false);????????//往隊列里要發送內容,待發送的內容????????$msg?=?new?AMQPMessage('我是一個生產者消息');????????//通過信道來進行發送消息????????//而exchange是怎麼知道消息應該推到哪個queue呢,這就要通過綁定queue與exchange時的routingkey了,通過代碼進行綁定並且指定routingkey,下面有一張關系圖,p(發布者)?—>?x(exchange)?bindding(綁定關系也就是我們的routingkey)?紅色代表著queue????????$channel->basic_publish($msg,?'',?'test');????????echo?"?[x]?Sent?'我是一個生產者消息!' ";????????//關閉信道????????$channel->close();????????//關閉連接????????$connection->close();????}}2.創建消費者因為消費者是需要常駐內存的,所以需要在cli下運行,我們可以通過以下操作創建一個任務。
?php?artisan?make:command?RabbitmqConsumerCommand基本代碼(接下來就在command裡面寫消費消息的邏輯)<?phpnamespace?AppConsoleCommands;use?IlluminateConsoleCommand;use?;class?RabbitmqConsumerCommand?extends?Command{????/**?????*?The?name?and?signature?of?the?console?command.?????*?????*?@var?string?????*/????protected?$signature?=?'rabbitmq_consumer'//給消費者起個command名稱????/**?????*?The?console?command?description.?????*?????*?@var?string?????*/????protected?$description?=?'Command?description'????/**?????*?Create?a?new?command?instance.?????*?????*?@return?void?????*/????public?function?__construct()????{????????parent::__construct();????}????/**?????*?Execute?the?console?command.?????*?????*?@return?int?????*/????public?function?handle()????{????????//創建伺服器連接????????$connection?=?new?AMQPStreamConnection('localhost',?5672,?'guest',?'guest');????????//連接信道????????//信道是生產消費者與rabbit通信的渠道,生產者publish或者消費者消費一個隊列都是需要通過信道來通信的????????//信道是建立在TCP上面的虛擬鏈接,也就是rabbitMQ在一個TCP上面建立成百上千的信道來達到多個線程處理。????????//注意是一個TCP?被多個線程共享,每個線程對應一個信道,信道在rabbit都有唯一的ID,保證了信道的私有性,對應上唯一的線程使用。????????$channel?=?$connection->channel();????????//channel->queue_declare通過信道創建一個是否是持久化的消息隊列????????//queue第一個參數代表消息隊列名稱????????$channel->queue_declare('test',?false,?false,?false,?false);????????echo?"?[*]?Waiting?for?messages.?To?exit?press?CTRL+C ";????????//進行監聽消費者是否有消息,如果有進行輸出消息內容????????$callback?=?function?($msg)?{????????????echo?'?[x]?Received?',?$msg->body,?" ";????????};????????//通過信道進行消費消息????????$channel->basic_consume('test',?'',?false,?true,?false,?false,?$callback);????????//如果信道是打開狀態????????while?($channel->is_open())?{????????????//然後讓信道一直處於監聽等待狀態????????????$channel->wait();????????}????????//關閉信道????????$channel->close();????????//關閉連接????????$connection->close();????}}三、使用command進行測試生產消息和消費消息是否成功執行生產消息 php artisan rabbitmq_procer 執行消費消息 hp artisan rabbitmq_consumer
❸ PHP 為什麼要使用命名空間,命名空間的作用
命名空間一個最明確的目的就是解決重名問題,PHP中不允許兩個函數或者類出現相同的名字,否則會產生一個致命的錯誤。這種情況下只要避免命名重復就可以解決,最常見的一種做法是約定一個前綴。
舉個栗子:項目中有兩個模塊:article和message board,它們各自有一個處理用戶留言的類Comment。之後我可能想要增加對所有用戶留言的一些信息統計功能,比如說我想得到所有留言的數量。這時候調用它們Comment提供的方法是很好的做法,但是同時引入各自的Comment類顯然是不行的,代碼會出錯,在另一個地方重寫任何一個Comment也會降低維護性。那這時只能重構類名,我約定了一個命名規則,在類名前面加上模塊名,像這樣:Article_Comment、MessageBoard_Comment
可以看到,名字變得很長,那意味著以後使用Comment的時候會寫上更多的代碼(至少字元多了)。並且,以後如果要對各個模塊增加更多的一些整合功能,或者是互相調用,發生重名的時候就需要重構名字。當然在項目開始的時候就注意到這個問題,並規定命名規則就能很好的避免這個問題。另一個解決方法可以考慮使用命名空間。
基礎
命名空間將代碼劃分出不同的空間(區域),每個空間的常量、函數、類(為了偷懶,我下邊都將它們稱為元素)的名字互不影響, 這個有點類似我們常常提到的『封裝'的概念。
創建一個命名空間需要使用namespace關鍵字,這樣:
復制代碼代碼如下:
<?php
//創建一個名為'Article'的命名空間
namespace Article;
?>
要注意的是,當前腳本文件的第一個命名空間前面不能有任何代碼,下面的寫法都是錯誤的:
復制代碼代碼如下:
//例一
//在腳本前面寫了一些邏輯代碼
<?php
$path = "/";
class Comment { }
namespace Article;
?>
//例二
//在腳本前面輸出了一些字元
<html></html>
<?php
namespace Article;
?>
為什麼要說第一個命名空間呢?因為同一腳本文件中可以創建多個命名空間。
下面我創建了兩個命名空間,順便為這兩個空間各自添加了一個Comment類元素:
復制代碼代碼如下:
<?php
//創建一個名為'Article'的命名空間
namespace Article;
//此Comment屬於Article空間的元素
class Comment { }
//創建一個名為'MessageBoard'的命名空間
namespace MessageBoard;
//此Comment屬於MessageBoard空間的元素
class Comment { }
?>
在不同空間之間不可以直接調用其它元素,需要使用命名空間的語法:
復制代碼代碼如下:
<?php
namespace Article;
class Comment { }
namespace MessageBoard;
class Comment { }
//調用當前空間(MessageBoard)的Comment類
$comment = new Comment();
//調用Article空間的Comment類
$article_comment = new \Article\Comment();
?>
可以看到,在MessageBoard空間中調用article空間里的Comment類時,使用了一種像文件路徑的語法: \空間名\元素名
除了類之外,對函數和常量的用法是一樣的,下面我為兩個空間創建了新的元素,並在MessageBoard空間中輸出了它們的值。
復制代碼代碼如下:
<?php
namespace Article;
const PATH = '/article';
function getCommentTotal() {
return 100;
}
class Comment { }
namespace MessageBoard;
const PATH = '/message_board';
function getCommentTotal() {
return 300;
}
class Comment { }
//調用當前空間的常量、函數和類
echo PATH; ///message_board
echo getCommentTotal(); //300
$comment = new Comment();
//調用Article空間的常量、函數和類
echo \Article\PATH; ///article
echo \Article\getCommentTotal(); //100
$article_comment = new \Article\Comment();
?>
然後我的確得到了Article空間的元素數據。
子空間
命名空間的調用語法像文件路徑一樣是有道理的,它允許我們自定義子空間來描述各個空間之間的關系。