php 開發APP介面
APP模擬器:Start BlueStacks;
第一、APP介面簡介
1.1、客戶端app通訊
這種通訊模式類似於BS架構系統相似,但是有區別:
(1):客戶端請求地址是不可見的,是封裝在APP中的;
(2):BS架構返回的是HTML格式資料,而APP返回的是XML和JSON資料格式。
1.2、app通訊格式的區別:
XML定義:擴充套件標記語言,可以用來標記資料、定義資料型別,是一種允許使用者對自己的標記語言進行定義的源語言。XML格式統一,跨平臺和語言,非常適合資料傳輸和通訊。(XML節點不能為數字)
- <span style="font-size:18px;"><?xml version=
- <item>
- <title>singwa</title>
- <test id="1"/>
- <address>beijing</address>
- </item></span>
JSON定義:JSON一種輕量級的資料交換格式,具有良好的可讀和便於 快速編寫的特徵。可以在不同的平臺之間進行資料交換。json資料相容性高、完全獨立與語言文字格式。
(1):可讀性方面 ---> XML比較好;
(2):生成資料方面 ----> json比較好;
(3):傳輸速度方面 ----> json比較好;
第二、封裝通訊介面資料方法:
1.1、PHP生成JSON資料(json_encode只支援UTF-8)
1.2、通訊資料標準模式
- <span style="font-size:18px;">code 狀態碼(200,400等)
- message 提示資訊(郵箱格式不正確:資料返回成功等)
- data 返回資料</span>
JSON封裝通訊方式:
- <span style="font-size:18px;"><?php
- class Pesponse {
- /**
- * [通過json方式輸出通訊資料]
- * @param integer $code 狀態碼
- * @param string $message 提示資訊
- * @param array $data 資料
- */
- publicstaticfunction json($code, $message='', $data=array()) {
- if (!is_numeric($code)) {
- return'';
- }
- $result = array(
- 'code'=>$code,
- 'message'=>$message,
- 'data'=>$data
- );
- echo json_encode($result);
- exit;
- }
- }</span>
- <span style="font-size:18px;"><?php
- class Pesponse {
- /**
- * [通過json方式輸出通訊資料]
- * @param integer $code 狀態碼
- * @param string $message 提示資訊
- * @param array $data 資料
- */
- publicstaticfunction xmlEncode($code, $message='', $data=array()) {
- if (!is_numeric($code)) {
- return'';
- }
- $result = array(
- 'code'=>$code,
- 'message'=>$message,
- 'data'=>$data
- );
- header("Content-Type:text/xml");
- $xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
- $xml .= "<root>\n";
- $xml .= self::xmlToEocode($result);
- $xml .= "</root>";
- echo$xml;
- }
- publicstaticfunction xmlToEocode($data) {
- $xml = $attr = "";
- foreach($dataas$key=>$val) {
- if (is_numeric($key)) {
- $attr = " id='{$key}'";
- $key = "item";
- }
- $xml .= "<{$key}{$attr}>";
- $xml .= is_array($val)?self::xmlToEocode($val):$val;
- $xml .= "</{$key}>";
- }
- return$xml;
- }
- }
- $data = array(
- 'id'=>"1",
- 'name'=>'singwa',
- 'type'=>array(1,2,3),
- );
- Pesponse::xmlEncode(200,'success',$data);</span>
綜合通訊方式封裝:(response.php)
- <span style="font-size:18px;"><?php
- class Pesponse {
- const JSON = "json";
- /**
- * [通過json方式輸出通訊資料]
- * @param integer $code 狀態碼
- * @param string $message 提示資訊
- * @param array $data 資料
- * @param string $type 資料型別
- */
- <span style="color: rgb(255, 0, 0);">publicstaticfunction show($code, $message='', $data=array(), $type=self::JSON) {
- if (!is_numeric($code)) {
- return"";
- }
- $type = isset($_GET['type']) ? $_GET['type'] : self::JSON;
- $result = array(
- 'code'=>$code,
- 'message'=>$message,
- 'data'=>$data,
- );
- if ($type == "json") {
- self::json($code, $message, $data); exit;
- } elseif($type == "array") {
- var_dump($result);
- } elseif($type == "xml") {
- self::xmlEncode($code, $message, $data);
- exit;
- } else {
- //TODO
- }
- }</span>
- /**
- * [通過json方式輸出通訊資料]
- * @param integer $code 狀態碼
- * @param string $message 提示資訊
- * @param array $data 資料
- */
- publicstaticfunction json($code, $message='', $data=array()) {
- if (!is_numeric($code)) {
- return'';
- }
- $result = array(
- 'code'=>$code,
- 'message'=>$message,
- 'data'=>$data
- );
- echo json_encode($result);
- exit;
- }
- publicstaticfunction xmlEncode($code, $message='', $data=array()) {
- if (!is_numeric($code)) {
- return'';
- }
- $result = array(
- 'code'=>$code,
- 'message'=>$message,
- 'data'=>$data
- );
- header("Content-Type:text/xml");
- $xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
- $xml .= "<root>\n";
- $xml .= self::xmlToEocode($result);
- $xml .= "</root>";
- echo$xml;
- }
- publicstaticfunction xmlToEocode($data) {
- $xml = $attr = "";
- foreach($dataas$key=>$val) {
- if (is_numeric($key)) {
- $attr = " id='{$key}'";
- $key = "item";
- }
- $xml .= "<{$key}{$attr}>";
- $xml .= is_array($val)?self::xmlToEocode($val):$val;
- $xml .= "</{$key}>";
- }
- return$xml;
- }
- }
- $data = array(
- 'id'=>"1",
- 'name'=>'singwa',
- 'type'=>array(1,2,3),
- 'test'=>array(4,5,6=>array(123,'ssss'))
- );
- Pesponse::show(200,'success',$data);</span>
2.1、PHP生成XML資料:
2.1.1、組裝字串
- <span style="font-size:18px;"><?php
- class Pesponse {
- publicstaticfunction xml() {
- header("Content-Type:text/xml");
- $xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
- $xml .= "<root>\n";
- $xml .= "<code>200</code>\n";
- $xml .= "<message>資料返回成功</message>\n";
- $xml .= "<data>\n";
- $xml .= "<id>1</id>\n";
- $xml .= "<name>singwa</name>\n";
- $xml .= "</data>\n";
- $xml .= "</root>";
- echo$xml;
- }
- }
- Pesponse::xml();</span>
2.1.2、使用系統類(PHP開發手冊中查詢)
DOMDocument XMLWriter SimpleXML
第三、核心技術
3.1、靜態快取(檔案,file.php)
- <span style="font-size:18px;"><?php
- class File {
- <span style="white-space:pre"> </span>private$_dir;
- <span style="white-space:pre"> </span>const EXT = '.txt';
- <span style="white-space:pre"> </span>publicfunction __construct(){
- <span style="white-space:pre"> </span>$this->_dir = dirname(__FILE__).'/file/';
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>/**
- <span style="white-space:pre"> </span> * @param [string] $key [檔名]
- <span style="white-space:pre"> </span> * @param string $value [資料]
- <span style="white-space:pre"> </span> * @param string $path [檔案路徑]
- <span style="white-space:pre"> </span> * @return [return] [位元組數 或者false]
- <span style="white-space:pre"> </span> */
- <span style="white-space:pre"> </span>publicfunction cacheData($key, $value = '', $cacheTime = 0) {
- <span style="white-space:pre"> </span>$filename = $this->_dir.$key.self::EXT;
- <span style="white-space:pre"> </span>if ($value !== "") {//將value值寫入快取
- <span style="white-space:pre"> </span>if (is_null($value)) {//當 $value為null時,刪除快取
- <span style="white-space:pre"> </span>return @unlink($filename);
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>$dir = dirname($filename);
- <span style="white-space:pre"> </span>if (!is_dir($dir)) {
- <span style="white-space:pre"> </span>mkdir($dir,0777);
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>//"%011d"表示不是11位,補0
- <span style="white-space:pre"> </span>$cacheTime = sprintf('%011d', $cacheTime);
- <span style="white-space:pre"> </span>//如果成功返回資料的位元組數,沒有成功返回false
- <span style="white-space:pre"> </span>returnfile_put_contents($filename, $cacheTime.json_encode($value));
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>//讀取快取資料(在呼叫cacheData方法$value不寫時)
- <span style="white-space:pre"> </span>if (!is_file($filename)) {
- <span style="white-space:pre"> </span>return FALSE;
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>//獲取快取內容
- <span style="white-space:pre"> </span>$contents = file_get_contents($filename);
- <span style="white-space:pre"> </span>//獲取快取時間
- <span style="white-space:pre"> </span>$cacheTime = (int)substr($contents,0,11);
- <span style="white-space:pre"> </span>//獲取快取內容
- <span style="white-space:pre"> </span>$value = substr($contents,11);
- <span style="white-space:pre"> </span>//判斷快取失效時間
- <span style="white-space:pre"> </span>if($cacheTime != 0 && $cacheTime+filemtime($filename)<time()) {
- <span style="white-space:pre"> </span>unlink($filename);
- <span style="white-space:pre"> </span>return FALSE;
- <span style="white-space:pre"> </span>}
- <span style="white-space:pre"> </span>return json_decode($value,true);
- <span style="white-space:pre"> </span>
- <span style="white-space:pre"> </span>}
- }</span>
第三、定時任務
1.定時任務命令
- 1.定時任務服務提供crontab命令來設定服務
- 2.crontab -e //編輯某個使用者的cron服務
- 3.crontab -l //列出某個使用者cron服務的詳細內容
- 4.crontab -r //刪除某個使用者的cron服務
3、定時任務的crontab例子
第四、APP介面例項
1、單例模式連結資料庫(db.php)
1.1、單例模式三大原則
(1):建構函式需要標記為非public(防止外部使用new操作符建立物件),單例類不能在其他類中例項化,只能被其自身例項化;
(2):擁有一個儲存類的例項的靜態成員變數$_instance;
(3):擁有一個訪問這個例項的公共的靜態方法。
- <?php
- class Db {
- staticprivate$_instance;
- staticprivate$_connectSource;
- private$dbConfig = array(
- 'host' => '127.0.0.1',
- 'user' => 'root',
- 'password'=> 'root',
- 'database'=> 'video',
- );
- privatefunction __construct() {
- }
- //公共的靜態方法
- staticpublicfunction getInstance() {
- if (!(self::$_instance instanceof self)) {
- self::$_instance = new self();
- }
- return self::$_instance;
- }
- //連線資料庫
- publicfunction connect() {
- if (!self::$_connectSource) {
- self::$_connectSource = @mysql_connect($this->_dbConfig['host'], $this->_dbConfig['user'], $this->_dbConfig['password']);
- if (self::$_connectSource) {
- thrownew Exception('mysql connect error'.mysql_error());
- }
- mysql_select_db($this->_dbConfig['database'], self::$_connectSource);
- mysql_quert('set names UTF-8', self::$_connectSource);
- }
- return self::$_connectSource;
- }
- }
- //連線資料庫
- $connect = Db::getInstance()->connect();
2、首頁APP介面開發
方案一、 讀取資料庫方式開發 首頁介面(應用場景:資料時效性比較高的系統)
- <?php
- require_once('./response.php');
- require_once('./db.php');
- //判斷連結合法性
- $page = isset($_GET['page']) ? $_GET['page'] : 1;
- $pageSize = isset($_GET['pagesize']) ? $_GET['pagesize'] : 1;
- if (!is_numeric($page) || !is_numeric($pageSize)) {
- return Response::show(401,'資料不合法');
- }
- $offset = ($page-1) * $pageSize;
- $sql = "select * from video where status = 1 order by orderby desc limit ".$offset.",".$pageSize;
- //連線資料庫
- try {
- $connect = Db::getInstance()->connect();
- } catch(Exception $e) {
- return Response::show(403, '資料庫連結失敗');
- }
- $result = mysql_query($sql, $connect);
- $videos = array();
- while ($video = mysql_fetch_assoc($result)) {
- $videos[] = $video;
- }
- if ($videos) {
- return Response::show(200, '首頁獲取資料成功', $videos);
- } else {
- return Response::show(400, '首頁獲取資料失敗', $videos);
- }
方案二、讀取快取方式開發首頁介面(用途:減少資料庫壓力)(檔案快取)
- <?php
- require_once('./response.php');
- require_once('./db.php');
- require_once('./file.php');
- //判斷連結合法性
- $page = isset($_GET['page']) ? $_GET['page'] : 1;
- $pageSize = isset($_GET['pagesize']) ? $_GET['pagesize'] : 1;
- if (!is_numeric($page) || !is_numeric($pageSize)) {
- return Response::show(401,'資料不合法');
- }
- $offset = ($page-1) * $pageSize;
- $sql = "select * from video where status = 1 order by orderby desc limit ".$offset.",".$pageSize;
- $cache = new File();
- $videos = array();
- if (!$videos = $cache->cacheData('index_cache'.$page.'-'.$pageSize)) {
- //連線資料庫
- try {
- $connect = Db::getInstance()->connect();
- } catch(Exception $e) {
- return Response::show(403, '資料庫連結失敗');
- }
- $result = mysql_query($sql, $connect);
- while ($video = mysql_fetch_assoc($result)) {
- $videos[] = $video;
- }
- if ($videos) {
- $cache->cacheData('index_cache'.$page.'-'.$pageSize,$videos,1200);
- }
- }
- if ($videos) {
- return Response::show(200, '首頁獲取資料成功', $videos);
- } else {
- return Response::show(400, '首頁獲取資料失敗', $videos);
- }
方案三、定時讀取快取方式開發首頁介面
- <?php
- //讓crontab定時執行的指令碼程式------ */5 * * * * /usr/bin/php /data/www/app/corn.php
- require_once('./db.php');
- require_once('./file.php');
- $sql = "select * from video where status = 1 order by orderby desc";
- try {
- $connect = Db::getInstance()->connect();
- } catch(Exception $e) {
- file_put_contents('./logs/'.date('y-m-d').'.txt',$e->getMessage());
- return;
- }
- $result = mysql_query($sql, $connect);
- $videos = array();
- while($video = mysql_fetch_assoc($result)) {
- $videos[] = $video;
- }
- $file = new File();
- if($videos) {
- $file->cacheData('index_cron_cache',$videos);
- } else {
- file_put_contents('/logs/'.date('y-m-d').'.txt',"沒有相關資料");
- }
- return;
1、APP版本升級分析以及資料表設計
檢測升級:首先開啟APP請求初始化介面init.php,檢測是否更新,如果更新下載最新的原始碼包,替換原來的APK,否的話直接返回首頁;
初始化介面init.php要傳遞的引數:app_id:客戶端id(1.安卓,2.iPhone)、version_id:(版本號)
2、升級介面開發和演示
處理介面業務(common.php)
- <?php
- /**
- * 處理介面公共業務
- */
- require_once('./response.php');
- require_once('./db.php');
- class Common {
- public$params;
- public$app;
- publicfunction check() {
- $this->params['app_id'] = $appId = isset($_POST['app_id']) ? $_POST['app_id'] : '';
- $this->params['version_id'] = $versionId = isset($_POST['version_id']) ? $_POST['version_id'] : '';
- $this->params['version_mini'] = $versionMini = isset($_POST['version_mini']) ? $_POST['version_mini'] : '';
- $this->params['did'] = $did = isset($_POST['did']) ? $_POST['did'] : '';
- $this->params['encrypt_did'] = $encryptDid = isset($_POST['encrypt_did']) ? $_POST['encrypt_did'] : '';
- if (!is_numeric($appId) || !is_numeric($versionId)) {
- return Response::show(401, '引數不合法');
- }
- //判斷APP是否需要加密
- $this->app = $this->getApp($appId);
- if (!$this->app) {
- return Response::show(402, 'app_id不存在');
- }
- if ($this->app['is_encryption'] && $encryptDid != md5($did . $this->app['key'])) {
- return Response::show(403, '沒有許可權');
- }
- }
- publicfunction getApp($id) {
- $sql<