이것은 내 해결책입니다. 단순히 새 업로드 ID를 일반 텍스트 파일에 작성합니다. 각 ID는 정확히 37 바이트 (36 + \ n)이므로 파일에 임의로 액세스 할 수있게됩니다. 또한 스레드 안전을 위해 flock
을 사용합니다.
function gen_uuid() {
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
// 16 bits for "time_mid"
mt_rand(0, 0xffff),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
mt_rand(0, 0x0fff) | 0x4000,
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
mt_rand(0, 0x3fff) | 0x8000,
// 48 bits for "node"
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
}
// "constants"
$savedDir = dirname(__FILE__) . '/saved';
$orderedFile = dirname(__FILE__) . '/ordered.txt';
// prepare response
$resp = null;
// switch on action
$action = $_REQUEST['action'];
if ($action == 'saveVideo') {
// read params
$video = $_REQUEST['video'];
$face = $_REQUEST['face'];
// add current timestamp
$date = time();
// generate UUID
$id = gen_uuid();
// package data
$pack = array(
'id' => $id,
'video' => $video,
'face' => $face,
'date' => $date
);
// save package using ID as filename
file_put_contents($savedDir . '/' . $id, json_encode($pack));
// write new ID to file with ordered IDs
$f = fopen($orderedFile, 'a');
if(flock($f, LOCK_EX)) {
fseek($f, 0, SEEK_END);
fwrite($f, $id . "\n");
flock($f, LOCK_UN);
}
fclose($f);
$resp = array('id' => $id);
}
else if ($action == 'getLatestVideos') {
// $debug = '';
// parse parameters
$amount = intval($_REQUEST['amount']);
$start = intval($_REQUEST['start']);
// $debug .= "amount $amount start $start";
// find $amount latest IDs (skip $start)
$ids = array();
$f = fopen($orderedFile, 'r');
if(flock($f, LOCK_SH)) {
// get file size
$fst = fstat($f);
$fsize = $fst['size'];
// determine IDs available
$available = floor($fsize/37);
// $debug .= " available $available";
if ($start < $available) {
// determine amount to seek back
$totamount = min($amount + $start, $available);
// $debug .= " totamount $totamount";
// seek back
fseek($f, -37 * $totamount, SEEK_END);
// now read forward until we have $amount (if could not seek back entirely, leave off the amount that would be sought back)
for ($i = 0; $i < min($amount, $available-$start); $i++) {
// read ID
$id = '';
while(strlen($id) < 36) {
$id .= fread($f, 36 - strlen($id));
}
// skip \n
fseek($f, 1, SEEK_CUR);
// add ID to list
$ids[] = $id;
}
}
flock($f, LOCK_UN);
}
fclose($f);
// reverse IDs so list becomes from new to old
$ids = array_reverse($ids);
// get datas from IDs
$resp = array();
foreach ($ids as $id) {
$resp[] = json_decode(file_get_contents($savedDir . '/' . $id));
}
// $resp[] = $debug;
}
else if ($action == 'getVideo') {
// read and clean ID
$id = strtolower($_REQUEST['id']);
$id = preg_replace('/[^a-f0-9-]/', '', $id);
// get data from ID
$resp = json_decode(file_get_contents($savedDir . '/' . $id));
}
// unknown operation
else {
$resp = 'Unknown action ' . $action;
}
// write response
echo json_encode($resp);
예, 일반 텍스트 파일에 ID를 쓰려고 생각했지만 임의 액세스가 아닙니다. 1000 목록에서 최신 10을 찾는 것은 처음 990 줄을 건너 뛰는 것을 의미합니다. 실제로 문제가되지는 않을 것입니다. (어떤 종류의 트래픽로드가 예상되는지는 정말로 모르지만) 실제로 적절하지 않습니다. –
해결되었습니다. 내 대답을 보라. –