【面試那些事兒二】 PHP 常見問題
阿新 • • 發佈:2019-01-31
PHP 的垃圾回收機制:
PHP垃圾回收機制是php5之後才有的這<span id="transmark"></span>個東西,下面我來給大家介紹一下關於PHP垃圾回收機制一些理解,希望對各位同學有所幫助。 php 5.3之前使用的垃圾回收機制是單純的“引用計數”,也就是每個記憶體物件都分配一個計數器,當記憶體物件被變數引用時,計數器 1;當變數引用撤掉後,計數器-1;當計數器=0時,表明記憶體物件沒有被使用,該記憶體物件則進行銷燬,垃圾回收完成。 “引用計數”存在問題,就是當兩個或多個物件互相引用形成環狀後,記憶體物件的計數器則不會消減為0;這時候,這一組記憶體物件已經沒用了,但是不能回收,從而導致記憶體洩露; php5.3開始,使用了新的垃圾回收機制,在引用計數基礎上,實現了一種複雜的演算法,來檢測記憶體物件中引用環的存在,以避免記憶體洩露
將外網圖片本地化、將外網圖片下載到本地的原理
//將外網圖片本地化、將外網圖片下載到本地的原理
copy("http://image.v1.cn/vodone/20150723/303862_0x0.jpg",'e:/wamp/www/303862_0x0.jpg');
PHP快取技術總結
/** 1、全頁面靜態化快取 也就是將頁面全部生成html靜態頁面,使用者訪問時直接訪問的靜態頁面,而不會去走php伺服器解析的流程。此種方式,在CMS系 統中比較常見,比如dedecms; 一種比較常用的實現方式是用輸出快取: Ob_start() ******要執行的程式碼******* $content = Ob_get_contents(); ****將快取內容寫入html檔案***** Ob_end_clean(); 2、頁面部分快取 該種方式,是將一個頁面中不經常變的部分進行靜態快取,而經常變化的塊不快取,最後組裝在一起顯示;可以使用類似於 ob_get_contents的方式實現,也可以利用類似ESI之類的頁面片段快取策略,使其用來做動態頁面中相對靜態的片段部分的快取 (ESI技術,請baidu,此處不詳講)。該種方式可以用於如商城中的商品頁; 3、資料快取 顧名思義,就是快取資料的一種方式;比如,商城中的某個商品資訊,當用商品id去請求時,就會得出包括店鋪資訊、商品資訊 等資料,此時就可以將這些資料快取到一個php檔案中,檔名包含商品id來建一個唯一標示;下一次有人想檢視這個商品時,首 先就直接調這個檔案裡面的資訊,而不用再去資料庫查詢;其實快取檔案中快取的就是一個php陣列之類; Ecmall商城系統裡面就用了這種方式; 4、查詢快取 其實這跟資料快取是一個思路,就是根據查詢語句來快取;將查詢得到的資料快取在一個檔案中,下次遇到相同的查詢時,就直 接先從這個檔案裡面調資料,不會再去查資料庫;但此處的快取檔名可能就需要以查詢語句為基點來建立唯一標示(用md5($sql)???); 按時間變更進行快取 其實,這一條不是真正的快取方式;上面的2、3、4的快取技術一般都用到了時間變更判斷;就是對於快取檔案您需要設一個有效 時間,在這個有效時間內,相同的訪問才會先取快取檔案的內容,但是超過設定的快取時間,就需要重新從資料庫中獲取資料, 並生產最新的快取檔案; 比如,我將我們商城的首頁就是設定2個小時更新一次; 5、按內容變更進行快取 這個也並非獨立的快取技術,需結合著用;就是當資料庫內容被修改時,即刻更新快取檔案; 比如,一個人流量很大的商城,商品很多,商品表必然比較大,這表的壓力也比較重;我們就可以對商品顯示頁進行頁面快取; 當商家在後臺修改這個商品的資訊時,點選儲存,我們同時就更新快取檔案;那麼,買家訪問這個商品資訊時,實際上訪問的是 一個靜態頁面,而不需要再去訪問資料庫; 是想,如果對商品頁不快取,那麼每次訪問一個商品就要去資料庫查一次,如果有10萬人線上瀏覽商品,那伺服器壓力就大了; 6、記憶體式快取 提到這個,可能大家想到的首先就是Memcached;memcached是高效能的分散式記憶體快取伺服器。 一般的使用目的是,通過快取數 據庫查詢結果,減少資料庫訪問次數,以提高動態Web應用的速度、 提高可擴充套件性。 它就是將需要快取的資訊,快取到系統記憶體中,需要獲取資訊時,直接到記憶體中取;比較常用的方式就是 key-->value方式; $memcachehost = '192.168.6.191'; $memcacheport = 11211; $memcachelife = 60; $memcache = new Memcache; $memcache->connect($memcachehost,$memcacheport) or die ("Could not connect"); $memcache->set('key','快取的內容'); $get = $memcache->get($key); //獲取資訊 7、apache快取模組 apache安裝完以後,是不允許被cache的。如果外接了cache或squid伺服器要求進行web加速的話,就需要在htttpd.conf裡進行設 置,當然前提是在安裝apache的時候要啟用mod_cache的模組。 安裝apache時:./configure --enable-cache --enable-disk-cache --enable-mem-cache 8、php APC快取擴充套件 Php有一個APC快取擴充套件,windows下面為php_apc.dll,需要先載入這個模組,然後是在php.ini裡面進行配置: [apc] extension=php_apc.dll apc.rfc1867 = on upload_max_filesize = 100M post_max_size = 100M apc.max_file_size = 200M upload_max_filesize = 1000M post_max_size = 1000M max_execution_time = 600 ; 每個PHP頁面執行的最大時間值(秒),預設30秒 max_input_time = 600 ; 每個PHP頁面接收資料所需的最大時間,預設60 memory_limit = 128M ; 每個PHP頁面所吃掉的最大記憶體,預設8M 9、Opcode快取 我們知道,php的執行流程可以用下圖來展示: php的執行流程 首先php程式碼被解析為Tokens,然後再編譯為Opcode碼,最後執行Opcode碼,返回結果;所以,對於相同的php檔案,第一次執行 時可以快取其Opcode碼,下次再執行這個頁面時,直接會去找到快取下的opcode碼,直接執行最後一步,而不再需要中間的步驟了。 比較知名的是XCache、Turck MM Cache、PHP Accelerator等; **/
遍歷函式:scandir()與glob()函式的區別
/** * scandir()與glob()函式的區別: * * 遍歷資料夾、遍歷目錄、遍歷子資料夾、遍歷子目錄、遍歷檔案 * 掃描單層資料夾的情況 1、scandir('E:/wamp/www/phpcms/'); 案例: Array( [0] => . [1] => .. [2] => admin.php [3] => api [4] => api.php [5] => caches [6] => crossdomain.xml [7] => favicon.ico [8] => html [9] => index.html [10] => index.php [11] => js.html [12] => nbproject [13] => phpcms [14] => phpsso_server [15] => plugin.php [16] => robots.txt [17] => statics [18] => uploadfile ) 2、glob('E:/wamp/www/phpcms/*'); 案例: Array( [0] => E:/wamp/www/phpcms/admin.php [1] => E:/wamp/www/phpcms/api [2] => E:/wamp/www/phpcms/api.php [3] => E:/wamp/www/phpcms/caches [4] => E:/wamp/www/phpcms/crossdomain.xml [5] => E:/wamp/www/phpcms/favicon.ico [6] => E:/wamp/www/phpcms/html [7] => E:/wamp/www/phpcms/index.html [8] => E:/wamp/www/phpcms/index.php [9] => E:/wamp/www/phpcms/js.html [10] => E:/wamp/www/phpcms/nbproject [11] => E:/wamp/www/phpcms/phpcms [12] => E:/wamp/www/phpcms/phpsso_server [13] => E:/wamp/www/phpcms/plugin.php [14] => E:/wamp/www/phpcms/robots.txt [15] => E:/wamp/www/phpcms/statics [16] => E:/wamp/www/phpcms/uploadfile ) */ echo "<pre>";print_r(scandir('E:/wamp/www/phpcms/'));//跟glob相比多出來兩個元素,分別是: "." 和 ".." echo "<pre>";print_r(glob('E:/wamp/www/phpcms/*'));//以陣列的形式返回與指定模式相匹配的檔名或目錄
如何在陣列頭部和尾部及任意位置插入元素?
①插入元素
array_unshift();//在陣列頭部插入一個或多個元素
array_push();//在陣列尾部插入一個或多個元素
array_splice($arr,$start,0,$arr1);//在陣列的第$start+1個位置插入新元素(指的是頭部和中部任意位置,但不包括尾部),注意:引數3一定要是0
②刪除元素
array_shift();//刪除陣列中首個元素,並返回刪除後的值
array_pop();//刪除陣列的最後一個元素(出棧),並返回刪除後的值
php如何方式SQL注入?我們在查詢資料庫時,出於安全考慮,需要過濾一些非法字元防止SQL惡意注入
//我們在查詢資料庫時,出於安全考慮,需要過濾一些非法字元防止SQL惡意注入
function injCheck($sql_str) {
$check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/', $sql_str);
if ($check) {
echo '非法字元!!';
exit;
} else {
return $sql_str;
}
}
echo injCheck('1 or 1=1');//提示:"非法字元!!"
php如何強制下載檔案?
//有時我們不想讓瀏覽器直接開啟檔案,如PDF檔案,而是要直接下載檔案,那麼以下函式可以強制下載檔案,函式中使用了application/octet-stream頭型別
function download($filename){
if ((isset($filename))&&(file_exists($filename))){
header("Content-length: ".filesize($filename));
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
readfile("$filename");
} else {
echo "Looks like file does not exist!";
}
}
download('/down/test_45f73e852.zip');
php如何獲取客戶端真實IP?//我們經常要用資料庫記錄使用者的IP,以下程式碼可以獲取客戶端真實的IP:
//獲取使用者真實IP
function getIp() {
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
$ip = getenv("HTTP_CLIENT_IP");
else
if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else
if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
$ip = getenv("REMOTE_ADDR");
else
if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
$ip = $_SERVER['REMOTE_ADDR'];
else
$ip = "unknown";
return ($ip);
}
echo getIp();//結果:您的IP是:221.223.234.138