Hello i'm using cakephp and i need to update the status throug an action method
the method in the controller is this
function setEstado($id, $id_usuario, $estado,$vars) {
i'm using serialize to get all the fields of the form (when i update the status i need to update all the changes done, so... This is my request
OrdenesReparaciones/setEstado/36725/46/6/_method=PUT&data%5BOrdenesReparacion%5D%5Bguardando%5D=&data%5BOrdenesReparacion%5D%5Bid%5D=36725&data%5BOrdenesReparacion%5D%5Bidusuarioa%5D=46&data%5BOrdenesReparacion%5D%5Bcliente_id%5D=14915&data%5BOrdenesReparacion%5D%5Bnumero%5D=220498&data%5BOrdenesReparacion%5D%5Btipo%5D=Presupuesto&data%5BOrdenesReparacion%5D%5Bnro_orden_anterior%5D=&data%5BOrdenesReparacion%5D%5Bfecha%5D=19-08-2015&data%5BOrdenesReparacion%5D%5Bfecha_prometido%5D=20-08-2015&data%5BOrdenesReparacion%5D%5Bfecha_asignado%5D=31-08-2015&data%5BOrdenesReparacion%5D%5Bcliente%5D=EDUARDO+DO+CAMPO&data%5BCliente%5D%5Bdireccion%5D=&telefono=&celular=099668032&email=&data%5BOrdenesReparacion%5D%5Barticulo%5D=MARTILLO&data%5BOrdenesReparacion%5D%5Bmodelo%5D=MD+908&data%5BOrdenesReparacion%5D%5Bmarca_id%5D=120&data%5BOrdenesReparacion%5D%5Bmarcass%5D=120&data%5BOrdenesReparacion%5D%5Bimportador%5D=R.+BALAGUER+S.A.&data%5BOrdenesReparacion%5D%5Bimportadors%5D=R.+BALAGUER+S.A.&data%5BOrdenesReparacion%5D%5Bdetalle_marca%5D=NEO&data%5BOrdenesReparacion%5D%5Bfecha_compra%5D=00-00-0000&data%5BOrdenesReparacion%5D%5Blugar_compra%5D=&data%5BOrdenesReparacion%5D%5Bnro_comprobante%5D=&data%5BOrdenesReparacion%5D%5BPrecio_compra%5D=&data%5BOrdenesReparacion%5D%5Bdesperfecto%5D=&data%5BOrdenesReparacion%5D%5Baccesorios%5D=&data%5BOrdenesReparacion%5D%5Bserie%5D=&data%5BOrdenesReparacion%5D%5Barea_id%5D=4&data%5BOrdenesReparacion%5D%5Bsub_taller%5D=0&data%5BOrdenesReparacion%5D%5Bsubtaller_id%5D=&bitacora_add=&data%5BOrdenesReparacion%5D%5Bpresupuesto_taller%5D=R-C%2C+R-M%2C+INTERRUPTOR%2C+ASEGURAR+TROMPA%2C+2+RULEMANES%2C+CARBONES%2C+AROS+DE+COMPRESION%2C+LIMPIEZA%2C+LUBRICACION%2C+AJUSTE%2C+REPARAR+CONEXIONES&respuestos=&data%5BOrdenesReparacion%5D%5Bmonto%5D=0.00&data%5BOrdenesReparacion%5D%5Brecibo_sena_id%5D=0&data%5BOrdenesReparacion%5D%5Bprecio_asignado%5D=4700.00&data%5BOrdenesReparacion%5D%5Brecibido_por%5D=22&data%5BOrdenesReparacion%5D%5Bvino_por%5D=22&data%5BOrdenesReparacion%5D%5Btipo_envio%5D=25&data%5BOrdenesReparacion%5D%5Bnro_remito%5D=&data%5BOrdenesReparacion%5D%5Bcant_llamados%5D=0&data%5BOrdenesReparacion%5D%5Bobservaciones%5D=5%25+26-08-2015+09%3A07%3A28+MAT+-+Bitacora+taller%3A+R-C%2C+R-M%2C+INTERRUPTOR%2C+ASEGURAR+TROMPA%2C+2+RULEMANES%2C+CARBONES%2C+AROS+DE+COMPRESION%2C+LIMPIEZA%2C+LUBRICACION%2C+AJUSTE%2C+REPARAR+CONEXIONES++++++26-08-2015+09%3A05%3A46+MAT+-+Cambio+precio%3A+4700.00++26-08-2015+09%3A01%3A52+MAT+-+Cambio+precio%3A+3200.00++19-08-2015+11%3A41%3A09+JORGE+-+Asignada+a+sector%3AINDUSTRIAL++19-08-2015+11%3A41%3A08+JORGE+-+Accesorios%3A+++19-08-2015+11%3A41%3A02+JORGE+-+Maquina%3A+MARTILLO++19-08-2015+11%3A40%3A39+JORGE+-+Se+cambió+tipo+de+orden+a+PRESUPUESTO+++++++++++++++++++++19-08-2015+11%3A40%3A13+SANTIAGO+-+Orden+creada++26-08-2015+09%3A07%3A28+MAT+-+CONFIRMADA&data%5BOrdenesReparacion%5D%5Bdestino%5D=&data%5BOrdenesReparacion%5D%5Balerta%5D=
it have the following pattern Controller=OrdenesReparaciones action=setEstado id=36725 id_usuario=46 estado=6 vars=_method...
i have the following error
Bad Request
Your browser sent a request that this server could not understand.
I just don't know which is the special char that is damaging my request, i already replace %2F which is '/' with '-' in the dates values, but i can't see here which character should i replace, please, any ideas or advices will mean a lot for me.
Related
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;
}
}
I'm creating a global high score table. The JavaScript sends the username and score to the PHP through some AJAX functions and POST. The PHP script then takes the variable, and compares the score values to the file on the server. It then puts the new score where it should go on the score table, and rewrites the file.
I had it working last night, but now, when I call the function, it displays my code instead, and firebug gives the error, "No element found". I'm not sure what I did between then and now, but I just can't figure this one out.
This is my first time using PHP and AJAX, so I'm not sure where or what the error is.
Any help would be appreciated!
The exact error:
Timestamp: 4/13/2013 1:59:18 PM
Error: no element found
Source File: file:///C:/wamp/www/ajax.php
Line: 84, Column: 3
Source Code:
?>
If I cannot help you solve this issue, I will delete this answer, but I wanted to post it like this so you can better read my suggestions.
Start by changing your HandleResponse function to this:
function HandleResponse(response)
{
console.log(response);
document.getElementById('ResponseDiv').innerHTML = response;
}
and post the result that appears above the error, in firebug.
What we are doing here is adding a way for us to see if any data was actually returned from the AJAX request. A call to console.log tells the browser to print the given argument to the console (in your case, firebug).
UPDATE 1
In your comments, you stated that nothing displayed when you logged the value of response. This means that you received nothing back from the server (in terms of data, at least).
My next suggestion is that you change the call to MakeRequest to the following:
<input type='button' id="test" onclick='MakeRequest("*");' value='Global Highscore Table'/>
Like before, leave the console.log line in the HandleResponse method, and post the result that appears above the error in firebug.
Here, we are setting your MakeRequest to make a request that passes a wild-card query parameter. At the time of this suggestion, I did not realize that the requested file expected two arguments, nor that passing a wild-card would error the script. However, this was still a good thing to do, as we found a new error, which tells us that the request is being received.
UPDATE 2
Now, cut and paste everything from your "ajax.php" file to your notepad or another, similar application. Then, set the following to be the only content of the "ajax.php" file:
<?php echo "Request received and response sent"; ?>
Again, post the result of the console.log.
Here, we are taking a step back from fixing the complex code, and we are going back to the basics. All we want to do, here, is verify that we can both send the request and receive a response.
If "Request received and response sent" is successfully returned as the response of the request, then we know that the error lies in ajax.php, and not in the request. If it is not, we know that there is a problem with the request (be it a server issue or the request, itself). If the latter is the case, there could still be a problem with ajax.php, but we must first fix the request.
UPDATE 3 (final solution)
Issue was found to be due to not correctly running on the local server.
I'm writing my first web service, and I have a problem related to JSON data passing. I have my web service divided in two files: controller.php, which contains the service handler, and service.php, which contains the classes and methods to be served on request.
This is the acquisition fragment from controller.php:
public function atender() {
// pre-procesamos la petición
if (!empty($_POST)) {
if (!empty($_POST["class"]) && !empty($_POST["action"]) && !empty($_POST["function"])) {
$clase = ucwords($_POST["class"]);
$metodo = "{$_POST["action"]}{$this->obtenerMetodo($_POST["function"])}";
$id = (!empty($_POST["datos"]) ? stripslashes($_POST["datos"]) : null);
I can attend requests on both GET and POST mode (I use GET for methods not requiring authentication, like getCategories, getCategoryById, getProducts and getProductById. These are methods to get the dish categories and dishes in a sushi restaurant.)
For any of the GET requests, everything works like expected. My problem comes when I handle POST requests. I need to get all URL parameters in JSON, as this is to serve an iOS app, and JSON is the way we handle data to/from.
This is the processing fragment from service.php:
public function putUser($datos) {
if (!empty($datos)) {
$usuario = json_decode($datos);
$this->log .= implode("/", $usuario) . "\r\n";
In this case, $datos is the JSON-encoded data from the request. It's received as $id in controller.php (the code above). As it's my first web service, it's very probable I'm doing something really bad here, but I'm a bit blinded.
I've tried different variations of the service handling code. Using json_decode($datos, true) doesn't work either. I get
'Unexpected token <' as a response and, in raw form (using the advanced REST client from Google Chrome) it says: ''Warning: implode() [<a href='function.implode'>function.implode</a>]: Invalid arguments passed in /home/refine/public_html/sushigo/palma/service.php on line 344'.
I know SOAP is, usually, a better alternative to writing custom code like this but, for now, I need to stick with this code and implement a better alternative for my next project. Could you tell me what am I doing wrong?
The error message says, basically, that it is NOT a valid JSON - and such error messages are usually right.
Your error is somewhere in the sending / receiving code. Probably you send the JSON in one form and try to access it in some other way. Since I have no way of looking at the requests sent from the phone, I would guess that:
you send the data as application/json and try to receive it as an url encoded form. If you don't understand the difference, here's your problem.
you use stripslashes on the JSON data, which is wrong. UNLESS you have magic_quotes turned on, which would also be wrong (that is: both magic_quotes and stripslashes have to go).
Tamper Data gives all the cookie context i wish to automate that. Session-Id and Login Credentials.
WGET or Wapiti kinda stuff.. but these are cmnd line based ..
i wish a web-based one ! the Tamper data values i need to pass are under the red box of screenshot.
Relying on the request-header's values is dicey and it is flawed since the request-header values can be easily manipulated (one example is what you yourself are showing).
If you want to login automatically into another web-application using the credentials you have provided in some other web-application then you can use Single Sign-on (SSO). More info can be found in this answer.
If you have some other requirement, then you can included that in the question so that it can be seen & answered accordingly.
Here is how you can get the request-header in a JSP:
request.getHeader("cookie") or request.getHeader("user-agent").
Or can use: request.getHeaderNames() to get all the headers and then loop through the names and get each header value by using point#1 like this:
Enumeration hNames = request.getHeaderNames();
while(hNames.hasMoreElements()) {
String hName = (String) hNames.nextElement();
System.out.println(hName + " = " + request.getHeader(hName);
}
This link might be helpful: Reading HTTP Request Headers
Here is how you can get the request headers in PHP:
Nice answer to the question: How do I read any request header in PHP,
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.