Browse Source

back to redis

master
Sergio Álvarez 5 months ago
parent
commit
4f0ac462e0
  1. 25
      .gitignore
  2. 50
      public/index.php
  3. 218
      src/preg.php
  4. 5
      src/redis.php

25
.gitignore

@ -0,0 +1,25 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
# composer
/vendor
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
*.zip

50
public/index.php

@ -0,0 +1,50 @@
<?php
die(1);
require_once dirname(dirname(__FILE__)) ."/../vendor/autoload.php";
function response(array $data): string
{
header("Content-Type: application/json");
die(json_encode($data));
}
try {
/*
if ($_SERVER['HTTP_HOST'] !== 'xrg.es') { // dev
// $ sudo mount --bind api/ ~/www/xrg.es
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS");
} else if (!preg_match("~^https://".preg_quote($_SERVER["HTTP_HOST"])."/~", $_SERVER["HTTP_REFERER"])) {
throw new Exception("Invalid request");
}
*/
// thank you php...
$post = json_decode(file_get_contents("php://input"), true);
if ($post['hash']) {
$key = mb_substr($post['hash'], 1, 10);
$state = $redis->hGetAll("xrg.es:". $key);
$redis->expire("xrg.es:". $key, 60*60*24*7); // touch
response($state);
}
if (!is_array($post)) {
die("{}");
}
$preg = new Preg($post);
$result = $preg->exec();
$key = $preg->hash();
$redis->hMSet("xrg.es:". $key, $post);
$redis->expire("xrg.es:". $key, 60*60*24*7);
response(array_merge((array)$result, ['hash' => $key]));
} catch (Throwable $e) {
response(['fatal' => $e->getMessage()]);
}

218
src/preg.php

