方案一:給原生APP提供api接口
網站建設哪家好,找創(chuàng)新互聯(lián)!專注于網頁設計、網站建設、微信開發(fā)、小程序定制開發(fā)、集團企業(yè)網站建設等服務項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了景縣免費建站歡迎大家使用!
使用TP框架時 放在common文件夾下文件名就叫function.php
?php
/**
*?Created?by?zhangkx
*?Email:?zkx520tnhb@163.com
*?Date:?2015/8/1
*?Time:?23:15
*/
/******?api開發(fā)輔助函數(shù)?*******/
/**
*?@param?null?$msg?返回正確的提示信息
*?@param?flag?success?CURD?操作成功
*?@param?array?$data?具體返回信息
*?Function?descript:?返回帶參數(shù),標志信息,提示信息的json?數(shù)組
*
*/
function?returnApiSuccess($msg?=?null,$data?=?array()){
$result?=?array(
'flag'?=?'Success',
'msg'?=?$msg,
'data'?=$data
);
print?json_encode($result);
}
/**
*?@param?null?$msg?返回具體錯誤的提示信息
*?@param?flag?success?CURD?操作失敗
*?Function?descript:返回標志信息?‘Error',和提示信息的json?數(shù)組
*/
function?returnApiError($msg?=?null){
$result?=?array(
'flag'?=?'Error',
'msg'?=?$msg,
);
print?json_encode($result);
}
/**
*?@param?null?$msg?返回具體錯誤的提示信息
*?@param?flag?success?CURD?操作失敗
*?Function?descript:返回標志信息?‘Error',和提示信息,當前系統(tǒng)繁忙,請稍后重試;
*/
function?returnApiErrorExample(){
$result?=?array(
'flag'?=?'Error',
'msg'?=?'當前系統(tǒng)繁忙,請稍后重試!',
);
print?json_encode($result);
}
/**
*?@param?null?$data
*?@return?array|mixed|null
*?Function?descript:?過濾post提交的參數(shù);
*
*/
function?checkDataPost($data?=?null){
if(!empty($data)){
$data?=?explode(',',$data);
foreach($data?as?$k=$v){
if((!isset($_POST[$k]))||(empty($_POST[$k]))){
if($_POST[$k]!==0??$_POST[$k]!=='0'){
returnApiError($k.'值為空!');
}
}
}
unset($data);
$data?=?I('post.');
unset($data['_URL_'],$data['token']);
return?$data;
}
}
/**
*?@param?null?$data
*?@return?array|mixed|null
*?Function?descript:?過濾get提交的參數(shù);
*
*/
function?checkDataGet($data?=?null){
if(!empty($data)){
$data?=?explode(',',$data);
foreach($data?as?$k=$v){
if((!isset($_GET[$k]))||(empty($_GET[$k]))){
if($_GET[$k]!==0??$_GET[$k]!=='0'){
returnApiError($k.'值為空!');
}
}
}
unset($data);
$data?=?I('get.');
unset($data['_URL_'],$data['token']);
return?$data;
}
}
查詢單個果品詳細信息
/**
*?發(fā)布模塊
*
*?獲取信息單個果品詳細信息
*
*/
public?function?getMyReleaseInfo(){
//檢查是否通過post方法得到數(shù)據(jù)
checkdataPost('id');
$where['id']?=?$_POST['id'];
$field[]?=?'id,fruit_name,high_price,low_price,address,size,weight,fruit_pic,remark';
$releaseInfo?=?$this-release_obj-findRelease($where,$field);
$releaseInfo['remark']?=?mb_substr($releaseInfo['remark'],0,49,'utf-8').'...';
//多張圖地址按逗號截取字符串,截取后如果存在空數(shù)組則需要過濾掉
$releaseInfo['fruit_pic']?=?array_filter(explode(',',?$releaseInfo['fruit_pic']));
$fruit_pic?=?$releaseInfo['fruit_pic'];unset($releaseInfo['fruit_pic']);
//為圖片添加存儲路徑
foreach($fruit_pic?as?$k=$v?){
$releaseInfo['fruit_pic'][]?=?'http://'.$_SERVER['HTTP_HOST'].'/Uploads/Release/'.$v;
}
if($releaseInfo){
returnApiSuccess('',$releaseInfo);
}else{
returnApiError(?'什么也沒查到(+_+)!');
}
}
findRelease()?方法的model
/**
*?查詢一條數(shù)據(jù)
*/
public?function?findRelease($where,$field){
if($where['status']?==?''?||?empty($where['status'])){
$where['status']?=?array('neq','9');
}
$result?=?$this-where($where)-field($field)-find();
return?$result;
}
app端接收到的數(shù)據(jù)(解碼json之后)
{
"flag":?"success",
"message":?"",
"responseList":?{
"id":?"2",
"fruit_name":?"蘋果",
"high_price":?"8.0",
"low_price":?"5.0",
"address":?"天津小白樓水果市場",
"size":?"2.0",
"weight":?"2.0",
"remark":?"急需...",
"fruit_pic":?[
"",
""
]
}
}
app端接收到的數(shù)據(jù)(原生json串)
代碼如下:
{"flag":"success","message":"","responseList":{"id":"2","fruit_name":"\u82f9\u679c","high_price":"8.0","low_price":"5.0","address":"\u5929\u6d25\u5c0f\u767d\u697c\u6c34\u679c\u5e02\u573a","size":"2.0","weight":"2.0","remark":"\u6025\u9700...","fruit_pic":["http:\/\/fruit.txunda.com\/Uploads\/Release\/201508\/55599e7514815.png","http:\/\/fruit.txunda.com\/Uploads\/Release\/201508\/554f2dc45b526.jpg"]}}
方案二:另外我們還可以通過ThinkPHP實現(xiàn)移動端訪問自動切換主題模板,這樣也可以做到移動端訪問
ThinkPHP的模板主題機制,如果只是在PC,只要需修改 DEFAULT_THEME (新版模板主題默認是空,表示不啟用模板主題功能)配置項就可以方便的實現(xiàn)多模板主題切換。
但對于移動端與PC端,也許你會設計完全不同的主題風格,且針對不同的來路提供不同的渲染方式,其中一種比較流行的方法是“響應式設計”,但就本人經歷而言,要實現(xiàn)完全的“響應式設計”并不是那么容易,且解決兼容問題也是個難題,假設是大型站點,比如:淘寶、百度、拍拍這些,響應式設計肯定是滿足不了需求的,而是需要針對手機訪問用戶提供單獨的手機網站。
ThinkPHP 完全能夠實現(xiàn),而且非常的簡單。與TPM的智能模版切換引擎相同,只要對來路進行判斷處理就行了。
一、將 ismobile() 加入到{項目/Common/common.php}
function?ismobile()?{
//?如果有HTTP_X_WAP_PROFILE則一定是移動設備
if?(isset?($_SERVER['HTTP_X_WAP_PROFILE']))
return?true;
//此條摘自TPM智能切換模板引擎,適合TPM開發(fā)
if(isset?($_SERVER['HTTP_CLIENT'])?'PhoneClient'==$_SERVER['HTTP_CLIENT'])
return?true;
//如果via信息含有wap則一定是移動設備,部分服務商會屏蔽該信息
if?(isset?($_SERVER['HTTP_VIA']))
//找不到為flase,否則為true
return?stristr($_SERVER['HTTP_VIA'],?'wap')???true?:?false;
//判斷手機發(fā)送的客戶端標志,兼容性有待提高
if?(isset?($_SERVER['HTTP_USER_AGENT']))?{
$clientkeywords?=?array(
'nokia','sony','ericsson','mot','samsung','htc','sgh','lg','sharp','sie-','philips','panasonic','alcatel','lenovo','iphone','ipod','blackberry','meizu','android','netfront','symbian','ucweb','windowsce','palm','operamini','operamobi','openwave','nexusone','cldc','midp','wap','mobile'
);
//從HTTP_USER_AGENT中查找手機瀏覽器的關鍵字
if?(preg_match("/("?.?implode('|',?$clientkeywords)?.?")/i",?strtolower($_SERVER['HTTP_USER_AGENT'])))?{
return?true;
}
}
//協(xié)議法,因為有可能不準確,放到最后判斷
if?(isset?($_SERVER['HTTP_ACCEPT']))?{
//?如果只支持wml并且不支持html那一定是移動設備
//?如果支持wml和html但是wml在html之前則是移動設備
if?((strpos($_SERVER['HTTP_ACCEPT'],?'vnd.wap.wml')?!==?false)??(strpos($_SERVER['HTTP_ACCEPT'],?'text/html')?===?false?||?(strpos($_SERVER['HTTP_ACCEPT'],?'vnd.wap.wml')??strpos($_SERVER['HTTP_ACCEPT'],?'text/html'))))?{
return?true;
}
}
return?false;
}
二、在{項目/Lib/}創(chuàng)建一個 CommonAction.php,假設你的項目已公共控制器,則無需創(chuàng)建,直接加在里面就行了。
Class?CommonAction?extends?Action{
Public?function?_initialize(){
//移動設備瀏覽,則切換模板
if?(ismobile())?{
//設置默認默認主題為?Mobile
C('DEFAULT_THEME','Mobile');
}
//............你的更多代碼.......
}
}
近期由于要開發(fā)公司外貿商城,需要對接Paypal支付。在開發(fā)過程中發(fā)現(xiàn)有好多坑。文檔都是英文文檔(主要還是自己英文水平不過關)、網上找的那些翻譯過的文檔老舊、沙箱環(huán)境網站卡的要讓人崩潰。整個過程真是讓人頭大,經過各種翻天覆地的百度、google、論壇終于功夫不負有心人跑通了。下面就結合網上的文檔給大家說說如何開發(fā)Paypal支付(一個Demo),避免大家在踩坑。
3.開啟PDT設置同步回調地址(這步拿到at_token return回調使用)
3.項目根目錄下創(chuàng)建return.php文件
4.項目根目錄下創(chuàng)建cancel.php文件
目前網上的文檔感覺沒有一個整體流程詳細的介紹,而且有些比較老。本篇文章是匯總整理并加入了一些自己的改造和踩坑分享而已。文介紹了paypal支付的其中一種方式,還有一種SDK的方式,這兩種有點小區(qū)別但是整體的流程還是一樣是。等后續(xù)會和大家分享另一種方式。還請各位大佬多多指教。
常規(guī)方式
常規(guī)方式就是按部就班的讀取文件了。其余的話和上述方案一致。
// 讀取配置文件內容
$handle = fopen("filepath", "r"); ? ? ? ? ? ?$content = fread($handle, filesize("filepath"));123
PHP解析XML
上述兩種讀取文件,其實都是為了PHP解析XML來做準備的。關于PHP解析XML的方式的博客有很多。方式也有很多,像simplexml,XMLReader,DOM啦等等。但是對于比較小型的xml配置文件,simplexml就足夠了。
配置文件
?xml version="1.0" encoding="UTF-8" ?mysql
!-- 為防止出現(xiàn)意外,請按照此標準順序書寫.其實也無所謂了 --
hostlocalhost/host
userroot/user
password123456/password
dbtest/db
port3306/port/mysql12345678910
解析
?php/**
* 作為解析XML配置文件必備工具
*/class XMLUtil {
public static $dbconfigpath = "./db.config.xml"; ? ?public static function getDBConfiguration() {
$dbconfig = array (); ? ? ? ?try { ? ? ? ? ? ?// 讀取配置文件內容
$handle = fopen(self::$dbconfigpath, "r"); ? ? ? ? ? ?$content = fread($handle, filesize(self::$dbconfigpath)); ? ? ? ? ? ?// 獲取xml文檔根節(jié)點,進而獲取相關的數(shù)據(jù)庫信息
$mysql = simplexml_load_string($content); ? ? ? ? ? ?// 將獲取到的xml節(jié)點信息賦值給關聯(lián)數(shù)組,方便接下來的方法調用
$dbconfig['host'] = $mysql-host; ? ? ? ? ? ?$dbconfig['user'] = $mysql-user; ? ? ? ? ? ?$dbconfig['password'] = $mysql-password; ? ? ? ? ? ?$dbconfig['db'] = $mysql-db; ? ? ? ? ? ?$dbconfig['port'] = $mysql-port; ? ? ? ? ? ?// 將配置信息以關聯(lián)數(shù)組的形式返回
return $dbconfig;
} catch ( Exception $e ) { ? ? ? ? ? ?throw new RuntimeException ( "mark讀取數(shù)據(jù)庫配置文件信息出錯!/markbr /" );
} ? ? ? ?return $dbconfig;
}
}1234567891011121314151617181920212223242526272829
數(shù)據(jù)庫連接池
對于PHP程序而言,優(yōu)化永無止境。而數(shù)據(jù)庫連接池就在一定程度上起到了優(yōu)化的作用。其使得對用戶的每一個請求而言,無需每次都像數(shù)據(jù)庫申請鏈接資源。而是通過已存在的數(shù)據(jù)庫連接池中的鏈接來返回,從時間上,效率上,都是一個大大的提升。
于是,這里簡單的模擬了一下數(shù)據(jù)庫連接池的實現(xiàn)。核心在于維護一個“池”。
從池子中取,用畢,歸還給池子。
?php/**x
* ?PHP中的數(shù)據(jù)庫 工具類設計
* ?郭璞
* ?2016年12月23日
*
**/class DbHelper { ? ?private $dbconfig; ? ?private $dbpool; ? ?public $poolsize; ? ?public function __construct($poolsize = 20) { ? ? ? ?if (! file_exists ( "./utils.php" )) { ? ? ? ? ? ?throw new RuntimeException ( "markutils.php文件丟失,無法進行配置文件的初始化操作!/markbr /" );
}else {
require './utils.php';
} ? ? ? ?// 初始化 配置文件信息
$this-dbconfig = XMLUtil::getDBConfiguration (); ? ? ? ?// 準備好數(shù)據(jù)庫連接池“偽隊列”
$this-poolsize = $poolsize;
$this-dbpool = array (); ? ? ? ?for($index = 1; $index = $this-poolsize; $index ++) {
$conn = mysqli_connect ( $this-dbconfig ['host'], $this-dbconfig ['user'], $this-dbconfig ['password'], $this-dbconfig ['db'] ) or die ( "mark連接數(shù)據(jù)庫失??!/markbr /" );
array_push ( $this-dbpool, $conn );
}
} ? ?/**
* 從數(shù)據(jù)庫連接池中獲取一個數(shù)據(jù)庫鏈接資源
*
* @throws ErrorException
* @return mixed
*/
public function getConn() { ? ? ? ?if (count ( $this-dbpool ) = 0) { ? ? ? ? ? ?throw new ErrorException ( "mark數(shù)據(jù)庫連接池中已無鏈接資源,請稍后重試!/mark" );
} else { ? ? ? ? ? ?return array_pop ( $this-dbpool );
}
} ? ?/**
* 將用完的數(shù)據(jù)庫鏈接資源放回到數(shù)據(jù)庫連接池
*
* @param unknown $conn
* @throws ErrorException
*/
public function release($conn) { ? ? ? ?if (count ( $this-dbpool ) = $this-poolsize) { ? ? ? ? ? ?throw new ErrorException ( "mark數(shù)據(jù)庫連接池已滿/markbr /" );
} else {
array_push ( $this-dbpool, $conn );
}
}
}
接口的流程.
建立控制器(訪問地址)-審核訪問者身份(token)-驗證提交數(shù)據(jù)是否符合類型(validate
)-處理接收數(shù)據(jù)(邏輯流程)-返回結果(json字符串).
其中要注意是否存在跨域,如果跨域要做跨域處理,例如返回jsonp.