# PHP-FPM過渡常駐內存
使用php開發的程序員大多數開發的都是web或者api接口,要么就是調用java的后端服務實現對外公開接口服務,這些開發大多數采用nginx+php-fpm模式來開發。
大多數的php開發者都沒有常駐內存的概念,畢竟都是大多數都是基于fpm模式來進行開發,很多工作fpm都幫我們做好管理好了,php的開發者只需要管好自己的業務邏輯代碼就已經足夠了。
### 常駐內存和php-fpm模式有什么區別?
注意|常駐內存|php-fpm
-|-|-
變量|不釋放|自動釋放
對象|只new一次|每次請求都需要重新new
單例|在初始化階段把對象存到內存|每個請求重建創建和銷毀對象
### 在使用常駐內存框架需要注意什么?
* 內存釋放
* 數據污染
* 資源釋放
* 靜態變量保存的對象不會被釋放,需要手動管理
* 禁止使用exit和die
* 禁止使用sleep時間長的函數,防止導致Worker進程退出
* 不同Worker進程創建的對象和連接是不能互通的,創建連接池需要注意
* 定義公共函數的時候要使用 function_exists 判斷函數是否存在,否則會提示重名
* 類引入文件需要使用 include_once 或者 require_once 否則會提示類名重復
* 修改代碼需要重啟服務才能生效
* echo、print_r、var_dump不會輸出到瀏覽器
* 不能像fpm一樣使用$_GET、$_POST、$_REQUEST、$_SESSION、$_COOKIE、$_SERVER等$_開頭的變量。
### 數據污染問題演示
```php
<?php
Swoole\Runtime::enableCoroutine(true);
$_array = [];
$http = new swoole_http_server("127.0.0.1", 9501);
$http->set(['worker_num'=>1]);
$http->on("start", function ($server) {
});
$http->on("request", function ($request, $response) {
global $_array;
if ($request->server['request_uri'] == '/a') {
echo "---------------a請求開始----------------\n";
print_r($_array);
echo "---------------a請求開始----------------\n";
$_array['key'] = 'My Name is php';
co::sleep(1);
echo "---------------a請求修改----------------\n";
print_r($_array);
echo "---------------a請求修改----------------\n";
$response->end($_array['key']);
} else {
echo "---------------其他請求開始----------------\n";
print_r($_array);
echo "---------------其他請求開始----------------\n";
$_array['key'] = 'My name is Sunny';
echo "---------------其他請求修改----------------\n";
print_r($_array);
echo "---------------其他請求修改----------------\n";
$response->end();
}
});
$http->start();
```
- 第一章:基礎知識
- 課程簡介
- PHP-FPM過渡常駐內存
- 進程
- 實戰:實現Master-Worker
- 線程
- 實戰:CC攻擊器
- 協程
- 實戰:實現waitGroup功能
- 進程、線程、協程的區別
- 第二章:初識Swoft2.0
- Swoft介紹
- Swoft環境安裝
- gcc升級
- 安裝Swoft框架
- 目錄結構介紹
- SwoftCli工具
- Swoft配置
- 第三章:Swoft2.0核心
- 上下文
- 常駐內存沒有上下文隔離
- 實戰:手寫swoole框架上下文管理
- Bean容器
- 實戰:根據容器原理實現容器
- 實戰:通過容器實現依賴注入
- Bean容器定義與使用
- 配置文件定義Bean
- 容器類型
- 面向接口的容器
- 注解
- 實戰:實現注解
- 自定義Swoft注解類
- 事件
- 連接池
- 實戰:Swoole實現連接池
- 第四章:Http服務器
- Http Server生命周期
- Http Server配置
- 控制器
- 路由
- 請求對象Request
- 響應對象Response
- Http異常處理
- 中間件
- 實戰:中間件實現JWT登陸授權
- 第五章:驗證器
- 內置驗證類型
- 驗證器的使用
- 自定義驗證器
- 第六章:數據庫操作
- 連接數據庫
- 實體模型
- 模型事件
- 查詢器
- 事務處理
- 連接池配置
- 讀寫分離
- 多數據庫切換
- Models分層結構
- 實戰:實現用戶CURD API
- 第七章:Redis
- 連接redis和使用
- Redis連接池
- Redis集群配置(單機版)
- Redis集群配置(多服務器)
- Redis連接集群
- Redis實戰:實現延時任務
- 第八章:AOP編程
- AOP概念
- AOP實現原理
- 實戰實現AOP:靜態代理
- 實戰實現AOP:動態代理
- 切面注解介紹
- PointExecution切面
- PointBean切面
- PointAnnotation切面
- 實戰:使用AOP實現日志記錄
- 第九章:任務處理
- 進程使用
- 進程池使用
- 實戰:進程消費隊列
- 實戰:進程實現RabbitMQ延時隊列
- 異步任務
- 協程任務
- 定時任務