PHP: Strange Array Problem - Where is my value? - php

I have an array ($form) which retreives some information from $_POST:
$form = $_POST['game'];
Now I want to work with the values in this array, but I somehow fail.
For debugging I used these commands (in the exact same order, with no extra lines inbetween):
print_r($form);
echo '#' . $form['System_ID'] . "#";
and as returned output I get:
Array
(
['Title'] => Empire: Total War - Special Forces
['Genre_ID'] => 1
['Type'] => Spiel
['System_ID'] => 1
)
##
Any ideas where my System_ID went? It's there in print_r, but not in the next line for echo?!?

Alright, I found the solution myself (a.k.a. d'oh!)
I added another
var_dump($form);
for further analysis and this is what I got:
array(4) {
["'Title'"]=>
string(34) "Empire: Total War - Special Forces"
["'Genre_ID'"]=>
string(1) "1"
["'Type'"]=>
string(5) "Spiel"
["'System_ID'"]=>
string(1) "1"
}
Notice the single quote inside the double quote?
Looks as if you're not allowed to use the single quote in html forms or they will be included in the array key:
Wrong: <input type="text" name="game['Title']" />
Correct: <input type="text" name="game[Title]" />

print_r() doesn't put quotes around keys - for debugging i'd recommend ditching print_r altogether. var_export or var_dump are better.
even better: use firephp. it sends the debug info via headers, so it doesn't mess up your output and thus is even usable with ajax. output is displayed nicely with firebug including syntax coloring for data structures.
and it's even easier to use: just fb($myvar);

It works for me:
<?
$form['System_ID'] = 1;
print_r($form);
echo '#' . $form['System_ID'] . '#';
?>
Output:
% php foo.php
Array
(
[System_ID] => 1
)
#1#
PHP 5.2.6, on Fedora Core 10
EDIT - note that there's a hint to the real cause here. In my code the print_r output (correctly) shows the array keys without single quotes around them. The original poster's keys did have quotes around them in the print_r output, showing that somehow the actual key contained the quote marks.

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.)

parse_ini_file converts values of constants into strings, even when using INI_SCANNER_TYPED

INI_SCANNER_TYPED, used as the 3rd argument to parse_ini_file(), should conserve boolean, null and integer values "when possible", according to the documentation
However, when constants are parsed, the values are converted to strings. The documentation is not clear on whether this is expected to happen. It is certainly undesirable, I can't imagine a single scenario where this would be useful. Other scanning types are to be used when you want string conversion, surely?
For example with the following ini file:
NUMBER = 1
TEXT = "1"
DEFINED_INTEGER_CONSTANT = FOO
DEFINED_BOOLEAN_CONSTANT = BAR
UNDEFINED_CONSTANT = BAZ
I use the following php file and get output in comments
<?php
declare(strict_types=1);
define("FOO", 123);
define("BAR", true);
$ini_file = parse_ini_file(__DIR__ . '/test.ini', false, INI_SCANNER_TYPED);
foreach($ini_file as $key => $value) {
define($key, $value);
}
var_dump(NUMBER); // => int(1)
var_dump(TEXT); // => string(1) "1"
var_dump(DEFINED_INTEGER_CONSTANT); // => string(3) "123"
var_dump(DEFINED_BOOLEAN_CONSTANT); // => "1"
var_dump(UNDEFINED_CONSTANT); // => "BAZ"
I neither expect nor want the string conversion in the 3rd and 4th examples. Can I use parse_ini_file to parse constants without string conversion, or do I need to do this another way? Is this something to do with the "where possible" clause in the documentation? Is keeping the original types not possible here for some reason?
Tested in PHP 7.1.26 and 7.3.7.
There does not seem to currently be a way to get parse_ini_file to behave in the expected way.
I have reported this and it has been verified as a bug - see here.

Unserialize not working for multi-dimensional array

