PHP安裝&使用yar框架

一、yar什麼

Yar是並行的RPC框架(Concurrent RPC framework),Laruence開發。

二、安裝yar

yar全部可用版本見:https://pecl.php.net/package/yar,根據自己的需要下載編譯安裝即可。
注:yar和PHP版本不一致會導致編譯失敗,如果出現編譯失敗請下載其他版本的yar重新編譯

# wget https://pecl.php.net/get/yar-1.2.3.tgz
# tar -xf yar-1.2.3.tgz 
# cd yar-1.2.3
#  ls
config.m4   LICENSE    tests       yar.c         yar_exception.c  yar_packager.h  yar_request.c   yar_response.h  yar_transport.c
config.w32  packagers  tools       yar_client.c  yar_exception.h  yar_protocol.c  yar_request.h   yar_server.c    yar_transport.h
CREDITS     php_yar.h  transports  yar_client.h  yar_packager.c   yar_protocol.h  yar_response.c  yar_server.h
#  ls /usr/local/php/php7/bin/
pear  peardev  pecl  phar  phar.phar  php  php-cgi  php-config  phpdbg  phpize
#  /usr/local/php/php7/bin/phpize
Configuring for:
PHP Api Version:         20170718
Zend Module Api No:      20170718
Zend Extension Api No:   320170718
#  ./configure --with-php-config=/usr/local/php/php7/bin/php-config
#  make && make install
................
............
Installing shared extensions:     /usr/local/php/php7/lib/php/extensions/no-debug-non-zts-20170718/

#  ls /usr/local/php/php7/lib/php/extensions/no-debug-non-zts-20170718/
mongodb.so  opcache.a  opcache.so  openssl.so  pcntl.so  phalcon.so  redis.so  swoole.so  xhprof.so  yaf.so  yar.so  zlib.so
 

三、配置php.ini 文件

我是PHP5.6 ,我的這個文件在/usr/local/php/etc這個目錄下,不同版本的PHP該文件所在的位置可能會有不同。

在文件末尾追加以下內容就行:

extension=/usr/local/php/php7/lib/php/extensions/no-debug-non-zts-20170718/yar.so      
或者直接:
extension=yar.so

憨憨們注意了,我的php.ini原文件是這樣的,相信你們的也差不多:

[XXX];
 If openssl.cafile is not specified or if the CA file is not found, the
; directory pointed to by openssl.capath is searched for a suitable
; certificate. This value must be a correctly hashed certificate directory.
; Most users should not specify a value for this directive as PHP will
; attempt to use the OS-managed cert stores in its absence. If specified,
; this value may still be overridden on a per-stream basis via the "capath"
; SSL stream context option.
;openssl.capath=
; Local Variables:
; tab-width: 4
;End:

仔細看到這裏的童靴應該和我一樣,是第一次接觸PHP這個垃圾語言腳本語言,中Java的毒已久的我還以爲配置文件裏面的英文分號“;”是該文件特有的分隔符號,於是我追加成下面這樣了:

; Local Variables:
; tab-width: 4
; extension=yar.so //end是結束的意思,那必須要放在那之前啊,你有分號我也寫上分號,照着你的格式來 [手動捂臉]
; End:

注意了,人家的這個分號是註釋鍵!相當於:
Java的"//“和”/* 註釋的內容*/",
JS 的"//",
HTML的"<!- 註釋的內容 ->"
python的“#”,
shell 的“#”。
所以要這麼配置:

; Local Variables:
; tab-width: 4
; End:

extension=yar.so    //分號開頭的是人家註釋掉的內容,我們不管,直接在文末追加你的內容即可。

四、測試yar安裝結果:

執行 php --ri yar 命令,查看輸出:

[root@localhost default]# php --ri yar

yar

yar support => enabled
Version => 1.2.3

Directive => Local Value => Master Value
yar.packager => php => php
yar.transport => curl => curl
yar.debug => Off => Off
yar.expose_info => On => On
yar.connect_timeout => 1000 => 1000
yar.timeout => 5000 => 5000
yar.content_type => application/octet-stream => application/octet-stream
yar.allow_persistent => 0 => 0
[root@localhost default]# 

如果你的輸出類似我上面的輸出,那麼你的yar就是安裝成功的,否則安裝失敗。

至此yar安裝完成

五、使用

摘自於yar框架的作者鳥哥的文章:https://www.laruence.com/2012/09/15/2779.html
Server端(server.php):

<?php
class API {
    /**
     * the doc info will be generated automatically into service info page.
     * @params
     * @return
     */
    public function api($parameter, $option = "foo") {
    echo "hello world ! ";
    }
 
    protected function client_can_not_see() {
    }
}
 
