So, I got my PHP script to store input in a .txt file, however, something is not working with my html page. I want to output text to both a .txt file as well as a div on my html page.
I personally think it has to do with the fact that the script itself is on a separate page and I'm refreshing the page so there is never an opportunity to show up. I feel like what the PHP script should do is pull from the .txt file instead. But not sure.
I've tried action="" and putting the PHP on the same page but that didn't write to the .txt file. The ONLY way it has written to the .txt file is when I do action="[php file]".
Any ideas?
HTML:
The reference:
<?php require_once('storeText.php');?>
The Form:
<form id="post" name="post" action="storeText.php" method="post">
<textarea name="msg" rows="5"></textarea>
<input class="button" name="submit" type="submit" value="SQUAWK!"/>
</form>
Where I want the input to go on the page:
<div class="menuItem" >
<?php echo $msg; ?>
</div>
PHP:
storeText.php
<?php
if ( isset( $_POST['submit'] ) ) {
$filename = 'posts.txt';
$msg = (isset($_POST['msg']) ? $_POST['msg'] : null);
if ( is_writable( $filename ) ) {
if ( $handle = fopen( $filename, 'a') ) {
fwrite( $handle, $msg );
echo "Success, wrote ( $msg ) to file ( $filename )";
fclose( $handle );
} else {
echo "Could not open file.";
}
} else {
echo "File not writable.";
}
header("Location: profile.html");
}
?>
FYI- I decided to use an alternate script for all the fwrite() haters out there... same deal... won't write to html page.
ALTERNATE PHP:
<?php
if(isset($_POST['submit']))
{
$file = 'posts.txt';
// Open the file to get existing content
$msg = file_get_contents($file);
// Append new content to the file
$msg .= (isset($_POST['msg']) ? $_POST['msg'] : null);
// Write the contents back to the file
file_put_contents($file, $msg);
header("Location: profile.html");
}
?>
Nikhil Patel pretty much beat me to this in the comments on your question, but let me try to offer some more detail.
I'm not 100% sure I'm reading your question correctly, so correct me if I'm wrong on any of this: You have a form on profile.html, which sumbits to storeText.php. StoreText.php writes the file and redirects back to profile.html. Then you want profile.html to display the same $msg variable that got written to the text file, but it isn't doing that. Is that right?
You may have a problem with expecting a .html file to be executed as PHP code. I don't know how your Web server is set up, but normally only .php files are parsed by PHP. You might try renaming profile.html to profile.php and see if that makes a difference. From here on out, I'll be assuming that profile.html is being parsed as PHP; if I'm wrong about that, you'll probably have to rename the file.
The real problem is the redirect. You could take either of two different approaches here. One way to do it would be to include storeText.php in profile.html and have the form submit to profile.html. Then the $msg variable would be available in profile.html and should display. The other approach would be a POST/redirect/GET setup in which the form submitted to storeText.php, which did the work and redirected the user back to profile.html.
The thing is, you can't do both the include and the redirect. That's where you're running into problems. See, each HTTP request from the client, including the new request that the client sends in response to the redirect header, causes your script to be run again from scratch. The brand new profile.html that starts up after the redirect has never seen the $msg variable that contained the value that was written to the file. The reason submitting to profile.html didn't work is that it includes all the code from storeText.php, including the redirect, and even if you redirect to the same file, it's still a new request.
If you want to use the redirect, you'll need some way of storing that variable on the server side so that profile.html can get to it. The usual way of doing this is with sessions. Just have both profile.html and storeText.php set up sessions, have storeText.php save $msg to the session, and have profile.html pull it back out. Then remove the require_once('storeText.php'); line from profile.html, since you don't need that logic there anymore.
If you're not attached to the redirect, then you can do what I normally do (and what Nikhil Patel suggested in the comments). I normally put my form-displaying logic and my form-processing logic in one file, which decides what to do based on whether there's form input. I find this makes it easier to do validation, among other things, but I digress. All you really have to change here is to have the form submit to profile.html (action="" will work fine) and remove the redirect from storeText.php. Then everything will work as you expect.
However, both these approaches are completely wrong if the whole point of what you're doing is to make profile.html output whatever's in the text file, regardless of whether or not you're seeing it right after the form submission. In that case, don't worry about keeping that $msg variable at all. Keep storeText.php pretty much as it is, including the redirect. Remove the include from profile.html. Then, instead of having profile.html just try to echo $msg, have it open the file and echo its contents. (You can even set up a loop to read in one line at a time and put each one in a separate div if you want.)
On re-reading your question, I can't quite tell which behavior you actually want. Your first version of storeText.php only stores the new content in $msg, and uses the fopen/fwrite/etc. functions to append it to the file. So if $msg did survive the redirect (e.g. if you stored it in a session), the user would only see the new bit that was added to the file. The alternate version loads the file into $msg, appends the new content to that, and overwrites the file with $msg. If $msg survived the redirect in that case, the user would see the entire contents of the file.
However, in either case, the user would only see the results right after submitting the form; a fresh GET request to profile.html would still show an empty div. If you want the information to be displayed any time a user views profile.html, reading it from the file is the only option.
By the way, you may already know this but it is worth making explicit anyway: Do not display any values you got from the user without escaping them. If you do, then your page will allow an attacker to input malicious code and have it run in your users' browsers. This applies whether you got the values from the last form input or from a file. Read up on cross-site scripting (XSS) at IT Security StackExchange or OWASP.org.
Use File Put Content to store data on any file
Related
I have 2 files :
// test-redirect1.php
<?php
session_start();
$_SESSION['ctrl_access'] = '81938193813819381';
// then some codes here...
?>
and this file :
// test-redirect2.php
<?php
session_start();
if ($_SESSION['ctrl_access'] != '81938193813819381') {
header( 'Location : goto-hell.php' );
}
// then some codes here...
?>
I want to have test-redirect2.php only proceed when the referrer file is test-redirect1.php.
I tried to use $_SERVER["HTTP_REFERER"] in test-redirect2.php but it doesn't show up if test-redirect1.php use header( 'Location : some-file' ); as redirect.
also, I don't want to show the ctrl_access variable to user. That's why I don't want to use POST / GET method.
so, I decided to go with $_SESSION...
but, the problem with the $_SESSION is, once I open test-redirect1.php on my browser, that variable is created then I can open test-redirect2.php and passing if condition.
how to have test-redirect2.php only proceed when the referrer file is test-redirect1.php?
thank you.
The "http referer" variable is sent by the browser. It is not a good security method for that reason, as it can be easily spoofed, however, you already answered your question as to how it is sent reliably. It is sent when you move from one page to another via a user clicking on a link.
You could probably trigger this behavior with javascript in a variety of ways such as:
document.getElementById('some_link_id').click();
The entire idea is bad. Adult sites were infamous for using this technique for security, and were easily exploited using browser plugins that let you set HTTP headers.
The session method you were using is far better.
Say I have two html files called html1 and html2. html1 contains an embedded swf file.
Now what I want is that the user can not go to html2 directly via url. He has to click it through the link in the swf in html1. Is there a way to achieve this?
If not possible in html, is it possible with php?
Thanks
EDIT:
After answer from John, I went ahead and tried his advice, but I can never access the file2.php, even if I have been to file1.php before. It keeps redirecting me back to file1.php, even when it should not.
My code from file1.php
//file1.php
<?php
session_start();
$_SESSION['enableAccessTill']=strtotime("+5 minutes");
?>
Here is file2.php
//file2.php
<?php
session_start();
if(!isset($_SESSION['enableAccessTil'])||$_SESSION['enableAccessTil']<time())
{
header("Location: indexFLA.php");
exit;
}
?>
what am I possibly doing wrong?
found it, it was due to a misspelling - "enableAccessTil" and "enableAccessTill"
professional solution:
create protected directory and make .htaccess file in directory and copy all embedded and partial files into directory.
this directory not accessible whit get url.
but you can include file whit php include and require method.
.htaccess content:
deny from all
This wont be possible in just plain html.
An easy way to do this is php is by setting a session variable in file 1, and test in file 2 it the users has been to file 1.
file1:
<?php
session_start();
$_SESSION['enableAccessTill'] = strtotime("+5 minutes"); //set the time here till when the user has access
[...]
file2
<?php
session_start();
if(!isset( $_SESSION['enableAccessTill'] ) || $_SESSION['enableAccessTill'] < time() ){ //If time is expired
header("Location: file1.php"); //redirect user to the first file
exit;
}
[...] //continue your script here.
Things with referrer check do usually fail (some browsers/firewalls blocking that variable).
Based on the options you described, it would sound most reasonable to make the html2 a php script and check that the referrer is the html1 file. The script should display the normal html1 content if that is the case, or an error message otherwise.
A sneaky user could still get around this if they knew what was going on, but it should be fine for the majority of your audience.
Possible with php.
At index.php you must write
<?php
define('START', true);
include 'file.php';
At file.php need write
<?php defined('START) or die('Direct access!!'); ?>
<embed> your swf file embed
This way you will prevent direct access
You could do it with PHP by using session variables. Start the session in html1. Check for the session in html2. If it exists, display html2. If it does not, don't display html2. In either case, destroy the session in html2.
well is posible with html you has two options one is cookies and the other is local storage in html5
localStorage.hasClick = true;
alert(localStorage.hasClick);
http://www.html5rocks.com/en/features/storage
but obviously the straightforward solution is php / c# / ruby / etc...
//when I said html i refer to use only client side html/javascript
I have the following PHP script within a file named login.php
<?php
$ref = $_SERVER['HTTP_REFERER'];
if ($ref == 'http://example.com/dir/invalid.php' || $ref == 'http://www.example.com /dir/invalid.php') {
echo '
<div id="invalid">
TESTTESTTESTTESTTESTTESTTESTTEST
</div>
';
}
?>
I have deliberately went to the invalid.php page (which redirects using header() to login.php) and this div does not show up. Does it have something to do with the referrer not really being invalid.php or is there an issue with the script?
Thanks
I don't think the HTTP_REFERER is what you think it is. Namely, it is the page from which the user followed a link to the current page. However, it's very unreliable as we rely on the browser of the user to correctly report this value.
I would suggest the option I thought you needed, except that the only one I can think of you might doesn't really makes sense... (checking if the url matches a url that's not the current script)... so I do not see what you are trying to do.
As promised several ways to do what you want to achieve:
First off, I don't like this solution at all and really consider it ugly, but it's the one closest to what you where trying to do.
invalid.php
require 'login.php'; // we include the file instead of referring to it
login.php
if ($_SERVER['SCRIPT_NAME'] == 'invalid.php')
{
// do whatever
}
The main difference between what you did and what I did for the user will be that here the url bar will show that you're at invalid.php and not somewhere else. This also means that refreshing doesn't make the message go away.
A better solution in my opinion is the following:
In your script that logs a user in (checks the database and everything):
if (!valid_login()) // pseudo-code, obviously
{
$_SESSION['invalid_login'] = true;
header('Location: login.php');
// previously, we had something like this instead of the two lines above:
// header('Location: invalid.php');
}
in login.php
if (isset($_SESSION['invalid_login']) && $_SESSION['invalid_login'])
{
$_SESSION['invalid_login'] = false;
// do whatever
}
Of course, this should be done with proper session facilities like starting up the session in both those files. Instead of using session variables, you could include the file and use normal variables or send GET variables through the header request, but both those solutions share a problem: refreshing doesn't make the message disappear. However, if you were to move the code from the top file of the two above to login.php (if it's not already there, I don't know what file that actually is...) you could once again use normal variables instead of session variables and have a solution in which refreshing does make it go away. In this case, you might argue that you are cluttering your files with bussiness logic and presentation, but there are solutions to that (like keeping it in a separate file, and including it into login.php, moving the html to another file and including that one into login.php or both.
My problem is simple. I need to upload a file directly to the correct server (which has currently low workload).
Therefore I do:
<?php
$server = file_get_contents('http://my-api.com/upload-server.php'); // returns url
?>
then i print my form like
<form method="post" action="<?php echo $server; ?>"...
Now I would like to shift this step to when the upload starts, like so:
<form method="post" action="http://my-api.com/upload-gateway.php"...
this url should do a redirect to the "real" server.
So that the upload page doesn't slow down loading and I have static html code that I can cache, embed etc...
Problem is that this works perfetly fine with get requests but not with post requests.
The request seems like to get transformed into a get request when redirecting using the location header. All post data is lost.
Is this impossible or am I doing it wrong? And yes, I considered a remote dynamic javascript that prints the html code with the correct server in the first place. I would rather like not to do that...
any ideas? Maby alternative uplod techniques?
edit:
this is the exact html code i use:
<form method='post' enctype='multipart/form-data' action='http://storage.ivana.2x.to/rest.php?action=target'>
<input type=hidden name=testfield value="test">
File to upload: <input type=file name=upfile><br>
Notes about the file: <input type=text name=note><br>
<br>
<input type=submit value=Press> to upload the file!
</form>
this is the redirect code i use:
if($_GET["action"] == "target") {
header("Location: http://storage.ivana.2x.to/rest.php?action=test");
}
this is the output code i use to see the results:
if($_GET["action"] == "test") {
echo "<pre>";
var_dump($_POST);
var_dump($_GET);
var_dump($_FILES);
}
the result when uploading a small file looks like:
array(0) {
}
array(1) {
["action"]=>
string(4) "test"
}
array(0) {
}
If you really want to load balance through the code while potentially caching the page with the upload form, first select the default download server (url); then, onSubmit call the server and find the best upload target and adjust the action attribute accordingly.
With this method, users who do not activate JS still get what they want, users with JS enabled get the better upload target, and you can still cache. Additionally, the timing of the cache request could potentially be more opportunistic, since the URL request will occur very shortly before the actual upload.
The only hitch will be the call to get the URL, which you can more easily performance tune (I imagine) than the process you are describing above. Uploading a file twice through a header directive and/or cURL call don't seem like a good tradeoff for caching a single html file, IMO. But I don't know what you're up against, either.
If you don't want to heavily administer the server environment and introduce load balancing, this is the option I would suggest.
Note, also, I am not a server administrator by trade.
You could try returning a code 302 (temporary moved), not 100% that would let your browser post the data to the changed url though, but it's worth something to check out.
[Edit]
According to this wikipedia article, the POST data would be converted to GET, which probably won't work for a file upload.
This is not a good solution. The file will be uploaded in it's entirety before the PHP script is even started. This means that if you succeed with what you're trying to do the client will have to upload the file twice!
I recommend that you try to figure out which server to send the request to when you're creating the form, so the action attribute in the form tag will point directly to the lesser loaded machine.
Or even better: use a serverside loadbalancer and make your HTTP infrastructure transparent to the browser. This is essentially a sysadmin problem.
i might be wrong but.. your form's action points to ?action=target and in your rest.php you do a header to "?action=test" well of course you wont find your $POST nor your $FILES!... a header() does not send those variables..
if you want to send your post and your file to a differente location you'll need to use the cUrl library.. but it wont be easy :)
Good Luck
I am relatively new to PHP, so my apologies if the answer is trivial. Lol
I wrote a simple Contact Us email form (actually a WordPress page-template file). All the code is in one file.
After the user submits the form and the email is sent, the file generates a Thank You message.
If the user reloads the Thank You page, they are prompted to "Resend the Form Data," which is why I am asking this question.
My question: How do I avoid the prompt to resend the form data and still keep all of my code (including the Thank You data) in one file?
EDIT: I've seen folks use headers( Location: ), but I don't think that will work for if I want to keep all my code in one file.
You could redirect to a different query.
header("Location: ?page=thankyou");
Then, you don't even need to check if the POST data was sent. Just display the thank you page if page is equal to thank you.
This worked for me, it can be put anywhere in html file not just beginning like header() function:
<?php
if (!empty($_POST)){
?>
<script type="text/javascript">
window.location = window.location.href;
</script>
<?php } ?>
I placed it into prevent_resend.php and then included it after the postdata processing was done.
// ... save data from $_POST to DB
include('prevent_resend.php');
// ... do some other stuff
You can use javascript to post the form and show the thank you message. This way the browser never leaves the page.
Even with a header('Location: xxx'); you can still redirect it to the same page, and either set a url parameter or a session variable to distinguish what should be shown.
Although I question your requirement to have all the code in one file (why couldn't you separate it, and use require_once to include shared library code?), the header('Location:') technique is still completely valid. Simply do:
header('Location: http://www.example.com/path/to/my-one-file-of-code.php?thankyou=1');
Then, in your file, you can have:
if (isset($_GET['thankyou']) && $_GET['thankyou']) {
// Do whatever it is you do to thank the visitor.
}
This worked for me:
header("Location: #");