Any tips or review points are appreciated, I'm not much familiar with server-side web-dev (PHP) and DB.
Few things of note:
I see no reason to separate codebase into different files and bother with
imports
- provided code is ALL the project and some paradigm boilerplate approach makes no sense. Also saves few disk reads. But if you disagree I'm all ears.ASCII for DB was deliberate, I knew the data I will be using and storing beforehand, I also wanted to see if I can make it work under the narrow and defined conditions. Yes, I know, I could just set utf8mb4 and forget. If it was more complex and public project with variety of data that would be it.
<html>
<head>
<title>Video Mirror</title>
</head>
<body>
<?php
ini_set('display_errors', 1);
if (!$_GET || empty($_GET['path'])) { die("No video ID specified"); }
//
$vKey = $_GET['path'];
$db_user = "linus_torvalds";
$db_pass = "kernel_overflow";
$db_conn = "mysql:host=localhost;dbname=streamab_vdata;charset=ascii";
if (!ctype_alnum($vKey) || (mb_strlen($vKey) > 6 || mb_strlen($vKey) < 5)) { die("Ivalid video key format"); }
$PDO = new PDO($db_conn, $db_user, $db_pass);
$SQL_QUERY = "SELECT * FROM cache WHERE id = ? LIMIT 1";
$queryStmnt = $PDO->prepare($SQL_QUERY);
$queryStmnt->execute([$vKey]);
$data = $queryStmnt->fetch();
if(!$data || ($data && $data['timestamp'] < time()))
{
$data = fethRemote("https://kino.com/$vKey");
$SQL_QUERY = "INSERT INTO cache (id, timestamp, url, width, height, type) VALUES(:id, :timestamp, :url, :width, :height, :type) ON DUPLICATE KEY UPDATE timestamp = :timestamp, url = :url";
$queryStmnt = $PDO->prepare($SQL_QUERY);
$queryStmnt->execute($data);
}
echo buildBody($data);
//
//Helpers
function doSQL($con, $query, $values)
{
$queryStmnt = $con->prepare($query);
$queryStmnt->execute($values);
//uhh conditional return?
}
function buildBody($values)
{
$vStyle = 'style="width:' . $values['width']. 'px;height:' . $values['height'] . 'px;\"';
$vSrc = 'src="' . $values['url'] . '"';
$vType = 'type="' . $values['type'] . '"';
return "<video controls $vStyle <source $vSrc $vType></video>";
}
function fethRemote($url)
{
$html = file_get_contents($url);
if(!$html || empty($html)) { die("Failed to fetch any data"); }
$dom = new DOMDocument;
@$dom->loadHTML($html);
$metaTags = $dom->getElementsByTagName('meta');
$data = ['id' => $vKey, 'timestamp' => '', 'url' => '', 'width' => '', 'height' => '', 'type' => ''];
foreach ($metaTags as $tag)
{
$c = $tag->getAttribute('content');
$p = $tag->getAttribute('property');
if(empty($c) || empty($p)) { continue; }
switch ($p)
{
case 'og:video:width':
$data['width'] = $c;
break;
case 'og:video:height':
$data['height'] = $c;
break;
case 'og:video:type':
$data['type'] = $c;
break;
case 'og:video:url':
$data['url'] = $c;
break;
}
}
if(empty($data) || empty($data['url'])) { die("Fetched page data does not contain valid matching tags"); }
$url_components = parse_url($data['url']);
parse_str($url_components['query'], $params);
$data['timestamp'] = $params['Expires'];
return $data;
}
?>
</body>
</html>
Few direct questions:
- Do people still put MySQL credential into the plain php-files or env. variables? Are we still in the stone age of security?
- PDO handles most of the query sanitation, is there something more I'm missing?
include/config.php
file that contains stuff like database credentials, which can then be set to be readable only to the user itself, with access to the include/ directory blocked by server configuration. But the core problem is that php needs to know those credentials in order to be able to authenticate to the database server, so they're going to have to be in plaintext somewhere. \$\endgroup\$