Это моё решение.Я просто пишу идентификаторы новых загрузок в простой текстовый файл.Поскольку каждый идентификатор составляет ровно 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);