$service = new Yar_Server(new API());
$service->handle();
?>

訪問:http://yourip/server.php 我們就會看到如下的接口文檔:

Yar Server: API
+API::api($parameter, $option = 'foo')

沒看見也不要慌,比如我剛開始就沒看見這個,網上絕大多都是這個例子抄來抄去 的,但是卻極少有人說看不到咋辦。試試下面這個:

  • 首先確認下你的yar是否正常安裝上了,php --ri yar 看看結果。
  • 關閉yar的debug選項:
    vim php.ini
    yar.debug=0 ;或者註釋掉即可

Client端也很簡單,有2種:
1)串行:

<?php
$client = new Yar_Client("http://host/server.php");
$result = $client->api("parameter);
?>

2)並行化調用

<?php
function callback($retval, $callinfo) {
     var_dump($retval);
}
 
Yar_Concurrent_Client::call("http://host/api/", "api", array("parameters"), "callback");
Yar_Concurrent_Client::call("http://host/api/", "api", array("parameters"), "callback");
Yar_Concurrent_Client::call("http://host/api/", "api", array("parameters"), "callback");
Yar_Concurrent_Client::call("http://host/api/", "api", array("parameters"), "callback");
Yar_Concurrent_Client::loop(); //send
?>

這樣, 所有的請求會一次發出, 只要有任何一個請求完成, 回調函數”callback”就會被立即調用.

這裏還有一個細節, Yar見縫插針的不會浪費任何時間, 在這些請求發送完成以後, Yar會調用一次callback, 和普通的請求返回回調不同, 這次的調用的$callinfo參數爲空.

五、實例

server端:yar.php

<?php

class API {
    /**
     * the doc info will be generated automatically into service info page.
     * @params
     * @return
     */
    public function test() {
        sleep(1);
        return 't';
        
    }
    
    public function test2() {
        sleep(3);
        return 'test2';
    }

}

?>
 
$service = new Yar_Server(new API());
$service->handle();

直接在瀏覽器打開http://localhost/yar.php會顯示API文檔。

client端:yar_client.php

<?php

//串行調用
//$client = new Yar_Client("http://localhost/yar.php");
//$client->test();
//$client->test2();

function callback($retval, $callinfo) {
    //var_dump($retval);
    
    error_log(time().':callinfo:'.json_encode($callinfo).PHP_EOL, 3, 't.log');
    
    if ($callinfo == NULL) {
       //做本地的邏輯
       //return TRUE;
       error_log(time().':'.'send req success'.PHP_EOL, 3, 't.log');
    }else{
        error_log(time().':'.$retval.PHP_EOL, 3, 't.log');
    }
    
    
     
}

function callback2($retval, $callinfo) {
   
     
}

function error_callback($type, $error, $callinfo) {
    error_log($error);
}

//並行調用:
//1、所有請求發送成功,Yar會調用一次callback,其中$callinfo爲null
//2、每個請求執行完成,獲取到了結果,也會去調用callback,其中$callinfo不爲null
$res = Yar_Concurrent_Client::call("http://localhost/yar.php", "test");
$res1 = Yar_Concurrent_Client::call("http://localhost/yar.php", "test2");
$res2 = Yar_Concurrent_Client::loop("callback", "error_callback");  //send

?>

t.log:

1472832899:callinfo:null
1472832899:send req success
1472832900:callinfo:{"sequence":1,"uri":"http:\/\/localhost\/yar.php","method":"test"}
1472832900:t
1472832902:callinfo:{"sequence":2,"uri":"http:\/\/localhost\/yar.php","method":"test2"}
1472832902:test2

log驗證了yar的執行過程。那麼,實際應用中,我們就可以先發送請求, 請求發送完畢,然後得到第一次回調($callinfo爲null), 繼續做我們當前進程的工作; 等所有工作結束以後, 再交給Yar去獲取並行RPC的響應:

<?php
function callback($retval, $callinfo) {
    if ($callinfo == NULL) {
        //請求發送完畢,會運行到這裏
        //做本地的邏輯
       return TRUE;
    }
 
     //RPC請求返回, callback會再次調用。返回值在$retval
}

實際項目裏,Server端裏爲避免每次實例化當前類,可以寫個父類:

<?php

/**
 *Yar控制器類
 */
class YarAction{

	/**
	 * 架構函數
	 * @access public
	 */
	public function __construct() {

		//判斷擴展是否存在
		if(!extension_loaded('yar'))
			die('yar not support');
		//實例化Yar_Server
		$server     =   new Yar_Server($this);
		// 啓動server
		$server->handle();
	}
}

參考資料:https://www.cnblogs.com/52fhy/p/5836065.html,感謝原文作者的無私分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章