日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

PHP 實現base64編碼文件上傳出現問題詳解

瀏覽:176日期:2022-09-09 09:23:42

一、場景

領導:小A同學,我們要做一個樣本上傳進行分析的功能,你看下是否使用base64編碼加進去,這樣客戶端的同學就不需要用form-data方式來上傳了,直接使用json格式就可以上報,可以讓格式上報統一。

小A:好的,領導,馬上搞定!

咋看上面的對話沒啥問題,很多公司團隊內部為了一些標準化的問題,都會進行一些技術選型問題,但是噩夢也就從這個對話開始,功能實現當然都是很簡單的,先來看簡單流程圖:

PHP 實現base64編碼文件上傳出現問題詳解

本身的流程是一個很簡單的文件轉換成base64上傳,再服務端decode保存,在開發聯調過程中沒有問題,非常完美的走下去了。

二、問題來了

突然有一天終端同學誤操作將一個37M文件上傳,nginx與php-fpm文件上傳限制均為(60M),但是在界面出現500錯誤,進入docker 日志查看有一條數據:

Allowed memory size of 8388608 bytes exhausted (tried to allocate 1298358 bytes)

玩php的基本都知道這是啥意思,就是代碼運行過程中使用內存超過 我們php.ini設置的memory_limit 的值,然后就屁顛屁顛進入php.ini找參數配置,很快找到:

memory_limit=128M

然后就轉念一想,不應該出現這個問題,我們知道,php的內部變量使用cow(寫時復制)機制來實現,那么內存申請只有在變量賦值變更才會進行

三、測驗

接下來我們單獨寫一個程序來進行測試,將一個4.89M文件進行base64_encode 編碼 與base64_decode解碼,查看各自占用內存以及過程中占用峰值內存

<?php$mid = memory_get_usage();$apk_content = file_get_contents(__DIR__ . ’/4bc1c8a05b8505662be778b6dad23b55.apk’);var_dump(’文件加載到內存:’ . round((memory_get_usage() - $mid) / 1024 / 1024, 2) . ’M’);var_dump(’過程中峰值使用的內存:’ . round(memory_get_peak_usage() / 1024 / 1024, 2) . ’M’);unset($mid);$mid = memory_get_usage();$base64_encode = base64_encode($apk_content);unset($apk_content);var_dump(’base64_encode占用內存:’ . round((memory_get_usage() - $mid) / 1024 / 1024, 2) . ’M’);var_dump(’過程中峰值使用的內存:’ . round(memory_get_peak_usage() / 1024 / 1024, 2) . ’M’);unset($mid);$mid = memory_get_usage();base64_decode($base64_encode);var_dump(’base64_decode占用內存:’ . round((memory_get_usage() - $mid) / 1024 / 1024, 2) . ’M’);var_dump(’過程中峰值使用的內存:’ . round(memory_get_peak_usage() / 1024 / 1024, 2) . ’M’);unset($mid);

執行結果:

string(29) '文件加載到內存:4.89M'string(38) '過程中峰值使用的內存:5.25M'string(33) 'base64_encode占用內存:1.63M'string(39) '過程中峰值使用的內存:11.76M'string(30) 'base64_decode占用內存:0M'string(38) '過程中峰值使用的內存:13.4M'

通過上面結果可以看出

加載文件使用內存沒有太大問題,加載過程使用的峰值在5.25M,高出整體文件大小不多,這在文件加載過程有一些臨時申請內存的問題 base64_encode占用內存,這個在使用的時候,就已經將內存差不多進行一個double,而這基本上也是在內核解析過程中,進行了內存申請,可以理解,文件本身占用內存+base64_encode 解析后的內存,兩份內存同時存在的 base64_decode操作,這個操作就是解密了,解密過程中,這里直接就占用了3倍多的內存操作,問題就出在這里,在場景中出現的問題是一個37M的文件,為什么就把單個fpm的128M內存占滿了呢

四、源碼解析

base64_encode源碼解析

首先找到對應的c文件 base64.c,找到里面php_base64_encode函數