So I have run into this problem many times before, but I would always get around it using base64_encode/decode and that would get it working right away.
However, in this application I cannot use that, because I need to be able to query this field and I wouldn't know how I could do that if it was encoded.
Pardon my ignorance, but is there a way to unserialize a multi-dimensional array without using base64 encoding?
Update 1
Removing the strings and turning them to integers fixes the problem. So it is either a problem with strings, or I suspect the " is causing issues. Anyway to work around that?
For this application, the second element of the array represents a date in a format that it would be searched under. Ideally, I would like to leave that as is, but if it is necessary I suppose I can use an integer to represent the number of days away from a constant, and then interpret that result.
Below is the code:
// Load Contact from Database
$returnFields = array('_AttendanceRecords');
$Contact = $app->loadCon(39732,$returnFields);
echo "<pre>";
print_r($Contact);
echo "</pre>";
echo $Contact['_AttendanceRecords'] . "</br>";
// To unserialize...
$AttendanceRecordsLoad = unserialize($Contact['_AttendanceRecords']);
echo "<pre>";
print_r($AttendanceRecordsLoad);
echo "</pre>";
Output is:
Array (
[_AttendanceRecords] => a:1:{i:0;a:3:{i:0;i:1;i:1;s:10:"10-09-2015";i:2;s:1:"1";}} )
a:1:{i:0;a:3:{i:0;i:1;i:1;s:10:"10-09-2015";i:2;s:1:"1";}}
As you can see, the final print_r comes out empty, which I believe is returning false for whatever reason.
Update 2
So after more fiddling around, I made this new code:
Code
$ContactId = 39732;
$returnFields = array('_AttendanceRecords');
$Contact = $app->loadCon($ContactId,$returnFields);
echo $Contact['_AttendanceRecords'] . " - IS result </br>";
echo $str = 'a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}}'; echo " - str result </br>";
// To unserialize...
$AttendanceRecordsLoad = unserialize($Contact['_AttendanceRecords']);
$AttendanceRecordsLoad1 = unserialize($str);
echo "IS<pre>";
print_r($AttendanceRecordsLoad);
echo "</pre>";
echo "str<pre>";
print_r($AttendanceRecordsLoad1);
echo "</pre>";
Output
a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}} - IS result
a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}} - str result
IS
str
Array (
[0] => Array
(
[0] => 0
[1] => 10-10-15
[2] => 1
)
)
I don't understand. The strings appear identical. Yet the result that comes from the database won't unserialize if it contains a string.
Does that make sense to anyone?
Update 3
Ok, so now I used var_dump instead of echo and I get this outputted:
Output
string(61) "a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}}" - IS
result
string(51) "a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}}" - str result
So obviously they are not identical. But I tried trim before, and now, and it doesn't remove any hidden extra characters that somehow have lodged themselves in to this string.
What does that mean and how do I correct this?
Ok figured it out by looking at this question:
SOLUTION FOUND - Same strings, but var_dump() says one is 5 characters longer
The fix was using this on the returned result from the database:
html_entity_decode($string], ENT_QUOTES)
Hope that helps someone else too.

Cleaner way to echo multi dimension array

