I have a problem when uploading a list of filenames to php. If the filename contains ] it will break the array decoding in PHP.
It can also be reproduced using $_GET as shown here.
What i want this to be decoded as is:
Array
(
[a] => Array
(
[b[]] => c
)
)
The goal is having a key in an array also containing the ] character
index.php?a[b[]]=c
Gives me this:
Array
(
[a] => Array
(
[b[] => c
)
)
Encoding them gives same problem
index.php?a[b%5B%5D]=c
Gives me this:
Array
(
[a] => Array
(
[b[] => c
)
)
Double encode it does not work either
index.php?a[b%255B%255D]=c
Gives me this:
Array
(
[a] => Array
(
[b%5B%5D] => c
)
)
Is it possible to encode this so PHP will decode it into a array with keys with the string that contains
Referencing my comment. You've put your focus on the wrong side of the table. It's not the handling of incoming information that is the problem, it's your client side submission of the data that isn't correctly passing through data. The brackets are UNSAFE characters to submit through to an endpoint and the client that is submitting this information is where you need to make the changes, not the backend handling the data.
Read up on the safe and unsafe characters in URL's here:
Stop using unsafe characters in URL's
Brackets are used to define nested list data and the way you are attempting to use it breaks that logic, you will have to change the way your frontend (or whatever is doing the HTTP request) encodes that data.
I don't know about your file upload and you need [ - character in filename or not, but problem with the $_GET array I can sloved so:
<? dump($_GET['a']); // Array([b[] => c)
$arr = [];
foreach ($_GET['a'] as $key => &$value) {
$vl = str_replace('[', '', $key);
dump($key); // b[
dump($vl); // b
$arr[$vl] = $value;
}
dump($arr); // Array([b] => c)
?>
Hope it helps you.
If you write a small script, you can ask PHP what it prefers:
<?php
$c = 0;
$data = array(
"a" => array(
"b[]" => $c
)
);
echo "<pre>";
var_export($data);
echo "\r\na[b[]]=c Encoded: " . urlencode("a[b[]]=c");
echo "</pre>";
?>
Results
array (
'a' =>
array (
'b[]' => 0,
),
)
a[b[]]=c Encoded: a%5Bb%5B%5D%5D%3Dc
Update
I wrote the following code just to see how the browser is encoding it:
<html>
<head>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
$(function(){
$("form").submit(function(e){
e.preventDefault();
var data = $(this).serialize();
console.log(data);
});
});
</script>
</head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="GET">
<label for "a">a[b[]] = </label>
<input type="text" name="a[b[]]" id="a" value="c" />
<br />
<button type="submit">
Go
</button>
</form>
</body>
</html>
When I click Go, I see the following in console:
a%5Bb%5B%5D%5D=c
When I then run it through urldecode():
<?php
echo urldecode("a%5Bb%5B%5D%5D=c");
?>
I see the following results:
a[b[]]=c
So it looks like you do not need to encode the = symbol, but you do want to encode [ and ] properly: %5B and %5D respectively.
So if you want to use:
index.php?a[b[]]=c
I would advise:
index.php?a%5Bb%5B%5D%5D=c
Hope that helps.
Related
I want to put json data into html form input checkbox with laravel blade.
I have multiple input checkbox values as test[],
Then I try use htmlspecialchars to print values into input.
If my frontend check this input, backend use print_r is like this
Array
(
[0] => {"value1":"tool_ad_id","value2":"\u65e5\u4ed8"}
[1] => {"value1":"ad_group1","value2":"\u30c4\u30fc\u30eb\u5e83\u544aID"}
)
but I use return $request->test['0']['value1']; can't get a value.
I want to get 'value1' and 'value2'.
PHP Laravel
#foreach($as as $key => $value)
<div class="col s6 m4 l3 blue-grey lighten-5">
<?php
$data = ['value1' => $value['en'] ,'value2' => $value['jp'] ];
$data_total = htmlspecialchars(json_encode($data));
?>
<input type="checkbox" id="test5{{ $key }}" value="{{$data_total}}" name="test[]" />
<label for="test5{{ $key }}">{{$value['jp']}}</label>
</div>
#endforeach
Laravel Controller
return $request->test['0']['value1'];
Error message
Illegal string offset 'value1'
[0] => {"value1":"tool_ad_id","value2":"\u65e5\u4ed8"}
Index => String
PHP does not parse JSON, you are receiving the JSON as normal string. Therefore, in order to convert it to a PHP object with properties correspongind to the keys, you need to use json_decode().
Try $test = json_decode($request->test['0'], true), and then access values off the $test variable.
$value1 = $test['value1'];
$value2 = $test['value2'];
I need to send object like php
$obj = [
array('id' => '111');
];
as POST request parameter.
I tried to use
[{struct,[{<<"id">>,<<"111">>},{<<"id">>, <<"222">>}]}]
[{struct,[{"id","111"}]}]
[{struct,[{"id":"111"}]}]
[{struct,[{"id"=>"111"}]}]
[[{"id","111"}]]
[{"id":"111"}]
[{"id"=>"111"}]
but it is wrong.
I tried to replace " by " but it's wrong too.
I don't find any examples in user manual about work with array or object. Does anyone faced with this question?
Build a query string using square brackets then URL encode it.
Example query string:
someArray[someindex_1][name]=blah&someArray[someindex_1][id]=123&someArray[someindex_2][name]=bah blah&someArray[someindex_2][id]=456
send the encoded string as the body of the post request. This should result in an array on the server like this:
print_r($_POST['someArray']);
// array(
// "someindex_1" => array(
// "name" => "blah"
// "id" => 123
// )
// "someindex_2" => array(
// "name" => "blah blah"
// "id" => 456
// )
//);
You can send an array in a POST request using the HTML element name with the square brackets "[]". An example is show below:
<input type="text" name="countries[]" value="Nigeria">
<input type="text" name="countries[]" value="Ghana">
Then in your PHP code, you can retrieve the values this way:
$countries = $_POST['countries']; //$countries is now an array of POST-ed countries
var_dump($countries);
But if what you want to send across is an Object, then you have to serialize it. You can use the code below:
$obj = get_an_object_somehow();
$encoded_obj = base64_encode(serialize($obj));
Then in your HTML form:
<input type="text" name="myObj" value="$encoded_obj">
Finally, in your form processing script, you can unserialize it as follows:
$decoded_obj = unserialize(base64_decode($obj));//get back original object
var_dump($decoded_obj);
I know this has been asked plenty of times before but still I have a problem after readaing all the other posts on the subject... Somewhere between my php code -and the javascript it is sitting in- my array is going awol.
In the attached code, I have an echo for debugging of the php. When I cut out the php section from the javascript and run it separately with the echo on, it shows me that it is building my json_encoded array correctly.
In the javascript immediately after the php end I assign the php to a javascript variable, so I can use it for further processing (plotting a graph). Putting in display statements, to display the content of the result of the php call to get the array into javascript, shows the array is empty.
If I cut and paste the output of the php echo and assign this literal to the javascript chartData array then everything works fine. Why is the javascript not getting the php array content?
Here's the code snip:
<script>
...some java script stuff;
<?php
// Define the mySQL db connection
$db = new PDO('mysql:host=localhost;dbname=remets;charset=UTF-8', 'remets', 'remets', array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
// Define SQL query to fetch data from mySQL
$stmt = $db->query("SELECT WeekNumber,XAxisCategory,YAxisValue FROM Metric WHERE ReportID = 'Q3' ORDER BY WeekNumber,XAxisCategory ASC");
// declarations
$amData = array();
$amArray = array();
$ctrinner = 0;
$ctrouter = -1;
$prevweek = "9999";
// Fetch data from mySQL and put it in an array in the format we need
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($prevweek !== $row['WeekNumber']) {
$ctrouter++;
$ctrinner = 0;
$amData[$ctrouter]["week"] = "".$row['WeekNumber']; // Prepending (or appending) the empty string makes the json encoding think the week number is a string, which is MUST have for AmCharts
}
$ctrinner++;
$amData[$ctrouter][$row['XAxisCategory']] = $row['YAxisValue'];
$prevweek = $row['WeekNumber'];
}
// Using json_encode puts the data into an array format that we can use in a javascript
$amJSONArray = json_encode($amData);
// Echo is for debugging only.
// echo $amJSONArray;
?>
var chartData = <?php echo $amJSONArray;
?>;
...more javascript stuff;
</script>
#Mahdi: The output of the print_r is: Array ( [0] => Array ( [week] => 1301 [Accepted] => 30 [Failed] => 5 [Passed] => 20 [Planned] => 5 [Skipped] => 5 [Unknown] => 26 ) [1] => Array ( [week] => 1302 [Accepted] => 25 [Failed] => 2 [Passed] => 25 [Planned] => 2 [Skipped] => 3 [Unknown] => 20 ) [2] => Array ( [week] => 1303 [Accepted] => 26 [Failed] => 26 [Passed] => 29 [Planned] => 26 [Skipped] => 26 [Unknown] => 10 ) )
#Mahdi: This is the jscript code immediately after the php (It is commented out because I tried lots of different options that were recommended in other posts in this forum and others - none of them work. I can run the php code and that works fine. If I copy the output of the echo in the php code snip I posted earlier and simply assign that to chartData (ie: chartData = "";
my chart is produced fine. The problem is not with the charting tool but somehow the array content is just not visible to the javascript which is directly below it in the .js file.
Thanks for your time up til now.
//var chartData = "<?php print($amJSONArray); ?>"; // This just returns the literal in the speech marks
//var chartData = '<?php print($amJSONArray); ?>'; // This also returns the literal in the speech marks
//var chartData = "<?php echo($amJSONArray); ?>"; // This just returns the literal in the speech marks
//var chartData = '<?php echo($amJSONArray); ?>'; // This also returns the literal in the speech marks
//var chartData = <?php echo ($amJSONArray) ?>; // This returns empty
//var chartData = <?php echo $amJSONArray ?>; // This returns empty
//var chartData = (<?php echo $amJSONArray ?>); // This returns empty
//alert(chartData); // Returns empty - just showing the contents of the array if I do the json_encode within the php part
//alert(<?php echo $amJSONArray ?>); // Returns empty - just showing the contents of the array if I do the json_encode during the array fetch
UPDATE:
I think there's something fundamentally wrong going on at my side. I used a very simple example which should write "hello world" to the screen but it returns nothing at all. If I substitute the 'write' with an 'alert' then it still shows nothing in the alert popup. Does anyone know why this would not be working? The code is:
<?php
$testvar = "Hello World";
?>
<html>
<head>
<script type="text/javascript">
function hello()
{
// create JavaScript variable, fill it with Php variable
var testvar = "<? print $testvar; ?>";
// output to screen
document.write( testvar );
}
</script>
</head>
<!-- Call JavaScript function to display variable -->
<body onload="hello()" >
</body>
</html>
If you are able to access the data as a string, you can try using the built-in JSON.parse() to convert it into usable javascript.
I am passing a list of numbers from a page to PHP serialized in JSON
{"items":"[1,2,3,4]"}
in my URL it is just
...&items={"items":[1,2,3,4]}
I decode this in PHP
$json = $_GET["items"];
$arr = json_decode($json, true);
I get an array
Array ( [items] => [1,2,4] )
But when I try a foreach on arr["items"] and print out each value, all I get is a single value
[1,2,4]
This is the code I am using to iterate
foreach($res["items"] as $value)
echo $value;
How come I am not getting something like
1
2
4
Look closely at your json string:
{"items":"[1,2,3,4]"}
Look closer:
"[1,2,3,4]"
You are saying that items is a string containing:
"[1,2,3,4]"
Remove the " and you'll be fine.
Your serialization is wrong. Should be:
{"items":[1,2,3]}
To get rid of problems like that use JSON.stringify in JS:
var myData = {"items" : [1,2,3]},
queryString = 'data='+encodeURIComponent(JSON.stringify(myData));
for IE < 8 it has to be included from external script (see here) :
<!--[if lt IE 8]><script src="/js/json2.js"></script><![endif]-->
Anyway much easier would be to send it already as an array:
items[0]=1&items[1]=2&items[2]=3
This way you can send also more complex structures:
data[items][0]=1&data[items][1]=2
// on PHP side will become
$_GET['data'] = array('items' => array(1,2))
I am trying this new method I've seen serializeArray().
//with ajax
var data = $("#form :input").serializeArray();
post_var = {'action': 'process', 'data': data };
$.ajax({.....etc
So I get these key value pairs, but how do I access them with PHP?
I thought I needed to do this, but it won't work:
// in PHP script
$data = json_decode($_POST['data'], true);
var_dump($data);// will return NULL?
Thanks, Richard
Like Gumbo suggested, you are likely not processing the return value of json_decode.
Try
$data = json_decode($_POST['data'], true);
var_dump($data);
If $data does not contain the expected data, then var_dump($_POST); to see what the Ajax call did post to your script. Might be you are trying to access the JSON from the wrong key.
EDIT
Actually, you should make sure that you are really sending JSON in the first place :)
The jQuery docs for serialize state The .serializeArray() method creates a JavaScript array of objects, ready to be encoded as a JSON string. Ready to be encoded is not JSON. Apparently, there is no Object2JSON function in jQuery so either use https://github.com/douglascrockford/JSON-js/blob/master/json2.js as a 3rd party lib or use http://api.jquery.com/serialize/ instead.
The OP could have actually still used serializeArray() instead of just serialize() by making the following changes:
//JS
var data = $("#form :input").serializeArray();
data = JSON.stringify(data);
post_var = {'action': 'process', 'data': data };
$.ajax({.....etc
// PHP
$data = json_decode(stripslashes($_POST['data']),true);
print_r($data); // this will print out the post data as an associative array
its possible by using the serialize array and json_decode()
// js
var dats = JSON.stringify($(this).serializeArray());
data: { values : dats } // ajax call
//PHP
$value = (json_decode(stripslashes($_REQUEST['values']), true));
the values are received as an array
each value can be retrieved using $value[0]['value'] each html component name is given as $value[0]['name']
print_r($value) //gives the following result
Array ( [0] => Array ( [name] => name [value] => Test ) [1] => Array ( [name] => exhibitor_id [value] => 36 ) [2] => Array ( [name] => email [value] => test#gmail.com ) [3] => Array ( [name] => phone [value] => 048028 ) [4] => Array ( [name] => titles [value] => Enquiry ) [5] => Array ( [name] => text [value] => test ) )
The JSON structure returned is not a string. You must use a plugin or third-party library to "stringify" it. See this for more info:
http://www.tutorialspoint.com/jquery/ajax-serializearray.htm
I have a very similar situation to this and I believe that Ty W has the correct answer. I'll include an example of my code, just in case there are enough differences to change the result, but it seems as though you can just use the posted values as you normally would in php.
// Javascript
$('#form-name').submit(function(evt){
var data = $(this).serializeArray();
$.ajax({ ...etc...
// PHP
echo $_POST['fieldName'];
This is a really simplified example, but I think the key point is that you don't want to use the json_decode() method as it probably produces unwanted output.
the javascript doesn't change the way that the values get posted does it? Shouldn't you be able to access the values via PHP as usual through $_POST['name_of_input_goes_here']
edit: you could always dump the contents of $_POST to see what you're receiving from the javascript form submission using print_r($_POST). That would give you some idea about what you'd need to do in PHP to access the data you need.
Maybe it will help those who are looking :)
You send data like this:
$.ajax({
url: 'url_name',
data: {
form_data: $('#form').serialize(),
},
dataType: 'json',
method: 'POST'
})
console.log($('#form').serialize()) //'f_ctrType=5&f_status=2&f_createdAt=2022/02/24&f_participants=1700'
Then on the server side use parse_str( $_POST['form_data'], $res).
Then the variable $res will contain the following:
Array
(
[f_ctrType] => 5
[f_status] => 2
[f_createdAt] => '2022/02/24'
[f_participants] => 1700
)
You can use this function in php to reverse serializeArray().
<?php
function serializeToArray($data){
foreach ($data as $d) {
if( substr($d["name"], -1) == "]" ){
$d["name"] = explode("[", str_replace("]", "", $d["name"]));
switch (sizeof($d["name"])) {
case 2:
$a[$d["name"][0]][$d["name"][1]] = $d["value"];
break;
case 3:
$a[$d["name"][0]][$d["name"][1]][$d["name"][2]] = $d["value"];
break;
case 4:
$a[$d["name"][0]][$d["name"][1]][$d["name"][2]][$d["name"][3]] = $d["value"];
break;
}
}else{
$a[$d["name"]] = $d["value"];
} // if
} // foreach
return $a;
}
?>