How to pass an array using $_POST? - php

I know there are some similar questions but none of them solves my issue.
I have a simple form:
<form method="post">
Import data: <textarea type="text" name="import"></textarea>
<input type="submit">
</form>
Then I get data from the "import" field:
$current = my_data();
$import = $_POST['import'];
$merge = array_merge($current,$import);
The problem is, even if I paste:
array('foo' => 'bar')
I get:
Warning: array_merge(): Argument #2 is not an array in
(address)
on line (line)
I can't change the HTML markup and I have to paste arrays there. Any ideas how to fix it? I've been reading about serialize() but not sure if there's anything to serialize is array() is not array() for PHP. Why is that? Any solutions? Thanks a lot!
UPDATE
$current hold an array of options for my theme.
$merge is supposed to hold the same keys with different values (around 30-50 of them, not multidimensional but might be in the future), but of course users might add new ones so in order to ignore them I'm actually using:
$imported_options = array_merge($current_options , array_intersect_key($_POST["import"], $current_options ));
(simplified this one as it's just an example)
So after all I want to load an array from the form and update the other array with it.

PHP will not create arrays in $_GET/$_POST unless you tell it to:
Import data: <textarea type="text" name="import[]"></textarea>
^^---- need these
Without the [], PHP will treat any duplicate field names as strings to be overwritten. With [] in the name, PHP will treat them as new elements in an array.

You can do
$current['import'] = $import;
Or you can change your html this way:
<textarea type="text" name="myarray['import']"></textarea>
And in php:
$import = $_POST['myarray'];

The second argument is not an array.
$_POST['import'] = value received from the form.
With that said, try:
$current [] = $_POST['import'];

What are you trying to get from $_POST['import'] ?
you are using a textarea to get an array?
if it's just a single variable then use array_push
http://php.net/manual/es/function.array-push.php
for array_merge you need to have 2 arrays.

Related

Can't Delete Specific Keys and Values from JSON in PHP

I'm trying to delete specific key and value pair from external JSON file in PHP when user clicked delete button on the page.
I'm not familiar with PHP so I couldn't able to figure out what I'm doing wrong. I looked at more than 20 questions on stackoverflow but none of them helped to solve my problem.
What I'm trying to achieve in general to write a simple script which user can write something in textbox and submit, show it on the page and when user wants delete it. (I have done the submit and showing part but stuck on deleting part)
Firstly my JSON file:
{
"departman1":
[
{"departman1stage":"John"},
{"departman1stage":"Test"},
{"departman1stage":"Test2"}
]
}
Part of my index.php file:
...
include ('yazdir.php');
include ('sil.php');
<div class='icerik'>
<?php
foreach ($json['departman1'] AS $d){
echo '<p class="' . $d['departman1stage'] .'">';
echo "--> ";
echo $d['departman1stage'];
echo '<form action="sil.php" method="POST"><button type="submit" class="dugme" name="' . $d['departman1stage'] .'"><i class="fa fa-trash"></i></button></form>';
echo "<br>";
echo "</p>";
}
?>
</div>
<br>
<form action="yazdir.php" method="POST">
<div class="icerik"><p><input type="text" name="departman1stage"></p></div>
<br>
<input type="submit" value="Gonder">
</form>
...
It is not related with problem but I still put my yazdir.php code:
$json_sifreli = file_get_contents ("data.json");
$json = json_decode($json_sifreli, true);
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$data = array(
'departman1stage' => $_POST["departman1stage"]
);
array_push ( $json['departman1'], $data );
$json_sifreleme = json_encode($json, true);
file_put_contents('data.json', $json_sifreleme);
}
sil.php is currently blank, as I said I tried different methods. Some of them deleted whole JSON file and put 'null' into it. Some of them deleted unrelated key and value pair. As a last resort, I decided to write here.
Thanks in advance, sorry for taking your time.
You can delete keys using the PHP built-in unset function. It works on individual array keys:
<?php
$foo = [
'a' => 23,
'b' => 42,
];
unset($foo['a']);
var_dump($foo);
Results in:
array(1) {
["b"]=>
int(42)
}
PHP arrays are hash maps, no matter if keys are strings are numeric. In your example JSON, departman1 is an array with numeric keys. You can delete numeric keys with unset as well:
$bar = [
23,
42,
];
unset($bar[0]);
var_dump($bar);
Results in:
array(1) {
[1]=>
int(42)
}
Note that the dump shows 1 as key. Unsetting numeric keys does not cause the array to be renumbered. You end up with holes and this will show up in json_encode output:
echo json_encode($bar);
// Results in: {"1":42}
So you could go through the swamp of using a JSON file as data store, but be cautioned it's a Pandoras Box full of hardships. It also doesn't scale beyond one concurrent user because json_encode and json_decode do not provide ACID properties, which database management systems provide you. My suggestion: ditch the JSON file and pick up a proper database such as PostgreSQL or MySQL (they have good support in PHP via PDO).
view the example code in playground
(BTW: You are using the $_POST variable directly, which is unsafe user input. Sanitizing input can be done with PHP built-in filter_var function.)