echo "{$line['text_1']}";
the above echo works fine ,however when it comes to 2d array, in my sublime, only {$line['text_2']} this part work fine. output error both sublime and browser
echo "$array_2d[{$line['text_1']}][{$line['text_2']}]";
any idea?
update
echo "$array_2d[$line['text_1']][$line['text_2']]";
using xampp, error Parse error: syntax error, unexpected '[', expecting ']' in C:\xampp\htdocs
and I'm just outputting a value from the mysql_fetch_assoc. I can do it in another way by echo '' however I'm trying to make my code easier for future editting and code copy paste
and yes I'm doing things like
echo "The price is $array_2d[$line['text_1']][$line['text_2']]"
with lots of html code in the double quote.
Why are you trying to output the array?
if it is for debugging purposes, you can just use the native php functions print_r() or var_dump()
You should be able to say
echo "item is {$array_2d[$line['text1']][$line['text2']]}";
to get to a subelement.
Of course, this is only really useful when it's not the only thing in the string. If you're only echoing the one value, you don't need the quotes, and things get simpler.
echo $array_2d[$line['text1']][$line['text2']];
this should work :
echo $array_2d[$line['text_1']][$line['text_2']];
When echoing variables, you don't have to use the quotes:
echo $array_2d[$line['text_1']][$line['text_2']];
If you do need to output something with that string, the concatentation operator can help you:
echo "Array: " . echo $array_2d[$line['text_1']][$line['text_2']];
You can use print_r() to echo the array.
e.g.:
print_r($array);
Output will be:
Array ( [test] => 1 [test2] => 2 [multi] => Array ( [multi] => 1 [multi2] => 2 ) )
Also you can use this to make it more readable in a HTML context:
echo '<pre>';
print_r($array);
echo '</pre>';
Output will be:
Array
(
[test] => 1
[test2] => 2
[multi] => Array
(
[multi] => 1
[multi2] => 2
)
)
You can use print_r() or var_dump() to echo an array.
The print_r() displays information about a variable in a way that's readable by humans whereas the var_dump() function displays structured information about variables/expressions including its type and value.
$array = 'YOUR ARRAY';
echo "<pre>";
print_r($array);
echo "</pre>";
or
$array = 'YOUR ARRAY';
var_dump($array);
Example variations
I'm wondering why you would try using the $line array as a key to access data in $array_2d.
Anyway, try this:
echo($line['text_1'].'<br>');
this:
echo($array_2d['text_1']['text_2'].'<br>');
and finally this (based on your "the $line array provides the keys for the $array_2d" array example)
$key_a = $line['text_1'];
$key_b = $line['text_2'];
echo($array_2d[$key_a][$key_b].'<br>');
Which can also be written shorter like this:
echo($array_2d[$line['text_1']][$line['text_2']].'<br>');
Verifying/Dumping the array contents
To verify if your arrays hold the data you expect, do not use print_r. Do use var_dump instead as it will return more information you can use to check on any issues you think you might be having.
Example:
echo('<pre>');
var_dump($array_2d);
echo('</pre>');
Differences between var_dump and print_r
The var_dump function displays structured information of a variable (or expression), including its type and value. Arrays are explored recursively with values indented to show structure. var_dump also shows which array values and object properties are references.
print_r on the other hand displays information about a variable in a readable way and array values will be presented in a format that shows keys and elements. But you'll miss out on the details var_dump provides.
Example:
$array = array('test', 1, array('two', 'more'));
output of print_r:
Array
(
[0] => test
[1] => 1
[2] => Array
(
[0] => two
[1] => more
)
)
output of var_dump:
array(3) {
[0]=> string(4) "test"
[1]=> int(1)
[2]=> array(2)
{
[0]=> string(3) "two"
[1]=> string(4) "more"
}
}

Array Not Returning Entire Element

I think I simply have invalid syntax, but for the life of me I can't figure it out. I have a nested array with 3 elements.
$screenshot = array( array( Carousel => "Library.png", Caption => "Long caption for the library goes here", ListItem => "The Library"));
I'm using a for loop to compose some HTML that includes the elements.
<?php
for ( $row = 0; $row < 4; $row++)
{
echo "<div class=\"feature-title\">" . $screenshot[$row]["ListItem"] . "</div>";
}
?>
My problem is that the "title" portion of the "a" tag only includes the first word, Long. So in the above case it would be:
<div class="feature-title">The Library</div>
Can anyone shed some light on my error? Thanks in advance.
You forgot double quotes around the attribute values, so only the first word counts. The rest become (invalid) attribute names.
Make a habit of wrapping, the array index within double-quotes i.e. " for string indexes.
$screenshot = array(
array(
"Carousel" => "Library.png",
"Caption" => "Long caption for the library goes here",
"ListItem" => "The Library")
);
As Starx and Ignacio have mentioned, the key parts of the arrays need to be quoted. It doesn't matter if they are single or double quotes though. If you turn on more verbose logging (like E_ALL instead of E_ALL & ~E_NOTICE) you'll get messages like this:
PHP Notice: Use of undefined constant Carousel - assumed 'Carousel' in badarray.php on line 3
PHP Notice: Use of undefined constant Caption - assumed 'Caption' in badarray.php on line 3
PHP Notice: Use of undefined constant ListItem - assumed 'ListItem' in badarray.php on line 3
PHP tries to find a constant that has been defined with those names. When it cannot find one it assumes you meant the string of that value. This means that if you ever did define a constant named "Carousel", "Caption" or "ListItem" it would change the key values in the array you defined.
The other issue I see, and it could just be that only partial code was included, was there is only a single array inside of the outer array so when you're accessing $screenshot[$row], there will be nothing there once your loop increments $row beyond 0.
If you can provide what you're trying to output from using that array, I can help you build that code.
please use this code
echo "<div class=\"feature-title\">" . $screenshot[$row]["ListItem"] . "</div>";

Categories