I have a little problem with a PHP warning:
I basically want to change the content of my page by clicking on links, like this:
<?php $page = ((!empty($_GET['page'])) ? $_GET['page'] : 'home'); ?>
<h1>Pages:</h1>
<ul>
<li>News</li>
<li>F.A.Q.</li>
<li>Contact</li>
</ul>
<?php include("$page.html");?>
This works really fine, but when I use a page that doesn't exist, for example
localhost/dir/index.php?page=notapage i get following error:
Warning: include(notapage.html): failed to open stream: No such file or directory in
C:\xampp\htdocs\dir\index.php on line 8
Warning: include(): Failed opening 'notapage.html' for inclusion (include_path='.;C:\xampp\php\PEAR') in C:\xampp\htdocs\dir\index.php on line 8
Is it possible to replace this warning by a custom message? (like a "404 not found")
Thanks in advance and happy easter!
You could use file_exists() but keep in mind that your approach is not very safe.
A safer approach would be using an array with allowed pages. This way you have a better control over user input. Something like this:
$pages = array(
'news' => 'News',
'faq' => 'F.A.Q.',
'contact' => 'Contact'
);
if (!empty($pages[$_GET['page']])) {
include($_GET['page'].'html');
} else {
include('error404.html');
}
You could also generate the menu using that array.
You can do
if (file_exists($page.html)) {
include("$page.html");
}
else
{
echo "404 Message";
}
Source: PHP Manual
You can check if the file exists() and then include a custom 404 template.
<?php
if (file_exists($page + '.html')) {
include ($page + '.html')
} else {
include ('404.html');
}
?>
The idea is to check if the file exists before trying to include() it:
if(!file_exists("$page.html"))
{
display_error404();
exit;
}
include("$page.html");
Yes it is possible, though I would recommend sending a 404 unless you are going to also use clean url's (like /news, /faq, /contact) that redirect behind the scenes to the index.php, writing the page parameter. This is because index.php really does exist, you just have a bad parameter. Thus a 404 would not be appropriate. This is not to mention that you actually can;t set a 404 header in this location anyway since you have already sent output to the browser.
For you case just set up a conditional on whether the file_exists and is readable like this:
$include_file = $page . '.html';
if (file_exists($include_file) && is_readable($include_file)) {
include($include_file);
} else {
// show error message
}
Related
I got this error message when i run my php CodeIgniter project:
A PHP Error was encountered
Severity: Warning
Message: Cannot modify header information - headers already sent by
(output started at
C:\AppServ\www\tree\application\models\mtree.php:17)
Filename: core/Common.php
Line Number: 442
line 17:
echo $row->members_id . "</br>";
this is my model function:
function convert_all() {
$this->db->empty_table('table1');
$this->db->empty_table('table2');
$this->db->query("INSERT INTO `table1` (`members_id`, `members_username`);
$query = $this->db->get('table2');
foreach ($query->result() as $row) {
if ($row->members_id > 1) {
echo $row->members_id . "</br>";
}
if ($this->isadvanced($row->members_id, $row->members_direct_id)) {
$this->insert_to_right($row, $row->members_direct_id);
} else {
$this->insert_to_left($row, $row->members_direct_id);
}
}
}
While using codeigniter, its best recommended that you echo only in views.
Echoing anywhere randomly sends some data to browser, after which you can't modify headers (this includes attempt to redirect, set content-type, etc)
You should re-organize your code, such that, echo are done within views only. This will solve your header issues in Codeigniter.
This also includes extra whitespaces at the end after the closing brace "} ?>" in non-view php files.
I think it will be helpfull
Use $config['sess_save_path'] = sys_get_temp_dir(); instead of $config['sess_save_path'] = NULL; in your Application/config/config.php file
You can't display anything before the header function is called. You should not display anything form model or controller to avoid this kind of error. If you want to display something form the controller or model then you should store the output to the buffer instead of sending it to the browser. You can store the output to the buffer using ob_start() function before header() function is called. Then you can do something like this
if(true)
{
header("Location:http://google.com");
}
else
{
ob_end_flush();
}
this was your issue - echo $row->members_id . ""; -- as the above answers say, don't echo something in your controllers, push to do it in the views - always
I'm trying "CheckBot" and I have an observation. The problem is that in my PHP code I have an if to check if the URL exists in a table called "seo_url" if it does not exist then we show the content of error.tpl
<?php
require_once 'app/config.php';
$url = isset($_GET["url"])?$_GET["url"]:'index';
$querytcseos = DB::queryFirstRow("SELECT * FROM tc_seos WHERE seo_url = %s LIMIT 1", $url);
require_once 'includes/header.tpl';
if (!$querytcseos['seo_file']) {
include 'includes/error.tpl';
} else {
include 'includes/'.$querytcseos['seo_file'].'.tpl';
}
require_once 'includes/footer.tpl';
?>
I see that this does not seem to be the right thing to do since "CheckBot" when you enter example.com/page-not-fount if you are finding content.
How do I get my error page taken as error 404?
http_response_code(404);
For best practice. You should respond it like that and let the server (Apache/Nginx/IIS) to handle the 404 page.
This is my code in index.php
include ($_GET['page']);
Actully i need to include page from url like
"?page=go.php"
on the other-hand i can not filter
"?page=example.com"
as for some case i need to include this value also. But this is a remote file inclusion (RFI) vulnerability. how can i prevent RFI attack from my site?
I am doing something like
$filename = $_GET['page'];
if (file_exists($filename)) {
{
include ($_GET['page']);
}
But it filters only
"?page=go.php"
this shorts of page.
And i am sucked with
"?page=example.com"
this shorts of page.
If I understand the question correctly; You could setup an array with 'allowed' pages such as:
$allowedPages = array('go.php', 'stop.php', 'file.php');
$filename = $_GET['page'];
if(in_array($filename, $allowedPages) && file_exists($filename)){
include ($filename);
}else{
//output error
}
I think this answer is too late, but for those who might search for this problem, I guess it can be done like this, too:
1.Define a constant with full path.
2.Define a white-list of allowed pages.
3.Get the $_GET variable, and convert it to lower case.
4.Then if the page returned by $_GET variable is in your white-list array, then require it, otherwise, redirect the user to the home page, and display an error message.
<?php
# this is abcd.php
define('SITE','http://www.yoursite.com/');
$allow = [SITE.'1.php', SITE.'2.php', SITE.'3.php'];
$get = strtolower(SITE.$_GET['page']);
if(in_array($get,$allow)){
include $get;
} else {
header('Location: index.php?param=incorrect');
}
?>
<?php
# this is index.php
if(isset($_GET['param']) && $_GET['param'] == 'incorrect'){
?>
<script type="text/javascript">
alert("INCORRECT PARAMETER PROVIDED");
</script>
<?php
} else die('ERROR');
I'm not 100% sure this will work without any probs, but I guess is a good start and you can play around with it and figure out what's suitable for you.
To be honest, your method of creating a dynamic website is definitely not the way to go.
To answer within the scope of this question, you'd do something like the following:
You'd have to set up a whitelist of files that are**ALLOWED** to be included through this function.
That could look something like this:
<?php
$whitelist = array(
'file1.php',
'file2.php',
'file3.php',
'file4.php',
'file5.php',
);
?>
Now before including the said file, you'd run a check with in_array()
<?php
if(in_array($_GET['page'] . '.php', $whitelist) && file_exists($_GET['page'] . '.php')) {
include($_GET['page'] . '.php');
}
?>
This, as you can see is not very pretty!
Another alternative would be doing something like:
<?php
$file = strtolower($_GET['page']) . '.php';
if(isset($whitelist[$file]) && file_exists($file)) {
include($_GET['page'] . '.php');
}
?>
Don't accept a page.php parameter, but just the name of the file.
"?page=go"
Then check if $_REQUEST["page"] is alphanumeric
if (ctype_alnum($_REQUEST["page"]))
And just don't give non-alpha-numeric names to your files.
Then do if file_exists on $_REQUEST["page"] and you should be quite good.
PS
$_REQUEST["page"] is about the same with $_GET["page"], it just intersects with $_POST
You can filter other domain urls instead of filtering files.
If parameter contains a hostname less than 3 letters, it is fine as no domain is 2 letters.
$tmp= parse_url ($_GET['page']);
if(strlen($tmp['host'])<3)
include($_GET['page']);
If there are some trusted hosts then you can validate them too.
I'm working with a page that, once a link is called this script checks and if the POST contains the keyword it and then finds that page. However no matter how I organize this if it doesn't work.
<?PHP
if($_POST['page']) {
$page = (int)$_POST['page'];
$exists = file_exists('pages/page_'.$page.'html');
if($exists) {
echo file_get_contexnts('pages/page_'.$page.'html');
} else {
echo 'There is no such page!';
}
} else if ($_POST['course']) die("0"); {
$course = (int)$_POST['course'];
$exists = file_exists('courses/course_'.$course.'html');
if($exists) {
echo file_get_contexnts('courses/course_'.$course.'html');
die("1");
} else {
echo 'There is no such page!';
}
}
?>
The error I'm currently receiving with this setup is:
Notice: Undefined index: course in C:\wamp\www\Home Page\load_page.php on line 12
Call Stack
# Time Memory Function Location
1 0.0003 253944 {main}( ) ..\load_page.php:0
Is it because there is no 'course' in the page? I might be confused of the code I'm modifying a tutorial of a simple ajax website. It is possible what I am trying to do does not work.
In that case how could I possible go about doing what I want to do.
Right now I have a home page and it loads in another page without switching pages. I like the floridness of it. I would like to have a sort of sub call. So if you are on the home page and you go to courses page then you can click on a specific course and that will load from a different directory within the courses directory.
Homepage (when you click on courses you go to...)
pages/courses_home.html (when you click on a course you go to...)
courses/course_1.html (you can view course and then click back to directory above or go to home)
That is the structure I'm looking to try to achieve.
If more information is needed please let me know what and I'll do my best to include it. Thank you.
The syntax should be:
if(isset($_POST["page"])) {
} elseif(isset($_POST["course"])) {
}
I am not sure why you have a die statement there, but I don't think it belongs. Also, keep in mind the logic for what happens if neither of these conditions is met.
Edit: also keep in mind that isset doesn't prevent empty strings, so you may want to check for that as well. A function you could use is
function checkPost($value) {
return isset($_POST[$value]) && $_POST[$value] !== "";
}
To use:
if(checkPost('page')) {
//some logic
}
Wrong syntax.
elseif ($_POST['course']) {
without die statement.If 'course' undefined else statement works and does not get error. Sorry for bad English.
Try this:
if isset(($_POST['page'])) {
...
} else if isset(($_POST['course'])) die("0"); {
instead of this:
if($_POST['page']) {
...
} else if ($_POST['course']) die("0"); {
I would like to open a page using index.php?do=settings,
I'm using following code:
$do='';
if (isset($_GET['do'])){
$do = strip_tags($_GET['action']);
}
if ($do == 'settings') {
header("location:settings.php");
}
if ($do == 'posts') {
header("location:posts.php");
}
but the problem is that I have manually add all menu in actions like above to make it work and when it redirects me, the index.php?do=settings disappears and just show me settings.php which I do not want
To avoid having to set it manually you can store the pages in an array with the keys as the page name and the value as the file and then include the file:
$pages = array(
'settings' => 'settings.php',
'otherpage' => 'somePage.php'
);
if (isset($pages[$do])) {
include $pages[$do];
}
You should include the file as the reason the URL changes is because of the redirect.
add the get var back in like so
header("location: http://yoursite.com/settings.php?do=".$do);
NB: that should be the full uri not a relative one
You can use http_build_query($_GET) to generate the query string for links that need to conserve GET data.
If you need to modify a GET key, save GET to a temp array, modify that and pass it to http_build_query.