mirror of
https://github.com/sigmasternchen/drnk.me
synced 2025-03-15 01:38:55 +00:00
feat: Basic project setup
This commit is contained in:
parent
9c6b129914
commit
f5d5166b4b
24 changed files with 514 additions and 0 deletions
49
.github/workflows/upload.yml
vendored
Normal file
49
.github/workflows/upload.yml
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
name: 'Publish to prod'
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "main"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
upload-prod:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: 'read'
|
||||||
|
id-token: 'write'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: 'actions/checkout@v3'
|
||||||
|
- name: Upload
|
||||||
|
env:
|
||||||
|
FTP_SERVER: ${{ secrets.FTP_SERVER }}
|
||||||
|
FTP_USERNAME: ${{ secrets.FTP_USERNAME }}
|
||||||
|
FTP_PASSWORD: ${{ secrets.FTP_PASSWORD }}
|
||||||
|
DB_DSN: ${{ secrets.DB_DSN }}
|
||||||
|
DB_SCHEMA: ${{ secrets.DB_SCHEMA }}
|
||||||
|
DB_USERNAME: ${{ secrets.DB_USERNAME }}
|
||||||
|
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
sudo apt install lftp
|
||||||
|
rm -rf .git .github
|
||||||
|
cp credentials.templ.php credentials.php
|
||||||
|
sed -i -e "s/{DB_DSN}/${DB_DSN}/g" credentials.php
|
||||||
|
sed -i -e "s/{DB_SCHEMA}/${DB_SCHEMA}/g" credentials.php
|
||||||
|
sed -i -e "s/{DB_USERNAME}/${DB_USERNAME}/g" credentials.php
|
||||||
|
sed -i -e "s/{DB_PASSWORD}/${DB_PASSWORD}/g" credentials.php
|
||||||
|
mv maintenance.php maintenance-real.php
|
||||||
|
sed -e 's/false/true/g' maintenance-real.php > maintenance.php
|
||||||
|
lftp -e "
|
||||||
|
set sftp:auto-confirm yes;
|
||||||
|
set ssl:verify-certificate no;
|
||||||
|
open -u ${FTP_USERNAME},${FTP_PASSWORD} sftp://${FTP_SERVER};
|
||||||
|
put maintenance.php -o maintenance.php;
|
||||||
|
mirror --exclude=maintenance-real.php -e -R ./ ./;
|
||||||
|
put maintenance-real.php -o maintenance.php;
|
||||||
|
quit;
|
||||||
|
"
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.idea
|
||||||
|
|
||||||
|
credentials.php
|
||||||
|
|
||||||
|
notes.txt
|
4
context.php
Normal file
4
context.php
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
const DB_CONNECTION = "DB_CONNECTION";
|
||||||
|
const REPOSITORIES = "REPOSITORIES";
|
5
controllers/GET.php
Normal file
5
controllers/GET.php
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return function (array &$context) {
|
||||||
|
echo "Hello World";
|
||||||
|
};
|
18
controllers/routes.php
Normal file
18
controllers/routes.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(ROOT . "/router/Router.php");
|
||||||
|
|
||||||
|
function fromController(string $path, string $endpoint = null) {
|
||||||
|
return function(array &$context) use ($path, $endpoint) {
|
||||||
|
if ($endpoint)
|
||||||
|
$context[ENDPOINT] = $endpoint;
|
||||||
|
|
||||||
|
return (require(ROOT . "/controllers/" . $path . ".php"))($context);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(Router $router) {
|
||||||
|
$router->addRoute(GET, "/", fromController("/GET"));
|
||||||
|
|
||||||
|
$router->addRoute(GET, "/.*", fromController("/slug/GET"));
|
||||||
|
};
|
5
controllers/slug/GET.php
Normal file
5
controllers/slug/GET.php
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return function (array &$context) {
|
||||||
|
echo "Hello World 2";
|
||||||
|
};
|
25
core.php
Normal file
25
core.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
const ROOT = __DIR__;
|
||||||
|
|
||||||
|
define("MAINTENANCE_MODE", require(ROOT . "/maintenance.php"));
|
||||||
|
|
||||||
|
if (MAINTENANCE_MODE) {
|
||||||
|
require(ROOT . "/templates/maintenance.php");
|
||||||
|
} else {
|
||||||
|
$connection = require_once(ROOT . "/persistence/connection.php");
|
||||||
|
(require(ROOT . "/persistence/migrate.php"))($connection);
|
||||||
|
|
||||||
|
$repositories = (require_once(ROOT . "/persistence/Repositories.php"))($connection);
|
||||||
|
|
||||||
|
$router = require(ROOT . "/router/Router.php");
|
||||||
|
(require(ROOT . "/controllers/routes.php"))($router);
|
||||||
|
|
||||||
|
require_once(ROOT . "/context.php");
|
||||||
|
$context = [
|
||||||
|
DB_CONNECTION => $connection,
|
||||||
|
REPOSITORIES => $repositories,
|
||||||
|
];
|
||||||
|
|
||||||
|
$router->execute($context);
|
||||||
|
}
|
7
credentials.templ.php
Normal file
7
credentials.templ.php
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// not constants so we can minimize their scope
|
||||||
|
$DB_DSN = "{DB_DSN}";
|
||||||
|
$DB_SCHEMA = "{DB_SCHEMA}";
|
||||||
|
$DB_USERNAME = "{DB_USERNAME}";
|
||||||
|
$DB_PASSWORD = "{DB_PASSWORD}";
|
13
html/.htaccess
Normal file
13
html/.htaccess
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteBase /
|
||||||
|
|
||||||
|
RewriteRule ^index\.php$ - [L]
|
||||||
|
RewriteCond %{REQUEST_URI} !^/static/
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteRule . /index.php [L]
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
php_flag log_errors on
|
||||||
|
php_value error_log /usr/home/usefula/php_dm.log
|
3
html/index.php
Normal file
3
html/index.php
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require("../core.php");
|
3
maintenance.php
Normal file
3
maintenance.php
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return false;
|
33
persistence/Repositories.php
Normal file
33
persistence/Repositories.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(__DIR__ . "/repositories/URLs.php");
|
||||||
|
|
||||||
|
class Repositories {
|
||||||
|
private PDO $connection;
|
||||||
|
|
||||||
|
private array $repositoryClasses = [
|
||||||
|
"urls" => URLs::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
private array $repositoryCache = [];
|
||||||
|
|
||||||
|
public function __construct(PDO $connection) {
|
||||||
|
$this->connection = $connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __get(string $name) {
|
||||||
|
$repository = $this->repositoryCache[$name] ?? null;
|
||||||
|
|
||||||
|
if (!$repository) {
|
||||||
|
$repository = new ($this->repositoryClasses[$name])($this->connection);
|
||||||
|
$this->repositoryCache[$name] = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(PDO $connection): Repositories {
|
||||||
|
return new Repositories($connection);
|
||||||
|
};
|
7
persistence/connection.php
Normal file
7
persistence/connection.php
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return (function() {
|
||||||
|
require(ROOT . "/credentials.php");
|
||||||
|
|
||||||
|
return new PDO($DB_DSN, $DB_USERNAME, $DB_PASSWORD);
|
||||||
|
})();
|
116
persistence/migrate.php
Normal file
116
persistence/migrate.php
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// has to be variable instead of const because PHP sucks
|
||||||
|
$MIGRATION_TABLE = "dm_migrations";
|
||||||
|
|
||||||
|
function ensureDbStructureForMigrations(PDO $connection) {
|
||||||
|
global $MIGRATION_TABLE;
|
||||||
|
|
||||||
|
require(ROOT . "/credentials.php");
|
||||||
|
|
||||||
|
if ($connection->query(<<<EOF
|
||||||
|
SELECT
|
||||||
|
TABLE_NAME
|
||||||
|
FROM
|
||||||
|
information_schema.TABLES
|
||||||
|
WHERE
|
||||||
|
TABLE_SCHEMA LIKE '${DB_SCHEMA}' AND
|
||||||
|
TABLE_TYPE LIKE 'BASE TABLE' AND
|
||||||
|
TABLE_NAME = '${MIGRATION_TABLE}'
|
||||||
|
EOF)->rowCount() == 0
|
||||||
|
) {
|
||||||
|
if ($connection->exec(<<<EOF
|
||||||
|
CREATE TABLE `${MIGRATION_TABLE}` (
|
||||||
|
`id` INTEGER PRIMARY KEY,
|
||||||
|
`file` VARCHAR(255),
|
||||||
|
`applied` DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
EOF) === false
|
||||||
|
) {
|
||||||
|
die("unable to bootstrap migrations: " . $connection->errorCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAllMigrations() {
|
||||||
|
$files = scandir(ROOT . "/persistence/migrations/");
|
||||||
|
$files = array_values(array_filter($files, fn($f) => $f[0] != "."));
|
||||||
|
sort($files);
|
||||||
|
|
||||||
|
$migrations = [];
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$delimiterPos = strpos($file, "_");
|
||||||
|
$migrations[intval(substr($file, 0, $delimiterPos))] = $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $migrations;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAppliedMigrations(PDO $connection) {
|
||||||
|
global $MIGRATION_TABLE;
|
||||||
|
|
||||||
|
$result = $connection->query(<<<EOF
|
||||||
|
SELECT * FROM `${MIGRATION_TABLE}`
|
||||||
|
EOF);
|
||||||
|
|
||||||
|
$migrations = [];
|
||||||
|
foreach ($result->fetchAll() as $row) {
|
||||||
|
$migrations[$row["id"]] = $row["file"];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $migrations;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMigrationsToApply(PDO $connection) {
|
||||||
|
$all = getAllMigrations();
|
||||||
|
$applied = getAppliedMigrations($connection);
|
||||||
|
|
||||||
|
foreach ($applied as $id => $file) {
|
||||||
|
unset($all[$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $all;
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeSqlScript(PDO $connection, string $sql, string $file) {
|
||||||
|
if ($connection->exec($sql) === false) {
|
||||||
|
die("failed to apply migration " . $file . ": " . $connection->errorCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyMigration(PDO $connection, int $id, string $file) {
|
||||||
|
global $MIGRATION_TABLE;
|
||||||
|
|
||||||
|
$connection->beginTransaction();
|
||||||
|
|
||||||
|
$sql = file_get_contents(ROOT . "/persistence/migrations/" . $file);
|
||||||
|
if (!$sql) {
|
||||||
|
die("Unable to read migration file: " . $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
executeSqlScript($connection, $sql, $file);
|
||||||
|
|
||||||
|
$statement = $connection->prepare(<<<EOF
|
||||||
|
INSERT INTO `${MIGRATION_TABLE}`
|
||||||
|
(`id`, `file`) VALUES
|
||||||
|
(?, ?)
|
||||||
|
EOF);
|
||||||
|
$statement->execute([$id, $file]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$connection->commit();
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
// this might happen if the migration script contains a DDL statement
|
||||||
|
// -> ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(PDO $connection) {
|
||||||
|
ensureDbStructureForMigrations($connection);
|
||||||
|
|
||||||
|
$migrations = getMigrationsToApply($connection);
|
||||||
|
foreach ($migrations as $id => $file) {
|
||||||
|
applyMigration($connection, $id, $file);
|
||||||
|
}
|
||||||
|
};
|
0
persistence/migrations/.gitkeep
Normal file
0
persistence/migrations/.gitkeep
Normal file
12
persistence/migrations/0001_addUrlTable.sql
Normal file
12
persistence/migrations/0001_addUrlTable.sql
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
CREATE TABLE `dm_urls` (
|
||||||
|
`id` BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`deleted` DATETIME,
|
||||||
|
`slug` VARCHAR(100) NOT NULL,
|
||||||
|
`url` VARCHAR(255) NOT NULL,
|
||||||
|
`access_key` VARCHAR(255),
|
||||||
|
|
||||||
|
INDEX (`slug`)
|
||||||
|
);
|
21
persistence/models/URL.php
Normal file
21
persistence/models/URL.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class URL {
|
||||||
|
public int $id;
|
||||||
|
public DateTime $created;
|
||||||
|
public DateTime $updated;
|
||||||
|
public DateTime $deleted;
|
||||||
|
public string $slug;
|
||||||
|
public string $url;
|
||||||
|
public string $accessKey;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
string $slug,
|
||||||
|
string $url,
|
||||||
|
string $accessKey
|
||||||
|
) {
|
||||||
|
$this->slug = $slug;
|
||||||
|
$this->url = $url;
|
||||||
|
$this->accessKey = $accessKey;
|
||||||
|
}
|
||||||
|
}
|
40
persistence/repositories/URLs.php
Normal file
40
persistence/repositories/URLs.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(__DIR__ . "/../models/URL.php");
|
||||||
|
|
||||||
|
class URLs {
|
||||||
|
private string $table = "dm_urls";
|
||||||
|
|
||||||
|
private PDO $connection;
|
||||||
|
|
||||||
|
public function __construct(PDO $connection) {
|
||||||
|
$this->connection = $connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add(URL $entry) {
|
||||||
|
$statement = $this->connection->prepare(<<<EOF
|
||||||
|
INSERT INTO `$this->table`
|
||||||
|
(`slug`, `url`, `access_key`) VALUES
|
||||||
|
(?, ?, ?)
|
||||||
|
EOF);
|
||||||
|
$statement->execute([
|
||||||
|
$entry->slug,
|
||||||
|
$entry->url,
|
||||||
|
$entry->accessKey,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBySlug(string $slug) {
|
||||||
|
$statement = $this->connection->prepare(<<<EOF
|
||||||
|
SELECT * FROM `$this->table`
|
||||||
|
WHERE `slug` = ?
|
||||||
|
EOF);
|
||||||
|
$statement->execute([$slug]);
|
||||||
|
|
||||||
|
if ($statement->rowCount() == 0) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return $statement->fetch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
78
router/Router.php
Normal file
78
router/Router.php
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(ROOT . "/utils/arrays.php");
|
||||||
|
require_once(ROOT . "/utils/error.php");
|
||||||
|
|
||||||
|
const GET = "GET";
|
||||||
|
const POST = "POST";
|
||||||
|
const PUT = "PUT";
|
||||||
|
const DELETE = "DELETE";
|
||||||
|
const HEAD = "HEAD";
|
||||||
|
const CONNECT = "CONNECT";
|
||||||
|
const OPTIONS = "OPTIONS";
|
||||||
|
const TRACE = "TRACE";
|
||||||
|
const PATCH = "PATCH";
|
||||||
|
|
||||||
|
class Router {
|
||||||
|
private $routes = [];
|
||||||
|
private $prefix = "";
|
||||||
|
public $notFoundHandler;
|
||||||
|
|
||||||
|
function __construct(string $prefix = "") {
|
||||||
|
$this->notFoundHandler = function(array &$context) {
|
||||||
|
setStatusCode(404);
|
||||||
|
require(ROOT . "/templates/404.php");
|
||||||
|
};
|
||||||
|
$this->prefix = $prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function findRoute(string $method, string $url) {
|
||||||
|
if (!key_exists($method, $this->routes)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$paths = $this->routes[$method];
|
||||||
|
|
||||||
|
foreach ($paths as $path => $handler) {
|
||||||
|
if (preg_match("/^" . str_replace("/", "\/", $path, ) . "$/", $url)) {
|
||||||
|
return $handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getPath($uri) {
|
||||||
|
if (($i = strpos($uri, "?")) !== false) {
|
||||||
|
return substr($uri, 0, $i);
|
||||||
|
} else {
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addRoute(string $method, string $path, $handler) {
|
||||||
|
array_get_or_add($method, $this->routes, [])[$path] = $handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(array &$context = []) {
|
||||||
|
$path = $this->getPath($_SERVER["REQUEST_URI"]);
|
||||||
|
$path = substr($path, strlen($this->prefix));
|
||||||
|
|
||||||
|
$route = $this->findRoute($_SERVER["REQUEST_METHOD"], $path);
|
||||||
|
|
||||||
|
if (!$route) {
|
||||||
|
$route = $this->notFoundHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
$context["REQUEST_PATH"] = $path;
|
||||||
|
|
||||||
|
return $route($context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calling magic to make the router a handler and thus cascade-able
|
||||||
|
public function __invoke(array &$context = []) {
|
||||||
|
return $this->execute($context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Router();
|
1
templates/404.php
Normal file
1
templates/404.php
Normal file
|
@ -0,0 +1 @@
|
||||||
|
404 Not found
|
1
templates/maintenance.php
Normal file
1
templates/maintenance.php
Normal file
|
@ -0,0 +1 @@
|
||||||
|
We are currently in maintenance mode.
|
10
utils/arrays.php
Normal file
10
utils/arrays.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function &array_get_or_add($needle, array &$haystack, $default=null) {
|
||||||
|
if (key_exists($needle, $haystack)) {
|
||||||
|
return $haystack[$needle];
|
||||||
|
} else {
|
||||||
|
$haystack[$needle] = $default;
|
||||||
|
return $haystack[$needle];
|
||||||
|
}
|
||||||
|
}
|
13
utils/error.php
Normal file
13
utils/error.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function setStatusCode(int $status) {
|
||||||
|
header("HTTP/", true, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorResponse(string $error, string $description) {
|
||||||
|
return [
|
||||||
|
"error" => $error,
|
||||||
|
"description" => $description,
|
||||||
|
"timestamp" => (new DateTime())->format("c")
|
||||||
|
];
|
||||||
|
}
|
45
utils/http.php
Normal file
45
utils/http.php
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function request(string $method, string $url, string $body = null, array $headers = []) {
|
||||||
|
$curlResource = curl_init();
|
||||||
|
|
||||||
|
curl_setopt($curlResource, CURLOPT_URL, $url);
|
||||||
|
curl_setopt($curlResource, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($curlResource, CURLOPT_CUSTOMREQUEST, $method);
|
||||||
|
curl_setopt($curlResource, CURLOPT_FOLLOWLOCATION, true);
|
||||||
|
curl_setopt($curlResource, CURLOPT_TIMEOUT, 10);
|
||||||
|
curl_setopt($curlResource, CURLOPT_FAILONERROR, true);
|
||||||
|
|
||||||
|
curl_setopt($curlResource, CURLOPT_VERBOSE, true);
|
||||||
|
|
||||||
|
if ($body)
|
||||||
|
curl_setopt($curlResource, CURLOPT_POSTFIELDS, $body);
|
||||||
|
|
||||||
|
if ($headers) {
|
||||||
|
if (!array_is_list($headers))
|
||||||
|
$headers = array_map(fn($k, $v) => $k . ": " . $v, array_keys($headers), array_values($headers));
|
||||||
|
|
||||||
|
|
||||||
|
curl_setopt($curlResource, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = curl_exec($curlResource);
|
||||||
|
$result = [
|
||||||
|
"body" => $body,
|
||||||
|
"isError" => curl_errno($curlResource),
|
||||||
|
"error" => curl_error($curlResource),
|
||||||
|
"status" => curl_getinfo($curlResource, CURLINFO_RESPONSE_CODE),
|
||||||
|
];
|
||||||
|
|
||||||
|
curl_close($curlResource);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRequest(string $url, array $headers = []) {
|
||||||
|
return request("GET", $url, null, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
function postRequest(string $url, string $body = null, $headers = []) {
|
||||||
|
return request("POST", $url, $body, $headers);
|
||||||
|
}
|
Loading…
Reference in a new issue