@ -0,0 +1,218 @@
<?php
class Preg
{
const FUNCTIONS = ["preg_match", "preg_match_all", "preg_split", "preg_replace", "preg_quote"];
const FLAGS = [
"preg_match" => ['PREG_OFFSET_CAPTURE', 'PREG_UNMATCHED_AS_NULL'],
"preg_match_all" => ['PREG_SET_ORDER', 'PREG_OFFSET_CAPTURE', 'PREG_UNMATCHED_AS_NULL'],
"preg_split" => ['PREG_SPLIT_NO_EMPTY', 'PREG_SPLIT_DELIM_CAPTURE', 'PREG_SPLIT_OFFSET_CAPTURE'],
"preg_replace" => [],
"preg_quote" => []
];
public function __construct($params)
{
if (!in_array($params["method"], self::FUNCTIONS)) {
throw new Error("Invalid function");
}
ksort($params);
$this->hash = base_convert(crc32(serialize($params)), 10, 36);
$this->raw = $params;
$this->method = $params["method"];
$this->pattern = $params["pattern"];
$this->replacement = $params["replacement"];
$this->subject = $params["subject"];
$this->offset = mb_strlen($params["offset"])? (int)$params["offset"]: 0;
$this->limit = mb_strlen($params["limit"])? (int)$params["limit"]: -1;
$this->delimeter = mb_strlen($params["delimeter"])? $params["delimeter"]: null;
$this->flags = 0;
$this->flags_str = [];
foreach (array_intersect(self::FLAGS[$this->method], array_keys((array)$params)) as $flag) {
if ($params[$flag]) {
$this->flags |= constant($flag);
$this->flags_str[] = $flag;
}
}
}
public function exec()
{
if (!mb_strlen($this->pattern)) {
return [];
}
$func = "exec_". $this->method;
return $this->$func();
}
protected function exec_preg_match()
{
$ret = @preg_match($this->pattern, $this->subject, $matches, $this->flags, $this->offset);
$error = $this->last_error();
return array_merge($this->result($ret), [
"dump" => $error?: $matches,
"error" => (bool)$error,
"code" => $this->syntax()
]);
}
protected function exec_preg_match_all()
{
$ret = @preg_match_all($this->pattern, $this->subject, $matches, $this->flags, $this->offset);
$error = $this->last_error();
return array_merge($this->result($ret), [
"dump" => $error?: $matches,
"error" => (bool)$error,
"code" => $this->syntax()
]);
}
protected function exec_preg_split()
{
$ret = @preg_split($this->pattern, $this->subject, $this->limit, $this->flags);
$error = $this->last_error();
return array_merge($this->result($ret), [
"dump" => $error?: $ret,
"error" => (bool)$error,
"code" => $this->syntax()
]);
}
protected function exec_preg_replace()
{
$ret = @preg_replace($this->pattern, $this->replacement, $this->subject, $this->limit);
$error = $this->last_error();
return array_merge($this->result($ret), [
"dump" => $error?: $ret,
"error" => (bool)$error,
"code" => $this->syntax()
]);
}
protected function exec_preg_quote()
{
$ret = @preg_quote($this->pattern, $this->delimeter);
$error = $this->last_error();
return array_merge($this->result($ret), [
"dump" => $error?: $ret,
"error" => (bool)$error,
"code" => $this->syntax()
]);
}
protected function last_error()
{
/*if (!preg_last_error()) {
return false;
}*/
$ple = preg_last_error();
$e = error_get_last();
$gdc = get_defined_constants(true)['pcre'];
$return = [];
if ($ple and in_array($ple, $gdc)) {
$return["preg_last_error()"] = array_flip($gdc)[preg_last_error()];
}
if ($e['type'] < E_NOTICE) {
$return["php error message"] = $e['message'];
}
return $return;
}
protected function result($var)
{
$gettype = gettype($var);
$return = [
"return_value" => "??",
"return_type" => $gettype
];
if (in_array($gettype, ["boolean", "integer", "NULL"])) {
$return["return_value"] = json_encode($var);
} elseif (in_array($gettype, ["string"])) {
$return["return_value"] = "len(". mb_strlen($var). ")";
} elseif (in_array($gettype, ["array"])) {
$return["return_value"] = "count(". count($var). ")";
}
return $return;
}
protected function syntax()
{
$args = [$this->method .'("'. $this->pattern.'"'];
if (in_array($this->method, ['preg_match', 'preg_match_all'])) {
$args[] = '"'. $this->crop_text($this->subject) .'", $matches';
if (count($this->flags_str)) {
$args[] = implode(" | ", $this->flags_str);
}
if (mb_strlen($this->raw['offset'])) {
$args[] = (!count($this->flags_str)? 'null, ': ''). (string)$this->offset;
}
} elseif (in_array($this->method, ['preg_split'])) {
$args[] = '"'. $this->crop_text($this->subject) .'"';
if (mb_strlen($this->raw['limit'])) {
$args[] = (string)$this->limit;
}
if (count($this->flags_str)) {
$args[] = (!mb_strlen($this->raw['limit'])? 'null, ': ''). implode(" | ", $this->flags_str);
}
} elseif (in_array($this->method, ['preg_replace'])) {
$args[] = '"'. $this->crop_text($this->replacement) .'"';
$args[] = '"'. $this->crop_text($this->subject) .'"';
if (mb_strlen($this->raw['limit'])) {
$args[] = (string)$this->limit;
}
} elseif (in_array($this->method, ['preg_quote'])) {
if (mb_strlen($this->delimeter)) {
$args[] = (string)$this->delimeter;
}
}
$code = implode(", ", $args). ");";
return str_replace(array('?&gt;', '&lt;?php&nbsp;', '&nbsp;', '<code>', '</code>'), array('', '', ' ', '', ''), highlight_string('<?php '. $code .' ?'.'>', true) );
}
protected function crop_text($str, $len=50)
{
if (mb_strlen($str, "utf-8") < $len) {
return $str;
}
return str_replace(array("\r", "\n"), array('\r', '\n'), addslashes(mb_substr($str, 0, $len, "utf-8")). "...");
}
public function hash() {
return $this->hash;
}
}

5
src/redis.php

@ -0,0 +1,5 @@
<?php
$redis = new Redis();
$redis->connect("localhost");
$redis->select(3);
Loading…
Cancel
Save