PHP get JSON object value from Input array (array-like name)

I have 3 inputs like this:
<input type="text" name="product[1][name]" >
<input type="text" name="product[1][cost]" >
<input type="text" name="product[1][qty]" >
... which goes until n products
<input type="text" name="product[n][name]" >
<input type="text" name="product[n][cost]" >
<input type="text" name="product[n][qty]" >
and based on the input value a JSON string like this:
{"product[1][name]": "Prod1", "product[1][cost]": "100$", "product[1][qty]": "3", "product[2][name]": "Prod2", ... }
how can I retrieve their name and value because neither json_decode function can take their values because of the array-like name
$decodedObject=json_decode($array['data']); // this data contains the json string
echo $decodedObject->product; // does not work
echo $decodedObject->product[1][qty]; // does not work
is there any simple way?
Or the only way is to cut the name like product[, take the inside elements , and the value after the : and so on?
But how can I even take the object from it without letting PHP know that's not an array ?
Firstly I found an alternative. The problem is that this:
$decodedObject=json_decode($array['data']); // will create an object
will not transform it in an array, instead I have used this:
$decodedObject=json_decode($array['data'], true); // will create an array
after that I had checked how many objects exist, and then just add them to another array:
$i=1;
while(isset($decodedObject["product[$i][qty]"])) // while any element exists
{
$newProducs= array();
$newProducs['name'] = $decodedObject["product[$i][name]"];
$newProducs['cost'] = $decodedObject["product[$i][cost]"];
$newProducs['qty'] = $decodedObject["product[$i][qty]"];
array_push($products, $newProducs); // optional: add to the main array (products) the new-created array (newProducs)
$i++; //increment to search another product
}
The problem was that I was not fully creating an array -_-
While this is not the full answer I still hope somebody will find a better solution and not a change.

SimpleXML, iteration on all element

I have a stock report file (coming from an outer source, therefore I can't modify in any way) and I would like to iterate over all elements (I have to save them into a MySQL table). As I see the $xml->Stockfile is an array of objects (2 items), so I tried to put it into an array.
For some reason the $myarray contains only the first element after the $myarray = $xml->StockFile assignment.
here is my code:
$xml = simplexml_load_file("../docs/stock.xml");
print_r($xml);
$myarray = $xml->StockFile;
print_r($myarray);
stock.xml:
<NewDataSet>
<StockFile>
<MatrixID>1533</MatrixID>
<Brand>myBrand</Brand>
<ProductCode>001</ProductCode>
<RRP>29.99</RRP>
<Image2Name />
<Image3Name />
</StockFile>
<StockFile>
<MatrixID>1534</MatrixID>
<Brand>myBrand</Brand>
<ProductCode>002</ProductCode>
<RRP>29.99</RRP>
<Image2Name />
<Image3Name />
</StockFile>
</NewDataSet>
Why I'm getting only one item instead of all?
What should I do do retrieve the whole array?
Take care with SimpleXMLElement. It has a lot of magic. Know the magic or get puzzled by print_r or var_dump or similar output. Your example extended:
$myarray = $xml->StockFile;
print_r($myarray); # shows one element
# foreach has both elements:
foreach($myarray as $name => $stockfile)
{
echo $name, ":\n", $stockfile->asXML(), "\n\n";
}
Even though it is the same variable ($myarray) it behaves differently depending on context it is used in. Inside a foreach the SimpleXMLElement (that is the type of that object) will provide an iterator over the child-elements named StockFile as specified here:
$myarray = $xml->StockFile;
However using that variable in some kind of single context, it will for example return the inner string of the first child-element with that name:
echo $myarray, "\n";
(which in your case is just some lines of whitespace).
See Demo: https://eval.in/83787
Running into this "trap" by SimpleXML is actually pretty common. I suggest to understand the basic usage by the example given in the manual:
Basic SimpleXML usage
change the last two lines to
foreach ($xml->StockFile as $nextStockFile) {
print_r ($nextStockFile);
}

Massive content replace on php data

I would like to perform massive content replace for some data called from mysql db in a php file.
Firstly, I have prepared an replacement array for content replace:-
$replacement_array = array(
"###123###" => "hello",
"###456###" => "great",
"###789###" => "ok"
);
Secondly, I call data from mysql db, the data would look like this:-
$data = "<input type="text" name="field1" value="###123###"><input type="text" name="field2" value="###789###">";
Thirdly, refer to the array, check up if $data contains any matched value in $replacement_array (this is the black box I wish to consult).
Fourthly, after content replacement, the resulting $data would become this:-
$data = "<input type="text" name="field1" value="hello"><input type="text" name="field2" value="ok">";
I guess the above will involve php in_array(), str_replace() and preg_match(), and I guess the flow may be like this:-
1) use explode() function to chop $data into a new $data_array by ###;
2) check values in $data_array is in_array() of $replacement_array;
3) if in_array(), carry out str_replace(); (in the above example there will be 2 times)
4) $data has proceeded 2 times of content replace, and ready to be used.
if the above steps 3) and 4) are carried out step by step, I it will be easy, however, if I wish to do it in 1 time, how shall I handle it?
You can use str_replace with first parameter as search array and second parameter as replace array.
$arr = array("###123###","###456###","###789###");
$arr1 = array("hello","great","ok");
str_replace($arr,$arr1, $data);

