php 實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接池、直播平臺(tái)秒殺 計(jì)數(shù)器 直播
yaf項(xiàng)目快速開(kāi)發(fā)(兼容php7):
yaf project rapid development, integration of the db action class support chain operation, support separate read and write, pdo, mysqli, mongo, upload operation, adding redis operations and weixin sharing, will then join weixin pay 集成了db操作類(lèi)支持鏈?zhǔn)讲僮鳎С肿x寫(xiě)分離,pdo,mysqli,mongo,upload操作, 加入redis操作以及微信分享,加入微信支付,加入swoole的支持, 已支持swoole_http_server,swoole_websocket_server,高并發(fā)搶購(gòu)、秒殺,數(shù)組算法處理等,添加了后臺(tái)admin模塊,集成表格樹(shù)!添加基于swoole的數(shù)據(jù)庫(kù)連接池,支持自定義加載目錄類(lèi)文件和函數(shù)文件(通過(guò)插件的形式實(shí)現(xiàn)的) 在/application/controllers/Index.php里添加了yac、yaconf的使用,通過(guò)yac實(shí)現(xiàn)高并發(fā)計(jì)數(shù)器,加入swoole實(shí)現(xiàn)簡(jiǎn)單的視頻直播,加入了網(wǎng)頁(yè)控制臺(tái)的實(shí)現(xiàn)例如:http://localhost/console/console.php
swoole實(shí)現(xiàn)簡(jiǎn)單的視頻直播(可以實(shí)時(shí)傳音頻、視頻、聊天)
需要php以cli模式運(yùn)行/server/swoole/SwooleLiveServer.php 錄制視頻頁(yè)面 http://localhost/index/swoolelivecamera 接受視頻頁(yè)面 http://localhost/index/swoolelive
composer 安裝
{ "require": { "yaffastdemo/yaf": "dev-master" } }
數(shù)據(jù)庫(kù)連接池使用方法
服務(wù)文件在/server/mysql/DbServer.php
簡(jiǎn)單地封裝文件在/application/library/mysql/dbclient.php
配置在conf/application.ini中
;數(shù)據(jù)庫(kù)連接池配置
DbServer.async=true //配置是同步執(zhí)行還是異步執(zhí)行,默認(rèn)不配置代表異步執(zhí)行,同步執(zhí)行設(shè)置為false
DbServer.multiprocess=false //配置是否啟用多進(jìn)程,默認(rèn)不配置代表單進(jìn)程阻塞模式,多進(jìn)程模式要設(shè)置為true
DbServer.pool_num=20 //配置連接池mysql的數(shù)量
DbServer.port=9501
DbServer.logfile="/server/log/DbServer.log"
DbServer.localip="192.168.2.13"
使用方法:
$dbclient=new mysql_dbclient;
//print_r($data);
for ($i=0; $i <100 ; $i++) {
$dbclient->query("INSERT INTO user(name) VALUES('$i')");
//echo "INSERT INTO user(name) VALUES('$i')";
}
$data=$dbclient->query("select * from user");
$dbclient->close();
print_r($data);
exit;
數(shù)據(jù)庫(kù)連接池多進(jìn)程執(zhí)行如下:
后臺(tái)訪問(wèn):http://localhost/admin/user/index
添加了紅包生成算法(拼手氣紅包和普通紅包),詳情見(jiàn):https://github.com/qieangel2013/php_ext_zqf
需要安裝php擴(kuò)展zqf $obj=new zqf(); 第一個(gè)參數(shù)是紅包總額,第二個(gè)人參數(shù)紅包數(shù)量,第三個(gè)參數(shù)默認(rèn)代表拼手氣紅包,設(shè)置為1的話為普通紅包 拼手氣紅包 $hongb= $obj->hongbao(10,8);或者$hongb= $obj->hongbao(10,8,0);返回?cái)?shù)組為Array ( [0] => 1.33 [1] => 1.02 [2] => 1.28 [3] => 0.44 [4] => 1.37 [5] => 0.81 [6] => 1.81 [7] => 1.94 ) 普通紅包,每個(gè)人數(shù)額一樣設(shè)置第三個(gè)參數(shù) $hongb= $obj->hongbao(10,8,1);返回?cái)?shù)組為Array ( [0] => 1.25 [1] => 1.25 [2] => 1.25 [3] => 1.25 [4] => 1.25 [5] => 1.25 [6] => 1.25 [7] => 1.25 ) var_dump($hongb);
添加了全局變量適用于高并發(fā)搶購(gòu)、秒殺,數(shù)組算法處理等詳情見(jiàn):https://github.com/qieangel2013/php_ext_zqf
需要安裝php擴(kuò)展zqf
首先安裝php擴(kuò)展zqf.so
phpize來(lái)安裝
然后在php文件調(diào)用
dl('zqf.so');或者phpini里加載
$obj=new zqf();
$counter= $obj->autoadd(0,1,0);(聲明只針對(duì)多線程)
echo $counter;
添加了分頁(yè)類(lèi)
$Page = new Page($count,$pageoffset); $show = $Page->show();
添加了swoole的task服務(wù)器,并實(shí)現(xiàn)拆包處理任務(wù)算法
$task=new swoole_taskclient();
//拆分?jǐn)?shù)據(jù)算法
$count_num_pre=$data['prenum'];
$count_num=$data['appendnum'];
$count_size=10000;//拆分?jǐn)?shù)據(jù)算法
if($count_num>$count_size){
$z_str=floor($count_num/$count_size);
$y_str=fmod($count_num,$count_size);
$data['explodenum']=$y_str==0?$z_str:$z_str+1;
for ($i=1; $i <$z_str+1 ; $i++) {
$data['appendnum']=$count_size;
$data['explodecount']=$i;
$task->connect(json_encode($data));
$data['prenum'] +=$count_size;
}
if($y_str){
$data['appendnum']=$y_str;
$data['explodecount']=$z_str+1;
$task->connect(json_encode($data));
}}else{
$task->connect(json_encode($data));
}
添加了驗(yàn)證碼類(lèi)
$config = array( 'fontSize' => 30, // 驗(yàn)證碼字體大小 'length' => 4, // 驗(yàn)證碼位數(shù) 'useNoise' => true, // 關(guān)閉驗(yàn)證碼雜點(diǎn) ); $Verify = new Verify($config); $Verify->entry();
添加了生成二維碼功能,詳情見(jiàn):https://github.com/qieangel2013/php_ext_zqf
需要安裝php擴(kuò)展zqf
$obj=new zqf();
$obj->savefile('https://www.baidu.com/s?wd=昌平香堂','./test.png',500);第一個(gè)參數(shù)是url,第二參數(shù)是保存路徑,第三個(gè)參數(shù)是二維碼長(zhǎng)或者寬
生成透明二維碼,詳情見(jiàn):https://github.com/qieangel2013/php_ext_zqf
$obj=new zqf();
$obj->savefile('https://www.baidu.com/s?wd=昌平香堂','./test.png',500,1);第一個(gè)參數(shù)是url,第二參數(shù)是保存路徑,第三個(gè)參數(shù)是二維碼長(zhǎng)或者寬,第四個(gè)參數(shù)是決定是否透明,默認(rèn)是不透明的
自定義自動(dòng)加載配置如下:
;可以任意加載多個(gè)目錄類(lèi)和目錄函數(shù)用,隔開(kāi) 例如:application.autolibrary='job,common';application.autofunction='pro,function' 支持深度查找目錄,如果不想開(kāi)啟可以不用配置 application.autolibrary='common' application.autofunction='function' ;如果不想開(kāi)啟可以不用配置
db操作類(lèi)讀寫(xiě)分離配置如下:
;數(shù)據(jù)庫(kù)驅(qū)動(dòng)類(lèi)型 database.config.type='mysql' ;服務(wù)器地址 database.config.host='192.168.0.1,192.168.0.2' ;數(shù)據(jù)庫(kù)名 database.config.name='root' ;用戶名 database.config.user='user1,user2' ;密碼 database.config.pwd='pwd1,pwd2' ;端口 database.config.port= '3306' ;啟用字段緩存 database.config.fields_cache=false ;數(shù)據(jù)庫(kù)編碼默認(rèn)采用utf8 database.config.charset='utf8' ;數(shù)據(jù)庫(kù)部署方式:0 集中式(單一服務(wù)器),1 分布式(主從服務(wù)器) database.config.deploy_type=1 ;數(shù)據(jù)庫(kù)讀寫(xiě)是否分離 主從式有效 database.config.rw_separate=true ;讀寫(xiě)分離后 主服務(wù)器數(shù)量 database.config.master_num=1 ;指定從服務(wù)器序號(hào) database.config.slave_no=''
db操作類(lèi)使用方法如下:
$where=array('id' =>37936);
$user=new HbModel('hb_users');//直接實(shí)例化給表名就行了,其他跟操作thinkphp一樣
$result=$user->where($where)->select();//支持鏈?zhǔn)讲僮?,支持pdo,mysqli,mongo
echo $user->getlastsql();
print_r($result);
exit;
redis操作使用方法如下:
$this->_redis=new phpredis();//需要安裝redis擴(kuò)展
$this->_redis->set('token',1);
upload操作使用方法如下:
$config=Yaf_Application::app()->getConfig()->upload->config->toArray();
$ftpconfig=Yaf_Application::app()->getConfig()->ftp->config->toArray();
$upload=new Upload($config, 'Ftp',$ftpconfig);
$info=$upload->upload();
if (!$info) {// 上傳錯(cuò)誤提示錯(cuò)誤信息
echo $upload->getError();
} else {// 上傳成功
if (!empty($info["UpLoadFile"]))
$pic=array("cate_pic" => $info["UpLoadFile"]['savepath'] . $info["UpLoadFile"]['savename']);
print_r($pic);
}
微信分享操作使用方法如下:
//微信分享
$jssdk=new wx_share_wxshare("你的appId", "你的appSecret");
$signPackage=$jssdk->GetSignPackage();;
$data['appId']=$signPackage['appId'];
$data['nonceStr']=$signPackage['nonceStr'];
$data['timestamp']=$signPackage['timestamp'];
$data['signature']=$signPackage['signature'];
$this->getView()->assign("token", json_encode($data));
微信支付操作使用方法如下:(具體操作在weixin控制器里)
$jsApi = new wx_pay_JsApi();
$oid=123;//訂單id
$userid=456;//用戶id
$wx_openid='';//微信授權(quán)id
if(empty($wx_openid)){
if (!isset($_GET['code'])) {
$url = wx_pay_config::JS_API_CALL_URL;
$url = str_replace('%oid%', $oid, $url);
$url = str_replace('%uid%', $userid, $url);
$url = $jsApi->createOauthUrlForCode($url);
Header("Location: $url");
} else {
$code = $_GET['code'];
$jsApi->setCode($code);
$openid = $jsApi->getOpenId();
}
}else{
$openid = $wx_openid;
}
$unifiedOrder = new wx_pay_UnifiedOrder();
$unifiedOrder->setParameter("body", "test"); //商品描述
$unifiedOrder->setParameter("out_trade_no", "1111111111"); //商戶訂單號(hào)
$unifiedOrder->setParameter("total_fee", "0101"); //總金額 $total
$unifiedOrder->setParameter("notify_url", wx_pay_config::NOTIFY_URL); //通知地址
$unifiedOrder->setParameter("trade_type", "JSAPI"); //交易類(lèi)型
$unifiedOrder->setParameter("openid", $openid); //用戶標(biāo)識(shí)
$prepay_id = $unifiedOrder->getPrepayId();
$jsApi->setPrepayId($prepay_id);
$jsApiParameters = $jsApi->getParameters();
swoole作為http_server操作使用方法如下:
根目錄下有server集成了swoole服務(wù)端 (后臺(tái)運(yùn)行直接php執(zhí)行)
HttpServer.php (linux環(huán)境下直接執(zhí)行php HttpServer.php)
http_server實(shí)現(xiàn)原理是把swoole作為底層處理請(qǐng)求,然后通過(guò)php-cli把url交給
yaf來(lái)處理,yaf只是作為一個(gè)框架使用
swoole作為http_server的調(diào)用如下:
在瀏覽器里輸入http://www.xxx.com:9501/index/swoolehttp,生產(chǎn)環(huán)境可以把監(jiān)聽(tīng)端口改為80
public function swoolehttpAction(){
Yaf_Dispatcher::getInstance()->autoRender(FALSE);
$where=array('id' =>37936);
$user=new HbModel('hb_users');//直接實(shí)例化給表名就行了,其他跟操作thinkphp一樣
$result = $user->where($where)->select();
//echo $user->getlastsql();
// echo json_encode( $result);
echo json_encode( $where);//通過(guò)swoole返回給瀏覽器結(jié)果{"id":37936}
}
swoole作為websocket_server操作使用方法如下:
根目錄下有server集成了swoole服務(wù)端 (后臺(tái)運(yùn)行直接php執(zhí)行)
WebSocketServer.php (linux環(huán)境下直接執(zhí)行php WebSocketServer.php)
websocket_server實(shí)現(xiàn)原理是把swoole作為websocket服務(wù)器,然后通過(guò)php-cli把參數(shù)傳給
yaf來(lái)處理,yaf來(lái)處理邏輯
swoole作為websocket_server的調(diào)用如下:
在瀏覽器里輸入http://www.xxx.com/index/swoolesocket
public function swoolesocketAction(){
Yaf_Dispatcher::getInstance()->autoRender(FALSE);
$this->getView()->display("index/swoolesocket.html");
}
html請(qǐng)求websocket
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="/public/js/jquery-1.8.0.min.js"></script>
<style>
#chatLog {width:440px; height:200px; border:1px solid #7F9DB9; overflow:auto;margin-bottom: 20px}
</style>
<meta charset="UTF-8">
<script type="text/javascript">
var exampleSocket = new WebSocket("ws://192.168.1.46:9503");//設(shè)為相應(yīng)的監(jiān)聽(tīng)ip及端口號(hào)
exampleSocket.onopen = function (event) {
exampleSocket.send("親!我連上啦!");
};
exampleSocket.onmessage = function (event) {
console.log(event.data);
$('#chatLog').append('<br/>'+event.data);
}
exampleSocket.onclose = function(event) {
console.log('Client notified socket has closed',event);
};
</script>
</head>
<body>
<div id="chatLog" ></div>
<input type="text" id="content">
<button onclick="exampleSocket.send( document.getElementById('content').value )">發(fā)送</button>
<button onclick="exampleSocket.send('smes_closed')">關(guān)閉</button>
</body>
</html>
