<?php
header('Content-Type: text/plain');
function block_check(int $max_size, string &$block): bool
{
$size = strlen($block);
if ($size <= 32 || $size != $max_size) {
return false;
}
$md5 = substr($block, 0, 32);
if (empty($md5)) {
return false;
}
$playload = substr($block, 32);
if (empty($playload)) {
return false;
}
return $md5 === md5($playload);
}
function block_data_write(int $max_size, string &$block, string $data): string
{
$body = strlen($data) . '|' . $data;
$len = strlen($body);
if (32 + $len > $max_size) {
throw new Exception('Too much data.');
}
$playload = str_pad($body, $max_size - 32, ' ');
return $block = md5($playload) . $playload;
}
function block_data_read(int $max_size, string &$block): string
{
if (!block_check($max_size, $block) || strlen($block) != $max_size) {
return '';
}
$data_length = '';
$data_start = 32;
for ($i = 32; $i < $max_size && $block[$i] != '|'; $i++) {
$data_length .= $block[$i];
$data_start = $i + 2;
}
return substr($block, $data_start, $data_length);
}
function block_data(int $max_size, string &$block, ?string $data = null): string
{
return is_null($data) ? block_data_read($max_size, $block) : block_data_write($max_size, $block, $data);
}
$max_size = 1024;
$key = ftok(__FILE__, '*');
if (-1 == $key) {
echo 'ftok fail';
exit(1);
}
echo 'Key: ' . $key . PHP_EOL;
$shmop = shmop_open($key, 'c', 0644, $max_size);
if (false === $shmop) {
echo 'shmop_open fail';
exit(1);
}
$save_data = shmop_read($shmop, 0, 0);
if (false === $save_data) {
echo 'shmop_read fail' . PHP_EOL;
} else {
echo base64_encode($save_data) . PHP_EOL;
$inside_message = block_data($max_size, $save_data);
if (empty($inside_message)) {
$inside_message = 'Hello, shmop.';
echo "Write: $inside_message" . PHP_EOL;
$shmop_write_data = '';
block_data($max_size, $shmop_write_data, $inside_message);
shmop_write($shmop, $shmop_write_data, 0);
} else {
echo "Read: $inside_message" . PHP_EOL;
}
}
shmop_close($shmop);
|