PHPAPI zend_string *php_base64_encode(const unsigned char *str, size_t length) /* {{{ */{const unsigned char *current = str;unsigned char *p;zend_string *result;result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);p = (unsigned char *)ZSTR_VAL(result); ...}

我們先來分析這段代碼,因為這里涉及到內存的問題,那么我們就看

result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);

這啥意思呢?

申請內存,最終調用的函數是:

safe_emalloc(size_t nmemb, size_t size, size_t offset)

在wiki上解釋是:

void *safe_emalloc(size_t nmemb, size_t size, size_t offset)分配緩沖區來存放每塊大小為 size 字節的 nmemb 塊,并附加 offset 字節。類似于 emalloc(nmemb * size + offset),但增加了針對溢出的特殊保護。

那么我可以簡單的認為,就是在encode過程中,重新申請了內存,申請的內存大小是文件本身的 4/3 大小,加上原來的文件本身大小,那么峰值大小可以理解為

峰值內存= 7/3 *4.89 = 11.41

那么與我們實驗過程中峰值大小基本是相符。

base64_decode操作

同樣我們進行源碼分析

PHPAPI zend_string *php_base64_decode_ex(const unsigned char *str, size_t length, zend_bool strict) /* {{{ */{const unsigned char *current = str;int ch, i = 0, j = 0, padding = 0;zend_string *result;result = zend_string_alloc(length, 0);...}

這里使用的zend_string_alloc來進行申請內存,那么底層使用的函數就是emalloc函數,來看下wiki的解釋

void *emalloc(size_t size)分配 size 字節的內存。

這個就比較好理解了,傳入參數內存再進行一個double拷貝就可以,

那么我們進行一個decode的內存峰值的計算:

峰值內存=(4/3+4/3) *4.89 =13.04

基本與我們測試的結果相差不多,因為精度關系,我們進行四舍五入的計算,測試代碼是精準計算,所以會有小數點偏差。

五、總結

