I'm making a content management system. I'm allowing the user to post a few bits of information through a form which will then be used on the new page (such as 'page title' and 'carousel speed'), but I'm struggling to get that information into the generated page.
To add the content of the site I'm using $page .= <<<'EOT'
and placing the html in there, but trying to echo $_POST
variables within this means that the PHP code will literally appear as I write it inside the EOT and not as a result.
Is there a way to tell the EOT to treat the <?php echo $_POST['speed'] ?>
as an exception?
<?php
$addTo = $_POST['addTo'];
//$visit = $_POST['visit'];
$dir = $_POST['name'];
$desc = $_POST['desc'];
$dir = preg_replace('/\s+/', '_', $dir);
mkdir($addTo.'/'.$dir, 0777);
mkdir($addTo.'/'.$dir.'/photos', 0777);
//Make page
$content = "he";
$myfile = fopen ($addTo.'/'.$dir.'/index.php', "w") or die ("Unable to open file!");
$page = "";
$speed = $_POST['speed'];
$page .= <<<'EOT'
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script src="https://use.fontawesome.com/2c6a42bed3.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div id="myCarousel" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators" style="display:none">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
<li data-target="#myCarousel" data-slide-to="3"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<?php
$active = "active";
$url = $_SERVER['REQUEST_URI'].'photos/';
//echo $url." - url<br/>";
$conn = mysqli_connect("localhost","root","","test");
$sql = "SELECT speed FROM pages WHERE title = ''";
if (mysqli_connect_errno()) {echo "Failed to connect to MySQL: " . mysqli_connect_error();}
$sql = "SELECT * FROM photos WHERE url = '$url'";
$result = mysqli_query($conn, $sql);
while($row = mysqli_fetch_array($result)) {
?>
<div class="item <?=$active?>">
<img src="<?php echo $row['url'].$row['caption']; ?>">
</div>
<?php
$active="";
}
$conn->close();
?>
</div>
<!-- Left and right controls -->
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</body>
<script type="text/javascript">
$(document).ready(function(){
$("#myCarousel").carousel({
interval : 420,
pause: false
});
});
</script>
%s
EOT;
?>
<?php
$output = sprintf($page, $speed);
echo $output;
fwrite($myfile, $page);
fclose($myfile);
$conn = mysqli_connect("localhost","root","","test");
if (mysqli_connect_errno()) {echo "Failed to connect to MySQL: " . mysqli_connect_error();}
$sql = "INSERT INTO pages (title, type, description, active, speed) VALUES ('$dir', '$addTo','$desc' , '1', '$speed')";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
//Redirect
if (isset($visit)){
//header('Location:index.php?newPage='.$addTo.'/'.$dir.'/'.$filename);
}
else {
//header('Location:index.php?newPage='.$addTo.'/'.$dir.'/'.$filename);
}
?>
Is there a way to tell the EOT to treat the
<?php echo
as an exception?
No there isn't, unless you replace 'EOT'
with "EOT"
. The first one (what you're currently using) treats everything as a raw string. The second one works just as double-quotes in PHP, so the string will be parsed and variables will be recognized.
I would keep using 'EOT'
as you are, and insert placeholders %s
in the string. Then I'd use sprintf
to replace the placeholders with values (see the docs)
// the %s will be replaced later with your values
$template = <<< 'EOT'
The car has speed %s and a mileage of %s ...
EOT;
//build the args. Use htmlspecialchars to protect your users from
// Cross-Site Scripting attacks
$args = [
htmlspecialchars($_POST['speed']),
htmlspecialchars($_POST['mileage']),
...
];
//insert the args into the template
$output = sprintf($template, ...$args);
echo $output;
security note: Because you output strings the user sent you back to the browser, you are vulnerable to Cross-Site Scripting (XSS) attacks: a user can get your website to execute any code she wants since you're using her input to build the page. I cleaned the inputs with htmlspecialchars()
to protect you.