# 啟用 Apache sudo apachectl start # 配置 PHP (macOS 內建) # 編輯 /etc/apache2/httpd.conf 取消註釋 LoadModule php7_module # 安裝 MySQL brew install mysql brew services start mysql
# /etc/apache2/extra/httpd-vhosts.confServerName api.local DocumentRoot "/Users/username/Sites/api" AllowOverride All Require all granted
編輯 /etc/hosts 添加 127.0.0.1 api.local
<?php
// api.local/index.php
header('Content-Type: application/json; charset=utf-8');
$data = [
'tid' => 100,
'name' => '標哥的技術博客',
'site' => 'www.huangyibiao.com'
];
$response = [
'code' => 200,
'message' => 'success',
'data' => $data,
'timestamp' => time(),
];
echo json_encode($response, JSON_UNESCAPED_UNICODE);
curl https://api.local/
# {"code":200,"message":"success","data":{"tid":100,"name":"標哥的技術博客","site":"www.huangyibiao.com"},"timestamp":1699999999}
<?php
header('Content-Type: application/json; charset=utf-8');
$type = isset($_POST['type']) ? (int)$_POST['type'] : 0;
$response = ['code' => 200, 'message' => 'success', 'data' => null];
if ($type < 1 || $type > 2) {
$response = ['code' => 400, 'message' => 'type 參數無效,需為 1 或 2', 'data' => null];
http_response_code(400);
exit(json_encode($response, JSON_UNESCAPED_UNICODE));
}
switch ($type) {
case 1:
$response['data'] = [
'type' => 1,
'name' => '標哥的技術博客',
'site' => 'www.huangyibiao.com'
];
break;
case 2:
$response['data'] = [
'type' => 2,
'name' => '公眾號:標哥的技術博客',
'site' => 'weixin search: biaogedejishuboke'
];
break;
}
echo json_encode($response, JSON_UNESCAPED_UNICODE);
curl -X POST -d "type=1" https://api.local/
# {"code":200,"message":"success","data":{"type":1,"name":"標哥的技術博客","site":"www.huangyibiao.com"},"timestamp":1699999999}
// GET
NSString *url = @"https://api.local/";
[HYBNetworking getWithUrl:url refreshCache:YES success:^(id response) {
NSLog(@"GET 成功: %@", response);
// response 已自動解析為 NSDictionary
} fail:^(NSError *error) {
NSLog(@"GET 失敗: %@", error);
}];
// POST
NSDictionary *params = @{@"type": @(1)};
[HYBNetworking postWithUrl:url refreshCache:YES params:params success:^(id response) {
NSLog(@"POST 成功: %@", response);
} fail:^(NSError *error) {
NSLog(@"POST 失敗: %@", error);
}];
// GET
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"https://api.local/"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) { NSLog(@"Error: %@", error); return; }
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(@"Response: %@", json);
}];
[task resume];
// POST
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.local/"]];
req.HTTPMethod = @"POST";
req.HTTPBody = [@"type=1" dataUsingEncoding:NSUTF8StringEncoding];
[[NSURLSession sharedSession] dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// 同樣解析...
}].resume();
| 層面 | 建議 | 工具/庫 |
|---|---|---|
| 路由分發 | 單入口 + 路由表 | FastRoute, 框架內建 |
| 參數驗證 | 專用驗證器類 | Respect/Validation, illuminate/validation |
| 異常處理 | 統一 try-catch + 友好錯誤碼 | Whoops (開發), 自定義異常體系 |
| 日誌記錄 | 結構化日誌 + 請求ID | Monolog, Laravel Log |
| 限流熔斷 | Redis 滑動窗口 + Sentinel | Predis + 自定義中間件 |
| 文檔生成 | OpenAPI 3.0 註解 | swagger-php, 屬性註解 |
| 測試 | 單元 + 集成 + 壓測 | PHPUnit, Postman, k6 |
本文演示了從零搭建 PHP 接口服務、編寫 GET/POST 接口、定義統一響應格式、iOS 客戶端對接的完整流程。**核心不在於語言,而在於:統一協議、嚴格驗證、可觀測性、文檔先行**。建議新項目直接使用 Laravel / Hyperf / ThinkPHP 6 等現代框架,享受開箱即用的路由、驗證、中間件、ORM、測試等能力,專注業務邏輯而非輪子構建。