那這就可以理解為什么一個為什么在我們一個37M的文件,不能再128M內存進行base64_encode與base64_decode操作,當然這里有一些臨時變量沒有及時釋放內存的情況,但是通過源碼分析可以知道,要做一次這樣場景來進行文件上傳,單純文件的內存損耗是2.6倍左右,所以為了節省內存,我們不要再用這個方式來進行操作了,很費內存的

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: PHP
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
91精品精品| 久久一区国产| 热久久久久久| 麻豆精品少妇| 日韩黄色在线观看| 99在线精品免费视频九九视| 欧美日一区二区三区在线观看国产免| 亚洲免费黄色| 清纯唯美亚洲综合一区| 人人精品久久| 精品在线网站观看| 国产激情久久| 一区在线免费观看| 亚洲综合色婷婷在线观看| 欧美一区精品| 欧美黄色精品| 激情综合自拍| 久久国产欧美日韩精品| 国产精品99久久久久久董美香| 美女久久久久久 | 成人日韩精品| 精品丝袜在线| 婷婷激情久久| 国产伦一区二区三区| 精品国产亚洲日本| 三上悠亚国产精品一区二区三区| 蜜臀av免费一区二区三区| 韩国女主播一区二区三区| 免费欧美日韩| 免费观看久久av| 日韩精品中文字幕一区二区| 欧美国产专区| 久久成人精品| 在线看片福利| 免费精品视频在线| 久久精品影视| 国产乱子精品一区二区在线观看 | 婷婷精品视频| 国产成年精品| 亚洲精品美女| 午夜久久美女| 成人黄色av| 精品久久久中文字幕| 欧美日韩三区| 欧美成人日韩| 99精品电影| 久久精品国产999大香线蕉| 久久国产精品毛片| 国产精品日本欧美一区二区三区| 你懂的网址国产 欧美| 日韩欧美中文在线观看| 久久久一本精品| 精品视频一区二区三区四区五区 | 精品视频在线观看网站| 尤物在线精品| 老司机精品久久| 日韩中文欧美在线| 综合欧美亚洲| 久久精品72免费观看| 91精品国产自产在线丝袜啪| 日韩欧美另类中文字幕| 蜜桃视频一区二区| 亚洲精品黄色| 鲁大师精品99久久久| 欧美+日本+国产+在线a∨观看| 欧美日韩国产探花| 日韩国产在线观看一区| 麻豆国产欧美一区二区三区| 韩国精品主播一区二区在线观看| 日韩一区欧美| 伊人精品在线| 免费久久精品视频| 伊人久久在线| 日韩精品久久理论片| 日韩深夜视频| 亚洲精品精选| 精品欧美一区二区三区在线观看| 亚洲无线观看| 夜鲁夜鲁夜鲁视频在线播放| 欧美日韩四区| 精品不卡一区| 日本在线视频一区二区| 亚洲国产专区校园欧美| 久久天堂影院| 综合亚洲色图| 美女毛片一区二区三区四区最新中文字幕亚洲| 精品视频在线你懂得| 欧美 日韩 国产一区二区在线视频| 好看的av在线不卡观看| 清纯唯美亚洲综合一区| 日韩免费久久| 亚洲一区网站| 欧美精品aa| 日韩午夜av在线| 国产精品hd| 国产色综合网| 国产a久久精品一区二区三区| 久久国产小视频| 日韩美女精品| 国产色播av在线| 亚洲麻豆一区| 欧美+日本+国产+在线a∨观看| 欧美精品观看| 性一交一乱一区二区洋洋av| 精品一区二区三区视频在线播放| 影音国产精品| 亲子伦视频一区二区三区| 国产日韩欧美三区| 视频一区二区中文字幕| 青青青免费在线视频| 国产乱码精品一区二区三区亚洲人| 日韩一区二区免费看| 精品国产91| 国产精成人品2018| 日韩在线卡一卡二| 激情亚洲影院在线观看| 国产中文字幕一区二区三区| 鲁大师成人一区二区三区 | 国产精品三级| 日韩极品在线观看| 亚洲毛片在线免费| 久久国产成人| 一本综合精品| 亚洲免费毛片| 亚洲三级观看| 综合一区av| 国产亚洲激情| 亚洲欧洲一区二区天堂久久| 91精品国产乱码久久久久久久| 麻豆国产在线| 日韩大片在线观看| 九色porny丨国产首页在线| 中文字幕在线看片| 欧美天堂视频| 久久国产主播| 日韩一区欧美| 在线 亚洲欧美在线综合一区| 欧美日韩国产高清| 首页欧美精品中文字幕| 日本中文字幕视频一区| 欧美日一区二区三区在线观看国产免| 无码日韩精品一区二区免费| 综合干狼人综合首页| 日韩激情一区二区| 美腿丝袜亚洲一区| 欧美国产美女| 夜久久久久久| 亚洲尤物av| 麻豆久久久久久| 亚洲一级二级| 日韩超碰人人爽人人做人人添| 国产伦理久久久久久妇女| 麻豆理论在线观看| 男女精品网站| 精品一区二区三区中文字幕| 欧美亚洲国产精品久久| 亚洲欧美日本国产| 久久中文字幕一区二区三区| 成人看片网站| 欧美日本三区| 黄色成人在线网址| 精品一区二区三区中文字幕| 亚洲激情社区| 91综合网人人| 视频一区国产视频| 欧产日产国产精品视频| 亚洲最大av| 久久国产中文字幕| 日本午夜精品视频在线观看| 日韩三区免费| 欧美精品不卡| 日韩国产欧美三级| 欧洲一级精品| 国产精品丝袜在线播放| 日韩视频精品在线观看| 高清一区二区| 国产亚洲精品美女久久| 久久成人亚洲| 亚洲天堂久久| 日韩久久精品| 精品日产乱码久久久久久仙踪林| 亚洲狼人精品一区二区三区| 天堂网av成人| 美女视频一区在线观看| 亚洲人成网77777色在线播放 | 日韩精品一区第一页| 婷婷亚洲综合| 欧美日韩中文一区二区| 老司机免费视频一区二区三区| 日韩国产在线观看一区| 亚洲精品欧美| 综合激情网站| 日韩中文字幕1| 色综合视频一区二区三区日韩 | 国产在线不卡一区二区三区 | 亚洲一级特黄| 91精品99| 99在线精品免费视频九九视| 99xxxx成人网| 日韩午夜精品|