Here's my code:
<?php
if(isset($_GET['p']))
{
$nshortname = strip_tags($_GET['p']);
$check = mysql_query("SELECT * FROM pages WHERE `shortname` = '$nshortname'");
if(mysql_num_rows($check) == 0)
{
echo '<center><font size="50" style="font-weight:bold;">404</font><br>Appears this page is a dead end</center>';
}
else
{
$h = mysql_fetch_array($check);
//post details
$title = $h["title"];
$content = $h["content"];
$shortname = $h["shortname"];
// Start of page content
echo '
<p>
<font size="5pt">'.$title.'</font><br><hr>
'.$content.'<br>
';
// End of page content
}
}
else
{
echo 'No page has been selected to view';
}
?>
What it does exactly, is it grabs pages from my database and reads them, so for example if I have a page in that table called "test" I can go to it by http://mylink.com/?p=test. Although i've come up with an issue. On one of those pages that come from the database I want to include but when I type it into the database field and go back to the page it shows with nothing.
I went to the source of the page in my browser and found out the code turned into <!--?php include "inc/extra/plugins/header/slideshow.php"?-->
Does anyone know how I can sold it from turning into <!--? and make my include code work.
I would caution against using eval() of unknown content. Basically, the content comes from your database, but that doesn't guarantee it's safe to execute as code! There are a lot of ways it could cause errors or do something malicious.
But you also have other dangerous security gaffes in your code. You should learn about how to defend against SQL injection vulnerabilities and Cross-Site Scripting (XSS) vulnerabilities and File Inclusion vulnerabilities.
Use mysql_real_escape_string() if you are still using the deprecated ext/mysql. But if you can, switch to mysqli or PDO_mysql and use prepared statements with parameters.
Always output dynamic content with htmlspecialchars(). What if the content contains Javascript code? It could cause mischief.
Never eval() arbitrary content as code. You have no control over what that content is, or what it could do when you execute it.
Be as restrictive as possible - if you want to include a file, store the filename separately from content (e.g. in a separate column), and use it only for including files.
Here's an example with some of these problems fixed in your code:
<?php
if(isset($_GET['p']))
{
$nshortname = mysql_real_escape_string($_GET['p']);
$check = mysql_query("SELECT * FROM pages WHERE `shortname` = '$nshortname'");
if(mysql_num_rows($check) == 0)
{
echo '<center><font size="50" style="font-weight:bold;">404</font><br>Appears this page is a dead end</center>';
}
else
{
$h = mysql_fetch_array($check);
//post details
$title = htmlspecialchars($h["title"]);
$content = htmlspecialchars($h["content"]);
$shortname = $h["shortname"];
// Start of page content
echo '
<p>
<font size="5pt">'.$title.'</font><br><hr>
'.$content.'<br>
';
// End of page content
// Start of include
if ($h["include"]) {
// strip out anything like "../../.." etc.
// to make sure this is only a simple filename.
$include = basename($h["include"]);
include "inc/extra/plugins/header/{$include}.php";
}
// End of plugin inclusion
}
}
else
{
echo 'No page has been selected to view';
}
?>
Also check out http://www.sitepoint.com/php-security-blunders/ and http://phpsec.org/projects/phpsecinfo/
Re your comments:
To allow a limited set of basic HTML, the best tool you need to use is http://htmlpurifier.org
I'm not sure what to say about your include displaying code instead of working. I just tested this, and the following two files seem to work exactly as intended:
foo.php:
<?php
echo "<h1>START FOO</h2>";
if ($_GET["include"]) {
$include = basename($_GET["include"]);
include "./{$include}.php";
}
echo "<h1>END FOO</h2>";
bar.php:
<?php
echo "<h2>BAR</h2>";
If you have a variable $content which is html with php, you can use
eval("?>" . $content . "<?php");
This will output $content having processed all the <?php ?> tags.
Related
I want to place an image, HTML or simply text as a page header on multiple pages, but it is specific to each page, based on the file name (and folder it is in).
So, for example, domain.com/portfolio/index.php gets one image (or text/HTML/CSS), domain.com/portfolio/about/index.php gets another, domain.com/portfolio/contact/index.php gets another and so on.
Basically, I want to update this common element from one file instead of updating a bunch of files. I will usually use either the same image or the same HTML/CC design with different text and/or image in it, so the code example below includes a simplified version of each, just in case.
I've successfully used this in the past for pageheaders on sites but it no longer seems to work (PHP updated or maybe Bootstrap 5 is mucking things up)... it sits in pageheader.php which is then included in the top.php that is used (included) on each page of the site. (And I am not a programmer :) )
Help is always appreciated - thanks!
<?php
$path = ("/portfolio");
$size = ("WIDTH=525 HEIGHT=41 BORDER=0");
$self = $_SERVER['PHP_SELF'];
if (strstr($PHP_SELF,"$path/about.php")) {echo "<h1>About Page Header HTML/CSS Here!</h1>";}
elseif (strstr($PHP_SELF,"$path/index.php")) {echo "Home Page Header Text Here";}
elseif (strstr($PHP_SELF,"$path/design/index.php")) print ("<IMG SRC=$path/images/header_design.jpg $size>");
elseif (strstr($PHP_SELF,"$path/articles/index.php")) print ("<IMG SRC=$path/images/header_articles.jpg $size>");
else {echo "<h1>Hello World.</h1>";}
?>
Note : $PHP_SELF in (strstr($PHP_SELF,"$path/about.php"))
Shouldn't it be $self, e.g. (strstr($self,"$path/about.php"))
<?php
$path = ("/portfolio");
$size = ("WIDTH=525 HEIGHT=41 BORDER=0");
$self = $_SERVER['PHP_SELF'];
if (strstr($self ,"$path/about.php")) {echo "<h1>About Page Header HTML/CSS Here!</h1>";}
elseif (strstr($self ,"$path/index.php")) {echo "Home Page Header Text Here";}
elseif (strstr($self ,"$path/design/index.php")) print ("<IMG SRC=$path/images/header_design.jpg $size>");
elseif (strstr($self ,"$path/articles/index.php")) print ("<IMG SRC=$path/images/header_articles.jpg $size>");
else {echo "<h1>Hello World.</h1>";}
?>
I know it has been discussed many times, but I can not find any solution to this problem.
I have a PHP file with the following code
if (file_exists("email.html")) {
$message = file_get_contents("email.html");
} else {
echo "No email.html file present";
return;
}
in my file email.html I have something like:
<p>Hello %recipient.UserName%, you receive this Email because you signed up at our site.</p>
variable $UserName is declared in the php file (in array).
When looking at the html file output, I see the variable is not correctly passed and stays as % %
Any suggestion?
thanks!
If you don't have a template engine you can't do it with % % OR other symbol . for your question simple approach is to use it like this :
<p>Hello <? = $recipient['UserName'] ?>, you receive this Email because you signed up at our site.</p>
EDIT
you have to include the file
ob_start();
include "email.html";
$message = ob_get_clean();
The title says it all: I want the page to determine the title, but the title is being set before the page is being read (I think). Is there a way to accomplish this, or am I doomed to include the header on each individual page?
Here's what I have:
php.ini:
auto_prepend_file = "header.php"
header.php:
<?php
if (isset($title) == false) {
$title = "foobar";
}
$title = "My Site : " . $title;
?>
<title><?php echo($title) ?></title>
index.php
<?php
$title = "Home"; // ideally this would make the title "My Site : Home"
?>
Instead of using auto_prepend_file, I would just use:
include 'header.php';
An important reason why I wouldn't use auto_prepend_file is, if you move to another server, you'll have to remember to edit the php.ini. If you just include the file, you can move your code to any server.
Also, just like Fred-ii- said, I wouldn't use parenthesis. Also, you are missing a semi-colon after the echo.
To take that a step further, I would create a file called something like $config.php or $vars.php. Include that before everything and have it define all your global variables and constants.
I would check this out: http://php.about.com/od/tutorials/ht/template_site.htm
This is not an ideal answer, but I could use CGI variables to get the name of the page, then turn that into a title.
function get_title($page){
$title = str_replace("/", "", $page);
$title = str_replace("_", " ", $title);
$title = str_replace(".php", "", $title);
$title = ucfirst($title);
if($title = "Index"){
$title = "Home";
} elseif ($title == "") {
$title = 'Foobar';
}
return $title;
}
$title = get_title($_SERVER["PHP_SELF"]);
$title = 'My Site: ' . $title;
As a follow-up to my original comment, I'm posting this as an answer because while it doesn't specifically solve the problem, it addresses the underlying cause.
Disclaimer: The code below has many problems, especially security, it's not meant to be copied directly but only explains the concept.
What you need to do is have a container file that includes your headers and whatever else, and each PHP file is included from there. For example, name your container index.php, and have the following in it:
<?php
include 'header.php';
if ($_GET['page'])
include $_GET['page'].'.php';
include 'footer.php';
?>
Then each PHP page you have will be wrapped in the index.php file, and you can add whatever you want in the header file which will be included in all of your files. That way you don't have to include anything in the individual page files.
The client will access your pages with a query string, such as: index.php?page=test
Again, for security reasons you will still want to include basic checks in each individual file, but technically this can be avoided in you plan for this. You definitely won't need to include huge headers in each file, like MySQL connections etc. Also for security you should have stringent checks on your $_GET variables to make sure that only the pages you want can be included.
I'd define a writeTitle (or similar) function in the header.php file which you're auto_prepending:
header.php
<?php
function writeTitle($title = 'foobar') {
$title = "My Site : " . $title;
return '<title>' . $title . </title>';
}
And then you can just call the function from your page scripts instead of setting a variable:
index.php
<?php
echo writeTitle('Home');
I am a total PHP novice and am trying to write what I think is a pretty simple script. This is the code I have so far:
HTML / PHP
<?php
$hits = file_get_contents('hits.txt');
++$hits;
file_put_contents('hits.txt', $hits);
echo $hits;
$url = $_GET['w'];
?>
<iframe src="<?php echo $url; ?>"></iframe>
<p>
<?php echo $hits; ?>
</p>
The result is a page with an iframe and a hit counter.
The problem with this script is that if the variable $url changes, the hit counter does not. My goal would be that if I visited http://www.website.com/index.php?w=blue.html I would get a different counter than if I visited http://www.website.com/index.php?w=yellow.html.
EDIT: I should add that this script is designed to accept any URL. I realize this complicates things significantly. My ultimate goal would be that if the counter didn't already exist for that particular URL, it would be generated on the fly.
Your current code saves the hit points for every page to the same file as a simple string.
You have a number of options. Here's one that would work if you prefer to stick with text files instead of databases.
You could take the URL in, hash it, and save the counter for that page in a hash-named text file.
Something like
if( isset($_GET) && !empty($_GET['W']) ){
$url = md5($_GET['w']);
$hits = file_get_contents('/hit_counters/'.$url.'.txt');
$hits++;
file_put_contents('/hit_counters/'.$url.'.txt', $hits);
}
and then later you could echo out the hits under that or pull the hits in on another script and echo like that.
If you need it to create new ones on the fly, you could add something like
if(!is_file('/hit_counters/'.$url.'.txt')){
$fh= fopen('/hit_counters/'.$url.'.txt', 'w');
fwrite($fh, '1');
fclose($fh);
}
NOTE
This could end up creating a ton of tiny text files, though. So be aware. If you are worried about that, you would really need to look into a database or read in a text file line by line to find the same hash.
TO IMPLEMENT
Replace the top part of your code within the <?php ?> with the following:
if( isset($_GET) && !empty($_GET['W']) ){
$url = md5($_GET['w']);
if(!is_file('/hit_counters/'.$url.'.txt')){
$fh= fopen('/hit_counters/'.$url.'.txt', 'w');
fwrite($fh, '1');
fclose($fh);
}else{
$hits = file_get_contents('/hit_counters/'.$url.'.txt');
$hits++;
file_put_contents('/hit_counters/'.$url.'.txt', $hits);
}
}
This will take the page name in, hash it, check to see if /hit_counters/THEHASH.txt exists, and create it if not or add +1 to it otherwise. A hash is sort of like encryption, but not really. It will change your $_get['w'] into a longer random-looking string.
You're writing the same hits.txt file regardless of what $_GET['w'] is set to. Try putting the hits.txt file in a folder like this:
<?php
$url = $_GET['w'];
$dir = str_replace(".html", "", $url);
$hits = file_get_contents($dir.'/hits.txt');
++$hits;
file_put_contents($dir.'/hits.txt', $hits);
echo $hits;
?>
<iframe src="<?php echo $url; ?>"></iframe>
<p>
<?php echo $hits; ?>
</p>
I am storing in a mySQL table the HTML/PHP content of individual slides to be displayed on a single page.
Here is an example of HTML/PHP code stored in the mySQL table:
<p>Welcome <?php echo $userData['fname']; ?>!</p>
<p>You made it to the first slide!</p>
I retrieve the content of the slides in PHP with the following code:
<?php
$fetchedPageSlideData = mysql_query("SELECT * FROM pageSlides WHERE pageID = $pageID ORDER BY 'order' DESC") or die(mysql_error());
while ($pageSlideData = mysql_fetch_array($fetchedPageSlideData)) {
$pageSlideContent = $pageSlideData['content']; ?>
<div><?php echo $pageSlideContent; ?></div>
<?php }
?>
All of the HTML of the content displays correctly, but the PHP is inserted as follows:
<!--?php echo $userData['fname']; ?-->
So the PHP is commented out and doesn't display.
How can I retrieve the HTML/PHP code and have the PHP not commented out?
It might be a better idea to use placeholder strings in the DB data. Executing arbitrary php code from a DB can be dangerous. PHP is Evil
Look into PHP function eval(): http://php.net/manual/en/function.eval.php
Dropping in and out of the PHP interpreter makes your code rather difficult to read. Consider:
<?php
$f = mysql_query(
"SELECT *
FROM pageSlides
WHERE pageID = $pageID
ORDER BY 'order' DESC"
) or die(mysql_error());
while ($d = mysql_fetch_array($f)) {
print "<div>" . $d['content'] . "</div>\n";
}
Regardless there is no implicit nor explicit mechanism here which would inject the comment tags you've presented. However it may be the browser trying to make sense of the unescaped html code and <?php ... ?> tags.
Try:
print "<div>" . htmlentities($d['content']) . "</div>\n";
As a side note, you might consider using
print "<div>" . highlight_string($d['content']) . "</div>\n";
Or do you mean that you actually want to run the code stored in the database - if so, you're asking for a world of pain. Eval is not evil - but you really must know what you're doing to avoid getting bitten by it.