php 實(shí)現(xiàn)數(shù)據(jù)庫連接池、直播平臺秒殺 計(jì)數(shù)器 直播
yaf項(xiàng)目快速開發(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操作類支持鏈?zhǔn)讲僮鳎С肿x寫分離,pdo,mysqli,mongo,upload操作, 加入redis操作以及微信分享,加入微信支付,加入swoole的支持, 已支持swoole_http_server,swoole_websocket_server,高并發(fā)搶購、秒殺,數(shù)組算法處理等,添加了后臺admin模塊,集成表格樹!添加基于swoole的數(shù)據(jù)庫連接池,支持自定義加載目錄類文件和函數(shù)文件(通過插件的形式實(shí)現(xiàn)的) 在/application/controllers/Index.php里添加了yac、yaconf的使用,通過yac實(shí)現(xiàn)高并發(fā)計(jì)數(shù)器,加入swoole實(shí)現(xiàn)簡單的視頻直播,加入了網(wǎng)頁控制臺的實(shí)現(xiàn)例如:http://localhost/console/console.php
swoole實(shí)現(xiàn)簡單的視頻直播(可以實(shí)時傳音頻、視頻、聊天)
需要php以cli模式運(yùn)行/server/swoole/SwooleLiveServer.php 錄制視頻頁面 http://localhost/index/swoolelivecamera 接受視頻頁面 http://localhost/index/swoolelive
composer 安裝
{ "require": { "yaffastdemo/yaf": "dev-master" } }
數(shù)據(jù)庫連接池使用方法
服務(wù)文件在/server/mysql/DbServer.php
簡單地封裝文件在/application/library/mysql/dbclient.php
配置在conf/application.ini中
;數(shù)據(jù)庫連接池配置
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ù)庫連接池多進(jìn)程執(zhí)行如下:
后臺訪問:http://localhost/admin/user/index
添加了紅包生成算法(拼手氣紅包和普通紅包),詳情見:https://github.com/qieangel2013/php_ext_zqf
需要安裝php擴(kuò)展zqf $obj=new zqf(); 第一個參數(shù)是紅包總額,第二個人參數(shù)紅包數(shù)量,第三個參數(shù)默認(rèn)代表拼手氣紅包,設(shè)置為1的話為普通紅包 拼手氣紅包 $hongb= $obj->hongbao(10,8);或者$hongb= $obj->hongbao(10,8,0);返回數(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 ) 普通紅包,每個人數(shù)額一樣設(shè)置第三個參數(shù) $hongb= $obj->hongbao(10,8,1);返回數(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ā)搶購、秒殺,數(shù)組算法處理等詳情見:https://github.com/qieangel2013/php_ext_zqf
需要安裝php擴(kuò)展zqf
首先安裝php擴(kuò)展zqf.so
phpize來安裝
然后在php文件調(diào)用
dl('zqf.so');或者phpini里加載
$obj=new zqf();
$counter= $obj->autoadd(0,1,0);(聲明只針對多線程)
echo $counter;
添加了分頁類
$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)證碼類
$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();
添加了生成二維碼功能,詳情見:https://github.com/qieangel2013/php_ext_zqf
需要安裝php擴(kuò)展zqf
$obj=new zqf();
$obj->savefile('https://www.baidu.com/s?wd=昌平香堂','./test.png',500);第一個參數(shù)是url,第二參數(shù)是保存路徑,第三個參數(shù)是二維碼長或者寬
生成透明二維碼,詳情見:https://github.com/qieangel2013/php_ext_zqf
$obj=new zqf();
$obj->savefile('https://www.baidu.com/s?wd=昌平香堂','./test.png',500,1);第一個參數(shù)是url,第二參數(shù)是保存路徑,第三個參數(shù)是二維碼長或者寬,第四個參數(shù)是決定是否透明,默認(rèn)是不透明的
自定義自動加載配置如下:
;可以任意加載多個目錄類和目錄函數(shù)用,隔開 例如:application.autolibrary='job,common';application.autofunction='pro,function' 支持深度查找目錄,如果不想開啟可以不用配置 application.autolibrary='common' application.autofunction='function' ;如果不想開啟可以不用配置
db操作類讀寫分離配置如下:
;數(shù)據(jù)庫驅(qū)動類型 database.config.type='mysql' ;服務(wù)器地址 database.config.host='192.168.0.1,192.168.0.2' ;數(shù)據(jù)庫名 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ù)庫編碼默認(rèn)采用utf8 database.config.charset='utf8' ;數(shù)據(jù)庫部署方式:0 集中式(單一服務(wù)器),1 分布式(主從服務(wù)器) database.config.deploy_type=1 ;數(shù)據(jù)庫讀寫是否分離 主從式有效 database.config.rw_separate=true ;讀寫分離后 主服務(wù)器數(shù)量 database.config.master_num=1 ;指定從服務(wù)器序號 database.config.slave_no=''
db操作類使用方法如下:
$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) {// 上傳錯誤提示錯誤信息
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"); //商戶訂單號
$unifiedOrder->setParameter("total_fee", "0101"); //總金額 $total
$unifiedOrder->setParameter("notify_url", wx_pay_config::NOTIFY_URL); //通知地址
$unifiedOrder->setParameter("trade_type", "JSAPI"); //交易類型
$unifiedOrder->setParameter("openid", $openid); //用戶標(biāo)識
$prepay_id = $unifiedOrder->getPrepayId();
$jsApi->setPrepayId($prepay_id);
$jsApiParameters = $jsApi->getParameters();
swoole作為http_server操作使用方法如下:
根目錄下有server集成了swoole服務(wù)端 (后臺運(yùn)行直接php執(zhí)行)
HttpServer.php (linux環(huán)境下直接執(zhí)行php HttpServer.php)
http_server實(shí)現(xiàn)原理是把swoole作為底層處理請求,然后通過php-cli把url交給
yaf來處理,yaf只是作為一個框架使用
swoole作為http_server的調(diào)用如下:
在瀏覽器里輸入http://www.xxx.com:9501/index/swoolehttp,生產(chǎn)環(huán)境可以把監(jiān)聽端口改為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);//通過swoole返回給瀏覽器結(jié)果{"id":37936}
}
swoole作為websocket_server操作使用方法如下:
根目錄下有server集成了swoole服務(wù)端 (后臺運(yùn)行直接php執(zhí)行)
WebSocketServer.php (linux環(huán)境下直接執(zhí)行php WebSocketServer.php)
websocket_server實(shí)現(xiàn)原理是把swoole作為websocket服務(wù)器,然后通過php-cli把參數(shù)傳給
yaf來處理,yaf來處理邏輯
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請求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)聽ip及端口號
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>
