怎麼解決防盜鏈?
Referrer白名單:設定Nginx只允許來自指定域名的請求,其他來源的請求將被拒絕。
location ~* \.(jpg|jpeg|png|gif)$ { valid_referers none blocked example.com; if ($invalid_referer) { return 403; } }
Referer黑名單:設定Nginx只允許來自指定域名以外的請求,其他來源的請求將被拒絕。
location ~* \.(jpg|jpeg|png|gif)$ { valid_referers none blocked; if ($invalid_referer) { return 403; } if ($http_referer ~* (badsite1.com|badsite2.com)) { return 403; } }
設定圖片的時效性:可以透過Nginx的add_header指令設定圖片的過期時間,從而防止其他網站永久使用你的圖片。
location ~* \.(jpg|jpeg|png|gif)$ { expires 30d; //30天后快取過期 add_header Cache-Control "public"; }
Rewrite防盜鏈:使用Nginx的rewrite模組,將請求的URL中的來源進行判斷,如果來源不正確,就跳轉到錯誤頁面。
location /images/ { if ($http_referer !~ "^https?://(www\.)?example\.com") { rewrite ^/images/(.*)$ /error.png last; } }
PHP的垃圾回收機制?
PHP的垃圾回收機制主要是基於引用計數(reference counting)演算法實現的。每當有一個變數引用一個物件時,物件的引用計數就會加一。每當一個變數不再引用該物件時,物件的引用計數就會減一。當物件的引用計數降為零時,物件就會被標記為垃圾,等待垃圾收集器的回收。
PHP 7.3之後,引入了一種新的垃圾收集器——“Zend GC”,它是一種全域性垃圾回收機制,可以更快地檢測和回收垃圾。
如何獲取客戶端真實IP?
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$client_ip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$client_ip = $_SERVER['REMOTE_ADDR'];
}
需要注意的是,$_SERVER['HTTP_X_FORWARDED_FOR']
和 $_SERVER['HTTP_CLIENT_IP']
的值可能是一個逗號分隔的 IP 地址列表,其中第一個 IP 地址是客戶端的真實 IP 地址。
如何防範CSRF攻擊
使用 CSRF Token
#client <form action="submit.php" method="post"> <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"> <!-- 其他表單元素 --> <button type="submit">提交</button> </form> #server session_start(); if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) { die('CSRF 驗證失敗'); }
檢查 Referer
if (strpos($_SERVER['HTTP_REFERER'], 'example.com') === false) { die('CSRF 驗證失敗'); }
新增驗證碼
PHP如何防範XSS攻擊
對使用者輸入進行過濾和轉義
$raw_input = '<script>alert("惡意程式碼");</script>'; $filtered_input = htmlspecialchars($raw_input, ENT_QUOTES, 'UTF-8'); echo $filtered_input; //<script>alert("惡意程式碼");</script>
htmlspecialchars()
函式只能防止 HTML 注入,對於其他型別的注入攻擊(例如 JavaScript、CSS、SQL 注入等),需要使用相應的轉義函式或過濾器。使用 Content Security Policy
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'");
對輸出內容進行過濾和轉義
在輸出內容之前,使用 htmlspecialchars() 函式對內容進行 HTML 轉義。
如果兩個檔案大小都超過了 1G,而 PHP 最大允許的記憶體只有 255M,那麼不能將整個檔案讀入記憶體中進行比較。一種可行的做法是對兩個檔案進行分塊處理,將每個塊讀入記憶體中進行比較,以此找到相同的行。
對兩個檔案進行分塊處理,將每個塊讀入記憶體中進行比較,以此找到相同的行
<?php
// 定義塊大小
define('BLOCK_SIZE', 1024 * 1024 * 256); // 256M
// 開啟檔案
$fp1 = fopen('file1.txt', 'r');
$fp2 = fopen('file2.txt', 'r');
$fp3 = fopen('result.txt', 'w');
// 初始化變數
$buffer1 = '';
$buffer2 = '';
$pos1 = 0;
$pos2 = 0;
// 讀取檔案塊並比較
while (!feof($fp1) || !feof($fp2)) {
// 讀取檔案塊
$buffer1 = fread($fp1, BLOCK_SIZE);
$buffer2 = fread($fp2, BLOCK_SIZE);
// 比較檔案塊
$lines1 = explode("\n", $buffer1);
$lines2 = explode("\n", $buffer2);
$count1 = count($lines1);
$count2 = count($lines2);
// 如果是塊的第一行,則修正當前位置
if ($pos1 == 0) {
$pos1 += strlen($lines1[0]) + 1;
}
if ($pos2 == 0) {
$pos2 += strlen($lines2[0]) + 1;
}
// 比較行資料
for ($i = 0; $i < min($count1, $count2); $i++) {
if ($lines1[$i] == $lines2[$i]) {
// 如果行資料相同,則將該行寫入新檔案
fwrite($fp3, $lines1[$i] . "\n");
}
// 更新位置資訊
$pos1 += strlen($lines1[$i]) + 1;
$pos2 += strlen($lines2[$i]) + 1;
}
// 如果檔案1比檔案2多出一行,需要將最後一行重新拼接到下一個塊的開頭
if ($count1 > $count2) {
$buffer1 = $lines1[$count2] . "\n";
$pos1 -= strlen($buffer1);
}
// 如果檔案2比檔案1多出一行,需要將最後一行重新拼接到下一個塊的開頭
if ($count2 > $count1) {
$buffer2 = $lines2[$count1] . "\n";
$pos2 -= strlen($buffer2);
}
// 定位檔案指標
fseek($fp1, $pos1);
fseek($fp2, $pos2);
}
// 關閉檔案控制程式碼
fclose($fp1);
fclose($fp2);
fclose($fp3);
10g 檔案,用 php 檢視它的行數
處理大檔案時,使用 PHP 的記憶體佔用可能會非常高,甚至可能導致指令碼執行時間過長或崩潰。為了避免這種情況,可以使用 PHP 的 SplFileObject 類,它支援迭代器模式,可以逐行讀取檔案,不會一次性將整個檔案讀入記憶體。
<?php
// 開啟檔案
$file = new SplFileObject('large_file.txt');
// 初始化行數為 0
$lineCount = 0;
// 迭代檔案中的每一行
foreach ($file as $line) {
// 每讀取一行,行數加一
$lineCount++;
}
// 輸出行數
echo "The file has $lineCount lines.\n";
?>
php7 效能為什麼提升這麼高?
PHP7 的效能提升主要來自於引擎最佳化和程式碼最佳化。引入 JIT 編譯器和改進垃圾回收機制,使得 PHP7 可以更快地執行程式碼。在標準庫和函式方面進行最佳化,也有助於提高 PHP7 的執行效率。
有一個 1G 大小的一個檔案,裡面每一行是一個詞,詞的大小不超過 16 個位元組,記憶體限制大小是 1M。返回頻數最高的 100 個詞
可以使用 PHP 的 SplFileObject 類進行逐行讀取,並將詞頻統計到一個陣列中。
<?php
$file = new SplFileObject('large_file.txt'); // 開啟檔案
$wordCount = array(); // 初始化詞頻統計陣列
while (!$file->eof()) { // 逐行讀取檔案內容
$line = $file->fgets(); // 讀取一行內容
$words = explode(' ', trim($line)); // 將一行內容按空格分割成詞
foreach ($words as $word) {
if (isset($wordCount[$word])) { // 如果詞已經存在,增加頻率
$wordCount[$word]++;
} else { // 否則,新增新的詞並初始化頻率為 1
$wordCount[$word] = 1;
}
}
}
arsort($wordCount); // 對詞頻統計陣列按值(頻率)進行降序排序
$i = 0;
foreach ($wordCount as $word => $count) { // 輸出頻率最高的 100 個詞
echo "$word: $count\n";
$i++;
if ($i >= 100) break;
}
?>
OOP物件導向是什麼?
怎麼防止重複下單?
- 前端校驗:在使用者點選“提交訂單”按鈕後,可以禁用該按鈕,避免使用者多次點選。
- 後端校驗:hash加密 使用者ID+商品ID+數量 作為依據,存在redis,設定過期時間,下單之前查詢是否有重複的key
- token:前端在提交訂單時,需要先向後端發起請求,獲取一個唯一的 token 或者 session ID,然後將該 token 或者 session ID 一起提交給後端。後端在處理訂單請求時,會先根據該 token 或者 session ID 判斷是否是重複提交的訂單。如果是網頁端還可以避免crsf攻擊
如果微信支付回撥出現故障,怎麼解決?
本作品採用《CC 協議》,轉載必須註明作者和本文連結