如何用PHP/MySQL為 iOS App 寫一個簡單的web伺服器(譯) PART1

來源:互聯網
上載者:User

原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app

  作為一個iPhone/iPad開發人員,能夠自己寫一個簡單的web伺服器將是很有用的。

  例如,你可能希望在軟體啟動時顯示一些來自伺服器的更新,或者在伺服器端儲存一些使用者資料。除了你的想象力,沒有什麼能限制你了。

  在第一篇中,我們將會一步一步的建立一個web伺服器,基於promo code system(促銷碼系統),我在我的第一個軟體中使用的,Wild Fables.在第二篇中,我們將會寫一個iOS App來和它進行互動。

為了完成這個教程,你將需要一個web伺服器,並裝有MySQL和PHP。如果你沒有,那麼你有以下幾種選擇:

  • 如果你想在你的Mac(free)上運行Apache/MySQL/PHP,有很多教程可以幫你。這裡有一個教程。
  • 如果你想租一個伺服器(需要花錢),這裡有一個教程。
  • 或者你很懶,以上兩種你都不想做,那麼你可以使用我在本教程PART2做的伺服器。

你不需要有PHP和MySQL的經驗(當然有更好)因為這個教程包含了所有你需要的代碼。

 

你將做什麼


    id
: app的唯一標示.

    app_id:  app 的唯一字串標示.

  • w_promo_code:儲存可用促銷碼的表
  •   id:唯一表示.
  •   rw_app_id: 對應的App.
  •   code: 使用者輸入的促銷碼字元.
  •   unlock_code: 返回給App的促銷碼字元.
  •   uses_remaining:促銷碼剩餘可使用次數.
  • rw_promo_code_redeemed:儲存促銷碼兌取後的資訊。為了防止一個裝置用一個促銷碼兌取多次。
  • id: 唯一標示.
  • rw_promo_code_id: 已經兌取的促銷碼ID (from rw_promo_code).
  • device_id: 已經兌取的裝置ID.
  • redeemed_time: 兌取的時間.
  • DROP TABLE  AUTO_INCREMENT PRIMARY ,,255) NOT ,255) NOT , AUTO_INCREMENT PRIMARY ,255) NOT  AUTO_INCREMENT PRIMARY ,,255) NOT ,

    在你的web伺服器上,你需要建立一個MySQL資料庫並建立這三張表。這裡是完成的命令:

    儲存上面的代碼到一個名為create.sql的檔案,然後:

    rwenderlich@kermit:~$  -u root -: monitor.  Commands  with ; or \g. connection id is 1286: 5.1.37-1ubuntu5.1-'help;' or '\h'  help. Type '\c' to clear the  input statement.>, 1 row affected (0.00> > grant all privileges on promos.* to 'username'@'localhost' identified by 'password', 0 rows affected (0.00> :~$  -u username -p promos < create.::~$  -u root -: monitor.  Commands  with ; or \g. connection id is 1417: 5.1.37-1ubuntu5.1-'help;' or '\h'  help. Type '\c' to clear the  input statement.> >+------------------------+| Tables_in_promos       |+------------------------+| rw_app                 | | rw_promo_code          | | rw_promo_code_redeemed | +------------------------+3 rows in set (0.00 sec)

    現在已有了三張空表。下一步,建立一個測試的app:

    INSERT INTO rw_app VALUES(1, 'com.razeware.test'1, 1, 'test', 'com.razeware.test.unlock.cake', 10000);

    好的。現在資料庫已經串連,可以寫PHP伺服器了。

    驗證PHP/MySQL

    在開始實現PHP伺服器之前,首先檢查PHP是否在你的伺服器上運行正常。在你的伺服器上建立一個叫promos的檔案夾,在裡面建立一個叫index.php的檔案:

    <?     "Hello, PHP!" = ->?>

    你可以用你的伺服器的URL測試,也可以像下面這樣在命令列測試:

    Ray-Wenderlichs-Mac-mini-2:~ rwenderlich$ curl http:Hello, PHP!

    下一步,擴充這個類,確保你的伺服器可以串連到資料庫:

         ->db =  mysqli('localhost', 'username', 'password', 'promos'->db->autocommit(    ->db->             = ->db->prepare('SELECT id, code, unlock_code, uses_remaining FROM rw_promo_code'->->bind_result(, , ,  (-> " has  uses remaining!"->

    這裡添加了一個建構函式來串連給定使用者名稱和密碼的資料庫,一個 解構函式來關閉資料庫。現在你可以測試一下了:

    Ray-Wenderlichs-Mac-mini-2:~ rwenderlich$ curl http:test has 10000 uses remaining!

    伺服器策略:GET還是POST:

     好的,現在是時候來實現完成的功能了。但首先,讓我們來談談web伺服器的策略。

    我們知道我們需要向伺服器發送一些資料,包括app的ID,兌換嗎,要兌換的裝置ID。

    如何發送呢?有兩種方法:GET(普通方法)和POST(用於發送表單)

    • 如果你選擇GET,那麼參數是URL的一部分,就是把參數發到URL裡,然後向伺服器發送請求。
    • 如果你選擇POST,參數被放到request body中

    每個都能滿足你的需求,但是當你要嘗試做些什麼的時候,比如兌換促銷碼,還是用POST比較好。這也是我將要做的。

    這是什麼意思呢?如果我們想在PHP中訪問這些參數,我們可以通過內建的$_POST 數組:

    ["rw_app_id"]

    我們將會用ASIHTTPRequest來串連伺服器,用ASIFormDataRequest類發送一個POST請求:

    ASIFormDataRequest *request = forKey:];

    更多GET和POST的資訊,請看Wikipedia entry。

    更新:請看@smpdawg’s的精彩評論forum topic

     

    web伺服器策略:演算法 

    下一步,我們要看看將要使用的web伺服器的演算法:

     

     getStatusCodeMessage(     = 100 => 'Continue',        101 => 'Switching Protocols',        200 => 'OK',        201 => 'Created',        202 => 'Accepted',        203 => 'Non-Authoritative Information',        204 => 'No Content',        205 => 'Reset Content',        206 => 'Partial Content',        300 => 'Multiple Choices',        301 => 'Moved Permanently',        302 => 'Found',        303 => 'See Other',        304 => 'Not Modified',        305 => 'Use Proxy',        306 => '(Unused)',        307 => 'Temporary Redirect',        400 => 'Bad Request',        401 => 'Unauthorized',        402 => 'Payment Required',        403 => 'Forbidden',        404 => 'Not Found',        405 => 'Method Not Allowed',        406 => 'Not Acceptable',        407 => 'Proxy Authentication Required',        408 => 'Request Timeout',        409 => 'Conflict',        410 => 'Gone',        411 => 'Length Required',        412 => 'Precondition Failed',        413 => 'Request Entity Too Large',        414 => 'Request-URI Too Long',        415 => 'Unsupported Media Type',        416 => 'Requested Range Not Satisfiable',        417 => 'Expectation Failed',        500 => 'Internal Server Error',        501 => 'Not Implemented',        502 => 'Bad Gateway',        503 => 'Service Unavailable',        504 => 'Gateway Timeout',        505 => 'HTTP Version Not Supported' (([])) ? [] : '' sendResponse( = 200,  = '',  = 'text/html' = 'HTTP/1.1 ' .  . ' ' . getStatusCodeMessage((('Content-type: ' .  

    如果你不理解為什麼我們不要這個,那是因為這是一個遵守HTTP協議的web伺服器,當你發送一個相應你可以制定一個包含錯誤碼和詳細描述的頭。有標準錯誤碼可以用,這些方法不過是用起來更方便。

    正如你看到的,我防線了一個可以把狀態嗎轉換成HTML資訊的教程。

    下一步,就是真正的實現了!

         ((["rw_app_id"]) && (["code"]) && (["device_id"         = ["rw_app_id" = ["code" = ["device_id"         = 0 = ->db->prepare('SELECT id, unlock_code, uses_remaining FROM rw_promo_code WHERE rw_app_id=? AND code=?'->bind_param("is", , ->->bind_result(, ,  (->->         ( <= 0400, 'Invalid code'          ( <= 0403, 'Code already used'          = ->db->prepare('SELECT id FROM rw_promo_code_redeemed WHERE device_id=? AND rw_promo_code_id=?'->bind_param("si", , ->->bind_result( (->->         ( > 0403, 'Code already used'          = ->db->prepare("INSERT INTO rw_promo_code_redeemed (rw_promo_code_id, device_id) VALUES (?, ?)"->bind_param("is", , ->->        ->db->query("UPDATE rw_promo_code SET uses_remaining=uses_remaining-1 WHERE id="->db->         = "unlock_code" => ,200, json_encode( 400, 'Invalid request' 

    你應該能夠讀懂這段代碼,否則的話查看以下這個教程Mysqli reference。這裡有一些事情我需要指出:

    • isset是一個用於檢測變數是否已經設定了的PHP函數。我們這裡用它來確保所有需要的POST參數都發送了。
    • 注意我們沒有自己把傳進來的變數放到SQL語句中,而是使用bind_param方法。這是更安全的方法,否則你可能使自己易受SQL injection的攻擊。
    • 注意 unlock_code 用JSON返回。我們當然可以直接用字串返回因為我們只返回一個資訊,但是用JSON便於以後擴充。

    現在,你的web伺服器就已經可以工作了。你可以用下面命令來測試:

    curl -F "rw_app_id=1" -F "code=test" -F "device_id=test" http:{"unlock_code":"com.razeware.wildfables.unlock.test"}

    注意,如果你在我的伺服器上測試,如果你得到“code already used”的錯誤,你應該更改你的device_id。

    你可能希望進入你的資料庫看看那裡是否有一個rw_promo_code_redeemed的入口,uses_remaining是否減一等等。

    下一步?

    敬請期待PART2. 

    相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.