Deleting a file on server by DELETE form method - php

I am trying to delete a file on my server using DELETE method in my html form.
I have a file ,and url to that file is :
http://example.com/file2.php
I am using the following code for deleting the file :
<form action="file2.php"method="DELETE">
<input type="submit"value="delete file">
</form>
When I press "delete file" button I get redirected to "file2.php" but it is not deleting the file.
Server is receving the request header in GET method :
GET /file2.php HTTP/1.1
instead of DELETE :
DELETE /file2.php HTTP/1.1
Does someone know why the delete method is not working? or how can I delete my file using DELETE method?

Most browser do not support DELETE as method parameter for <form ...>. Indeed it's not even part of the HTML specification:
The method and formmethod content attributes are enumerated attributes with the following keywords and states:
The keyword get, mapping to the state GET, indicating the HTTP GET method.
The keyword post, mapping to the state POST, indicating the HTTP POST method.
And here is some kind of explanation:
It seems that we currently do not understand how PUT and DELETE will be useful for HTML forms.
For DELETE, it's indeed easy to create a useful request. However, server implementations usually respond with 200 and a minimal response body ("deleted") or 204 (no content). So it's not clear how this can be used in a web application.
For PUT, it seems there's no real use case as long as the web page doesn't have full control over the payload, and also can set the content type.
Please consider removing this feature until there's a clearer understanding about what it's good for.
Frameworks like laravel provide method spoofing:
<input type='_method' value='DELETE' />
This will override the method of the request and will - for example - call a destroy function:
Route::delete('/items/{id}', 'ItemController#destroy');
If you don't use a framework, you can try to mimic this behaviour:
if($_SERVER['REQUEST_METHOD'] === 'DELETE' || (isset($_REQUEST['_method'] && $_REQUEST['_method'] === 'delete') {
...
}

Mozilla only specifies only GET and POST
I have 2 recommendations:
Use a POST to send data to your PHP code and handle it from there
Don't actually delete stuff that simple. Create some function that will just say it is deleted till after you are really sure it has to be gone

Related

How to make a request to delete a row in DB?

I have read everything on this topic - and still in a fog.
I made a CRUD functional, and the question is - how to test/ how to use delete or update functions?
In my routes.php there is a one string:
Route::resource('templates', 'Vendor\App\Controllers\TemplateController');
In controller destroy and update functions are implemented.
So i'm trying to test delete. When a send DELETE request - i've got a error
RouteCollection->methodNotAllowed(array('GET', 'HEAD', 'POST'))
As far as i googled, method must be POST, but one of the form fields - named _method must have the value DELETE So i use the postman for testing, and got the same error:
What am i doing wrong? how to make a delete request?
You are doing the right request, but to the wrong URL. As noted in the corresponding docs, the URL for the DELETE request should be /templates/{id}. Try it eg. with templates/1

$_POST request in PHP how can i apply?

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-

HTTP protocol's PUT and DELETE and their usage in PHP

Introduction
I've read the following:
Hypertext Transfer Protocol (HTTP) is the life of the web. It's used every time you transfer a document, or make an AJAX request. But HTTP is surprisingly a relative unknown among some web developers.
The HTTP verbs comprise a major portion of our “uniform interface” constraint and provide us the action counterpart to the noun-based resource. The primary or most-commonly-used HTTP verbs (or methods, as they are properly called) are POST, GET, PUT, and DELETE.
Huh?
Well, we came to the point I lost track of things.
PUT and DELETE, they say. I've only ever heard of POST and GET and never saw something like $_PUT or $_DELETE passing by in any PHP code I've ever viewed.
My question
What are these methods (PUT) and (DELETE) for and if it's possible to use them in PHP, how would I go about this.
Note: I know this is not really a problem but I always grab a learning opportunity if I see one and would very much like to learn to use these methods in PHP if this is possible.
What are these methods (PUT) and (DELETE) for...
There are a lot of words to spend to explain this, and I'm not skilled enough to do it, but as already posted, a quick recap of what the HTTP specification describes.
The protocol basically says this:
use GET when you need to access a resource and retrieve data, and you don't have to modify or alter the state of this data.
use POST when you need to send some data to the server. Ex. from a form to save these data somewhere.
use HEAD when you need to access a resource and retrieve just the Headers from the response, without any resource data.
use PUT when you need to replace the state of some data already existing on that system.
use DELETE when you need to delete a resource (relative to the URI you've sent) on that system.
use OPTIONS when you need to get the communication options from a resource, so for checking allowed methods for that resource. Ex. we use it for CORS request and permissions rules.
You can read about the remaining two methods on that document, sorry I've never used it.
Basically a protocol is a set of rules you should use from your application to adhere to it.
... and if it's possible to
use them in PHP, how would I go about this.
From your php application you can retrieve which method was used by looking into the super global array $_SERVER and check the value of the field REQUEST_METHOD.
So from your php application you're now able to recognize if this is a DELETE or a PUT request, ex. $_SERVER['REQUEST_METHOD'] === 'DELETE' or $_SERVER['REQUEST_METHOD'] === 'PUT'.
* Please be also aware that some applications dealing with browsers that don't support PUT or DELETE methods use the following trick, a hidden field from the html form with the verb specified in its value attribute, ex.:
<input name="_method" type="hidden" value="delete" />
Follow an example with a small description on a possible way to handle those 2 http requests
When you (your browser, your client) request a resource to an HTTP server you must use one of the method that the protocol (HTTP) accepts. So your request needs to pass:
A METHOD
An Uri of the resource
Request Headers, like User-Agent, Host, Content-Length, etc
(Optional body of the request)
Now, while you would be able to get data from POST and GET requests with the respective globals ($_GET, $_POST), in case of PUT and DELETE requests PHP doesn't provide these fast access globals; But you can use the value of $_SERVER['REQUEST_METHOD'] to check the method in the request and handle your logic consequently.
So a PUT request would look like:
PUT /something/index.php
(body) maybe=aparameter
and you can access those data in PHP by reading the php://input stream, ex. with something like:
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
$myEntireBody = file_get_contents('php://input'); //Be aware that the stream can only be read once
}
and a DELETE request would look like:
DELETE /something/index.php?maybe=aparameter
and again you can build your logic after have checked the method:
if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
// do something
}
Please pay attention that a DELETE request has no Body and pay very attention to Response Status Code too (ex. if you received a PUT request and you've updated that resource without error you should return a 204 status -No content-).
Way to use PUT data from PHP:
$method = $_SERVER['REQUEST_METHOD'];
if ('PUT' === $method) {
parse_str(file_get_contents('php://input'), $_PUT);
var_dump($_PUT); //$_PUT contains put fields
}
PHP's $_GET and $_POST are poorly named. $_GET is used to access the values of query string parameters, and $_POST lets you access the request body.
Using query string parameters is not limited to GET requests, and other kinds of requests than just POST can come with a request body.
If you want to find out the verb used to request the page, use $_SERVER['REQUEST_METHOD'].
Most suitable place to use these (PUT and DELETE) methods is REST API. Where we use http methods to define the mode of operation for example you want to fetch any resources then you can use following:
GET http://api.example.com/employee/<any_id>
to add a new item:
POST http://api.example.com/employee/
to Update or Edit:
PUT http://api.example.com/employee/
to Delete an existing resource:
DELETE http://api.example.com/employee/1
etc.
Now on PHP side you just need to read what HTTP method used so that you can make an action according to that.
There are lots of libraries available which can do that for you.
What are these methods (PUT) and (DELETE)
There are described in the HTTP spec.
In a nutshell, and simplifying somewhat, PUT is for uploading a file to a URL and DELETE is for deleting a file from a URL.
never sawy something like $_PUT or $_DELETE passing by in any PHP code I've ever viewed
$_POST and $_GET are terribly named superglobals. $_POST is for data parsed from the request body. $_GET is for data parsed from the URL. There's nothing that strictly ties data in either of those places (especially the URL) to a particular request method.
DELETE requests only care about the URL's path, so there is no data to parse.
PUT requests usually care about the entire request body (not a parsed version of it) which you would access with file_get_contents('php://input');.
for and if it's possible to use them in PHP, how would I go about this.
You'd need to map the URL onto a PHP script (e.g. with URL rewriting), test the request method, work out what URL you were actually dealing with, and then write code to do the appropriate action.
$GLOBALS["_PUT"]=null;
if($_SERVER['REQUEST_METHOD'] == 'PUT') {
$form_data= json_encode(file_get_contents("php://input"));
$key_size=52;
$key=substr($form_data, 1, $key_size);
$acc_params=explode($key,$form_data);
array_shift($acc_params);
array_pop($acc_params);
foreach ($acc_params as $item){
$start_key=' name=\"';
$end_key='\"\r\n\r\n';
$start_key_pos=strpos($item,$start_key)+strlen($start_key);
$end_key_pos=strpos($item,$end_key);
$key=substr($item, $start_key_pos, ($end_key_pos-$start_key_pos));
$end_value='\r\n';
$value=substr($item, $end_key_pos+strlen($end_key), -strlen($end_value));
$_PUT[$key]=$value;
}
$GLOBALS["_PUT"]=$_PUT;
}
if (!function_exists("getParameter")){
function getParameter($parameter)
{
$value=null;
if(($_SERVER['REQUEST_METHOD'] == 'POST')&& (isset($_POST[$parameter]))){
$value=$_POST[$parameter];
}
else if(($_SERVER['REQUEST_METHOD'] == 'PUT')&& (isset($GLOBALS["_PUT"][$parameter])))
{
$value=$GLOBALS["_PUT"][$parameter];
}
else if(($_SERVER['REQUEST_METHOD'] == 'DELETE')&& (isset($_DELETE[$parameter]))){
$value=$_DELETE[$parameter];
}
else if(($_SERVER['REQUEST_METHOD'] == 'PATCH')&& (isset($_PATCH[$parameter]))){
$value=$_PATCH[$parameter];
}
else if(isset($_GET[$parameter])){
$value=$_GET[$parameter];
}
return $value;
}
}

PHP get PUT request body

I'm currently developing a Restful Json-API in PHP. I want to send a PUT-Request to items/:id to update a record. The data will be transferred as application/json.
I want to call the API with
curl -H "Content-Type: application/json" -X PUT -d '{"example" : "data"}' "http://localhost/items/someid"
On the server side, I'm not able the retrieve the request body. I tried
file_get_contents("php://input");
but this returns an empty string. Also a fopen()/fread() combination doesn't work.
When calling via POST, everything works great, I can read the json perfectly on the server side. But the API isn't Restful anymore. Does anyone have a solution for this? Is there another way to send and receive Json?
btw, I'm developing the API with the Slim Framework.
php://input is only readable once for PUT requests:
Note: A stream opened with php://input can only be read once; the stream does not support seek operations. However, depending on the SAPI implementation, it may be possible to open another php://input stream and restart reading. This is only possible if the request body data has been saved. Typically, this is the case for POST requests, but not other request methods, such as PUT or PROPFIND.
http://php.net/manual/en/wrappers.php.php
The Slim framework already reads the data upon request. Take the data from the Request object, into which it has been read.
On the server side, I'm not able the retrieve the request body. I tried file_get_contents("php://input");
You can only use file_get_contents( 'php://input', 'r' ); once per request. Retrieving its values will truncate the values as well, so if you call it twice, it'll return an empty string. Slim's request object contains the values you need, so:
<?php
$app = new Slim( );
$app->put( '/items/someid', function () use ( $app ) {
echo $app->request( )->put( 'example' ); // should display "data".
});
The example from the PHP manual uses fopen to access php://input in read mode. Have you tried doing it that way instead?
EDIT: The manual page for PHP:// says some stuff that seems to suggest that PUT data might not be available in some cases!
Note: A stream opened with php://input can only be read once; the
stream does not support seek operations. However, depending on the
SAPI implementation, it may be possible to open another php://input
stream and restart reading. This is only possible if the request body
data has been saved. Typically, this is the case for POST requests,
but not other request methods, such as PUT or PROPFIND.
I don't know where this will leave you regarding PUT processing. One page seems to say it's possible, the other seems to imply that it won't work under the wrong set of circumstances
I was reading the SLIM framework documentation the other day and it said that some browsers have problems with PUT and DELETE.
Excerpt:
Unfortunately, modern browsers do not provide native support for PUT requests. To work around this limitation, ensure your HTML form’s method is “post”, then add a method override parameter to your HTML form like this:
<form action="/books/1" method="post">
... other form fields here...
<input type="hidden" name="_METHOD" value="PUT"/>
<input type="submit" value="Update Book"/>
</form>
Source: http://www.slimframework.com/documentation/stable

AJAX & PHP:GET parameters causing Flickr api key error

I'm trying to send a URL with aFLickr API key to fetch results for a given photo tag. The Ajax code should return the XML to my browser. However the URL structure with parameters seems to cause a problem in my setup:
**the HTML file:**
...
url="api.flickr.com/services/rest/?method=flickr.photos.search&api_key=75564008a468bf8a284dc94bbd176dd8&tags=paris"
request.open("GET","xmlget.php?url=" + url + nocache, true)
...
**the 'xmlget.php' file:**
...
echo file_get_contents($_GET['url']);
...
error: code="100" msg="Invalid API Key (Key has invalid format)">
the link works fine if tested in the adress bar so there must be a breakdown somewhere when the URL is processed.
i tried wrapping it into encodeURI but no luck :(
Note: related post
You need to use encodeURIComponent instead of encodeURI to actually get that string encoded.
May I make 2 suggestions?
just pass the search parameters to xmlget.php and do the rest there even if it means having to pass a service type if you are using that generically
I don't remember what all a Flickr api key gets you, but it's generally a bad thing to post anything called an "api key" in public. In addition to the question, that includes sticking it in javascript that an end user can access.

Categories