I have a form with a small number (up to 10) of inputs. One of those inputs is a file upload input. The form layout is as follows:
<form method="post" ...>
<input type="hidden" name="input_no_1" value="value_no_1">
<input type="file" name="input_no_2">
<input type="hidden" name="input_no_3" value="value_no_3">
<button type="submit">send</button>
99.9% of the time this form works fine and I get all the data on the PHP side. However, every once in a while, the POST data gets truncated, and the $_POST variable contains only this:
input_no_1 => value_no_1
The file input and every other input that follows the file input are missing.
This error happens almost exclusively with user agents that contain "Mobile Safari". I suspect that mobile phone users could be using a less reliable network connection and as a result, their request gets aborted and PHP doesn't receive the entire uploaded data.
In my application, I need to know whether the data in the $_POST array is complete or not. I was expecting that if the HTTP server doesn't receive the entire request, I wouldn't even see it from the PHP side.
I am using apache/fpm. The upload_max_filesize and post_max_size are both set to 2G and are nowhere near the size of the uploaded files.
The question: what is the best way to handle incomplete POST data in PHP? Is there a way to prevent these requests from reaching my application, and if not, is there a way to know whether the posted data is complete? I prefer not to add any fields at the end of the form just to find out whether the request is complete or not :)
It sounds like this is a case of needing some server side form validation. Assuming the above fields are all required, something like the following might work for you:
if (!isset($_POST['input_no_1'], $_POST['input_no_2'], $_FILES['input_no_2'])) {
die('Form not filled completely');
} else {
//process form
}
Related
I want to know how to use POST request in PHP. I used $_REQUEST['text'] for getting data from url like http://localhost/data.php?text=ABCDEFGH but If i pass very long text than ERROR : Request-URI Too Long.
if(isset($_REQUEST['text'])){
$parsetext=$_REQUEST['text']; //get data here data > ABCDEFGH
}else{
echo "not valid";
}
Please any one tell me how to support long TEXT using POST request. I know that $_REQUEST is for both request GET & POST.
Regarding the error, you can check these links (I assume you've already seen this):
How do I resolve a HTTP 414 “Request URI too long” error?
Request-URI Too Large
And for your question: I want to know how to use POST request in PHP.
Create a form.
(I assume that the textbox from this form will get the long data that you want to POST).
<form method="POST" action="http://localhost/data.php">
<input type="text" name="input_text" />
<button type="submit">Submit</button>
</form>
Receive the data from the from input using the defined method on your form. In this case the method is POST and the url/file that will receive the submitted data is http://localhost/data.php.
if (isset($_POST['input_text'])) {
// Where input_text is the name of your textbox.
$text = $_POST['input_text'];
echo $text;
}
ERROR : Request-URI Too Long.
$_REQUEST, as you say, handles $_POST and $_GET methods is correct.
Regarding your question, even though you use $_REQUEST to get the data, in the background it use the $_GET method to catch the query string you pass with the url.
$_GET method has limit on size and this is the main reason why you encounter that error. Whereas $_POST method don't have limit: Is there a maximum size for content of an HTTP POST?.
Conclusion: Better not use $_REQUEST, use $_GET or $_POST specifically :D
First of all, read this Question/Answer, this will probably clear some things for you on the differences between POST and GET and what method you should use for your project.
Then, you should forget about the $_REQUEST and use either $_GET or $_POST. This will prevent some security issues that you'll probably run into if you keep using $_REQUEST. More on that in the PHP Manual
Next up, you should definitely switch to POST, instead of GET if you're passing large sets of data. Otherwise you have to modify your apache config and that is not recommended if you plan on releasing you code to the public.
-EDIT START-
You can even use POST within AJAX, if everything is on the same server.
-EDIT END-
I'm making a small CMS for practice. I am using CKEDITOR and is trying to make it avaliable to write something like %contactform% in the text, and then my PHP function will replace it with a contactform.
I've accomplished to replace the text with a form. But now I need the PHP code for the form to send a mail. I'm using file_get_contents(); but it's stripping the php-code.
I've used include(); to get the php-code from another file then and that works for now. I would like to do it with one file tho.
So - can I get all content from a file INCLUDING the php-code?
*UPDATE *
I'll try to explain in another way.
I can create a page in my CMS where I can write a header and some content. In the content I am able to write %contactform%.
When I get the content from the database I am replacing %contactform% with the content from /inserts/contactform.php, using file_get_contents(); where I have the form in HTML and my php code:
if(isset($_POST['submit'])) {
echo 'Now my form is submitted!';
}
<form method="post">
<input type="text" name="email">
<input type="submit" name="submit">
</form>
Now I was expecting to retrieve the form AND the php code active. But If I press my submit button in the form it's not firing the php code.
I do not wan't to show the php code I want to be able to use it.
I still have to guess, but from your update, I think you ultimatly end up with a variable, which contains the content from the database with %contactform% replaced by file_get_contents('/inserts/contactform.php').
Something like:
$contentToOutput = str_replace(
'%contactform%',
file_get_contents('/inserts/contactform.php'),
$contentFromDatabase
);
If you echo out that variable, it will just send it's content as is. No php will get executed.
Though it's risky in many cases, if you know what you're doing you can use eval to parse the php code. With mixed code like this, you maybe want to do it like the following.
ob_start();
eval('; ?>' . $contentToOutput);
$parsedContent = ob_get_clean();
$parsedContent should now contain the results after executing the code. You can now send it to the user or handle it whatever way you want to.
Of course you'll have to make sure that whatever is in $contentToOutput is valid php code (or a valid mixture of php with php-tags and text).
Here is a link to the symfony Templating/PhpEngine class. Have a look at the evaluate method to see the above example in real code.
yes...
$content = file_get_contents( 'path to your file' );
for printing try
echo htmlspecialchars( $content );
From reading the revised question, I think the answer is "You can't get there from here." Let me try to explain what I think you will encounter.
First, consider the nature of HTTP and the client/server model. Clients make requests and servers make responses. Each request is atomic, complete and stateless, and each response is complete and usually instantaneous. And that is the end of it. The server disconnects and goes back to "sleep" until the client makes a new request.
Let's say I make a request for a web page. A PHP script runs and it prepares a response document (HTML, probably) and the server sends the document to my browser. If the document contains an HTML form, I can submit the form to the URL of the action= script. But when I submit the form, I am making a new request that goes back to the server.
As I understand your design, the plan is to put both the HTML form and the PHP action script into the textarea of the CKeditor at the location of the %contactform% string. This would be presented to the client who would submit the form back to your server, where it would run the PHP script. I just don't think that will work, and if you find a way to make it work, you're basically saying, "I will accept external input and run it in PHP." That would represent an unacceptable security exposure for me.
If you can step back from the technical details and just tell us in plain language what you're trying to achieve, we may be able to offer a suggestion about the design pattern.
I'm trying to emulate a POST call/fileupload so I can do it programmatically, rather than using a clunky outdated app.
The form field in my attempted emulation looks like this
<Input Type=text name="data" value="begin+600+%7B_TRACK_NAME_%7D%0D%0AM240S...">
According to my HTTP traffic analyzer, the original version posts like this
data=begin+600+%7b%5fTRACK%5fNAME%5f%7d%0d%0aM240S...
(it goes on and on, and it's a chunked upload, so there are dozens of these posts)
When I attempt my POST call (from a PHP form), it sends this
data=begin%2B600%2B%257B_TRACK_NAME_%257D%250D%250AM240S...
(on and on and on)
so, naturally the server side is stunned at my stupidity and says terrible things about me, and my loved ones, rather than accepting the file.
Any ideas?
Well, the reason I haven't posted my code is because it's all literally just one PHP form post. Meaning... I get the same error if I just take the data that I'm posting, and manually send it, rather than generating that data programmatically.
But, if it helps, the code I would use would look something like this.
// Opening the file and loading into the variable $contents
$filename = "sample.mp3";
$handle = fopen($filename,"r");
$contents = fread($handle, filesize($filename));
fclose($handle);
// uu_encoding the string
$uu_string = convert_uuencode($contents);
// the first line BEFORE uu_encoding looks like
// ID39TTrandomCOMengiTunPGAP0TENiTunes 10.5.1COMhe
// (it's an MP3)
// the first line AFTER uu_encoding looks like
// M240S`#`````0.514,#``"`!R86YD;VT`0T]-```0`&5N9VE4=6Y01T%0
// url_encoding the uu_encoded string
$url_string = rawurlencode($uu_string);
// the first line after url_encoding looks like
// M240S%60%40%60%60%60%60%600.514%2C...
<form action="target.aspx">
<Input Type=text name="data" value="<? echo $url_string; ?>">
<Input Type=Submit>
</form>
When submitted, the POST call looks like this
If I submit this the server will respond "Error: Input String was not in a correct format.", which I believe is because the server is expecting data to be a certain format and length. So my aim is to figure out why my data doesnt look like the traditional "final" data, and the first step is figuring out why my data looks like that.
If I understand your problem correctly, you should use htmlspecialchars instead of rawurlencode. Urlencode is used for HTTP, not HTML, plus your data seems to be encoded already, so you just encode it twice.
Alternatively, you could use cURL to send the post from the server and avoid the HTML form mess altogether.
My situation: I need to send text to an ASP.NET web service using POST. The entire page there is a form:
<form name="aspnetForm" method="post" action="Discussion.aspx?classroom=lG39il1cotOAGJwiNvmQlIPfwmjikD%2fAHLhjjGInAZQ%3d&Page=Posts&ID=794239&Sort=&SortOrder=" id="aspnetForm">
So, I figured if I sent a POST request to this form with the correct inputs it would work. And, to an extent, it has. The form inputs are as follows:
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDw..." />
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWYQLrt..." />
And a bunch of other inputs. The code I have used is as follows:
// grab form info
$inputs = extract_form_inputs($discussion['body']);
$inputs['__EVENTTARGET'] = 'ctl00$cphMain$ctl01$btnSubmit';
$inputs['ctl00$cphMain$ctl01$tbNickname'] = "Your Instructor";
$inputs['ctl00$cphMain$ctl01$reMessage'] = $message;
// submit form
$r = request_send($discussion['url'], $inputs);
extract_form_inputs does exactly that. $discussion['body'] is the content of the page. $discussion['url'] is the URL of the page. request_send has two arguments: ($url, $post_array). It performs rawurlencode on each element of the array and joins them up as keypairs, in the same way as http_build_query.
The request is url encoded properly, sent to the correct page, and works fine until I insert html tags. I have checked - the 'greater than' and 'less than' symbols ('<' and '>') are url-encoded properly. However, the server responds with a 500 error.
It accepts any other text.
Has anyone else come across this sort of problem?
Is there some setting on an ASP.NET server that denies html? I can't see this being the case - there is a rich text editor on the website that I am sending requests to. This text editor performs the same request as I am, only I am doing it remotely. The rich text editor sends html to the form - I have checked that, too, using javascript.
Note: I do not have the power to modify the ASP.NET server.
Maybe the validateRequest flag/attribute is set and therefore your data is considered harmful and rejected.
You could use something like firebug or fiddler2 to log the actual request your browser sends and then compare it to your script's request. Can you log all the data request_send() sends, including all headers? Depending on how request_send() works you might be able to route it through fiddler, too, which perhaps makes it easier to compare the requests, e.g. when I run
$ctx = stream_context_create(array('http'=>array('proxy'=>'tcp://localhost:8888')));
file_get_contents('http://php.net', 0, $ctx);
the requests shows up in fiddler (8888 being fiddler's default proxy port).
edit: Do you only receive a 500 Internal Server Error or does the response contain more information? In case php doesn't fetch or doesn't return the response body you might want to look that up in fiddler, too.
I have compared the results and found that the website stupidly url-encodes the messages twice before submitting. Not even full url-encoding - it misses most unwanted characters. Still, the formatting now works - I just url-encode the message twice before sending and it comes out fine on the other end.
Thanks for the help!
I'm new to PHP and I'm trying to do something that may be bad practise and may well be impossible. I'm basically just hacking something together to test my knowledge and see what PHP can do.
I have one webpage with a form that collects data. That is submited to a PHP script that does a bunch of processing - but doesn't actually display anything important. What I want is that once the processing is done, the script then tells the browser to open another page, where the results are displayed.
I know I can use header('Location: page.php'); but I can't work out how to provide POST data with this. How can I do that? Alternatively, is there another way to tell the browser to open another page?
EDIT: What I'm taking from the responses is that it's possible to do this using various hacks but I'd be better off to just have the processing and the display code in one file. I'm happy with that; this was an experiment more than anything.
You could store that data in the session e.g. in the first file that handles the post
session_start();
$_SESSION['formdata'] = $_POST; //or whatever
then you can read it on the next page like
session_start();
print_r($_SESSION['formdata']);
or you could pass it through GET: (but as per comments this is a bad idea)
header('Location: page.php?' . http_build_query($_POST));
If you do that make sure you do additional processing/validation on page.php as a malicious user could change the variables. also you may not need the whole post transmitted to the next page
Edit
I should make clear that I think the second option is possibly worse, as you are limited by the size of data you can send through get and it is possibly less secure as users can more obviously manipulate the data.
Is it really necessary to call another page after the processing is done? I'd probably do the following:
<form method="post" action="display.php">
...
</form>
display.php:
if ($_POST) {
require_once(process.php);
process($_POST);
display_results;
}
with process.php containing the code necessary for processing the post request.
Alternatively, you could use something like the cURL library to pass the results of the processing to a page specified by yourself. Don't know if that's really what you're after though.
You could use JavaScript as a dirty work-around:
<form id="redirect_form" method="post" action="http://someserver.com/somepage.php">
<input type="hidden" name="field_1" value="<?php echo htmlentities($value_1); ?>">
<input type="hidden" name="field_2" value="<?php echo htmlentities($value_2); ?>">
<input type="hidden" name="field_3" value="<?php echo htmlentities($value_3); ?>">
</form>
<script type="text/javascript">
document.getElementById('redirect_form').submit();
</script>
(the script should be below the form)
There's no way to redirect the user's browser to an arbitary page and sent a POST request. That would be a bit security risk, where any link could cause you to make any form submission to an arbitrary site without you having any kind of clue about what was going to happen.
In short, it's not possible
AFAIK this is usually done as a two-step process:
On form.php, POST the data to script process.php
The process.php script processes the data but never outputs anything itself, it always calls header("Location: asdasd") to redirect to a success.php or failure.php page (if applicable)
Do it all in one script and just output different HTML for the results.
<?php if($doingForm) { ?>
html for form here
<?php } else { ?>
html for results
<? } ?>
This problem has vexed me for some time. My custom CMS does some quite complex processing, uploading and manipulation, and so sometimes ouputs quite lengthy error and information messages, which aren't suitable for converting to GET data, and I have always wanted to avoid the reload problem on data INSERT, but not yet found an adequate solution.
I believe the correct way to go about this, is to create message arrays for each possible state - each message or error you could want to display, and then you only need to send error/message numbers which are a lot easier to handle than long data strings, but it's something I have always shied away from personally as I find it a bit tedious and cumbersome. Frankly, this is probably just laziness on my part.
I quite like the SESSION variable storage solution, but this raises the question of how do you ensure the SESSION data is properly destroyed?
As long as you ensure you are only sending information (messages/errors) and not data that should/could be stored (and thus potentially sensitive) this should be an avoidable problem.
I hope i got your qestion right.
You might try this:
Adjust your form to look like this:
form method="POST" action="process_data.php"
2.
Then you create the file process_data.php, wich surprisingly processes the data.
And in this file you use header:
For example:
$head = sprintf("page.php?data1=%d?data2=%d",$data1,$data2);
header($head);
I hope i could help.