How to dynamicly set a array variable?

I have a problem with this code:
$a['i'] = 1;
$b = '$a[\'i\']';
echo $$b;
It display an error:
Notice: Undefined variable: $a['i'] in test.php on line 6
Is it possible to create dynamic array variable?
Thanks for your time.
EDIT: In my example I am trying to edit an multidimensional array. There is a problem when I try to add data to my array (JSON). I don't have fixed dimension of array, it my be 2 or more dimension (I am building a model for Web form, and I want to add invalid value to JSON).
Now in one of the methods of Web form object I have code which checks repopulation object to add invalid value if needed.
I can not just add a value to JSON array, I need to edit it on multidimensional level.
For now I came up on solution to dynamically generate variable name and, then, edit it. If someone have solution it will be appreciated.
private $form = array(
'form_contact'=>array(
'attr'=>array('tag'=>'FORM', 'method'=>'post'),
'elem'=>array(
'fs_contact'=>array(
'attr'=>array('legend'=>'Kontakt', 'tag'=>'FSET'),
'elem'=>array(
'name'=>array(
'attr'=>array('SPAN'=>'Ime i prezime', 'title'=>'Unesite Vaše ime i prezime', 'tag'=>'INPUT', 'type'=>'text'),
'validat'=>array('req'=>'noscript', 'length'=>255),
'invalid'=>true), // Holds info that this is invalid
'www'=>array(
'attr'=>array('SPAN'=>'Web sajt', 'title'=>'Unesite Vaš sajt', 'tag'=>'INPUT', 'type'=>'text'),
'validat'=>array('length'=>255)),
'email'=>array(
'attr'=>array('SPAN'=>'E-mail', 'title'=>'Unesite Vaš email', 'tag'=>'INPUT', 'type'=>'text'),
'validat'=>array('req'=>'email', 'length'=>255)),
'message'=>array(
'attr'=>array('SPAN'=>'Poruka', 'cols'=>'60', 'rows'=>'5', 'title'=>'Unesite Vašu poruku', 'tag'=>'TEXTA', 'value'=>'nesto'),
'validat'=>array('req'=>'all')),
'submit_new_contact_form'=>array(
'attr'=>array('tag'=>'INPUT', 'type'=>'submit', 'value'=>'Pošalji poruku!'))
))// FS end
)) // Form end
);// Array end
You can't do it that way, as PHP thinks you're looking for a variable with the name $a['i'], rather than the 'i' key in the $a array.
The proper, and conventional, way is to use a dynamic key/index instead:
$b = 'i';
echo $a[$b];

Categories